diff --git a/readme.plan.md b/readme.plan.md index 3ef15f4..7f6bde3 100644 --- a/readme.plan.md +++ b/readme.plan.md @@ -1,255 +1,775 @@ -# SmartProxy Interface & Type Naming Standardization Plan +# SmartProxy Fully Unified Configuration Plan ## Project Goal -Standardize interface and type naming throughout the SmartProxy codebase to improve maintainability, readability, and developer experience by: -1. Ensuring all interfaces are prefixed with "I" -2. Ensuring all type aliases are prefixed with "T" -3. Maintaining backward compatibility through type aliases -4. Updating documentation to reflect naming conventions +Redesign SmartProxy's configuration for a more elegant, unified, and comprehensible approach by: +1. Creating a single, unified configuration model that covers both "where to listen" and "how to forward" +2. Eliminating the confusion between domain configs and port forwarding +3. Providing a clear, declarative API that makes the intent obvious +4. Enhancing maintainability and extensibility for future features -## Phase 2: Core Module Standardization +## Current Issues -- [ ] Update core module interfaces and types - - [ ] Rename interfaces in `ts/core/models/common-types.ts` - - [ ] `AcmeOptions` → `IAcmeOptions` - - [ ] `DomainOptions` → `IDomainOptions` - - [ ] Other common interfaces - - [ ] Add backward compatibility aliases - - [ ] Update imports throughout core module +The current approach has several issues: -- [ ] Update core utility type definitions - - [ ] Update `ts/core/utils/validation-utils.ts` - - [ ] Update `ts/core/utils/ip-utils.ts` - - [ ] Standardize event type definitions +1. **Dual Configuration Systems**: + - Port configuration (`fromPort`, `toPort`, `globalPortRanges`) for "where to listen" + - Domain configuration (`domainConfigs`) for "how to forward" + - Unclear relationship between these two systems -- [ ] Test core module changes - - [ ] Run unit tests for core modules - - [ ] Verify type compatibility - - [ ] Ensure backward compatibility +2. **Mixed Concerns**: + - Port management is mixed with forwarding logic + - Domain routing is separated from port listening + - Security settings defined in multiple places -## Phase 3: Certificate Module Standardization +3. **Complex Logic**: + - PortRangeManager must coordinate with domain configuration + - Implicit rules for handling connections based on port and domain -- [ ] Update certificate interfaces - - [ ] Rename interfaces in `ts/certificate/models/certificate-types.ts` - - [ ] `CertificateData` → `ICertificateData` - - [ ] `Certificates` → `ICertificates` - - [ ] `CertificateFailure` → `ICertificateFailure` - - [ ] `CertificateExpiring` → `ICertificateExpiring` - - [ ] `ForwardConfig` → `IForwardConfig` - - [ ] `DomainForwardConfig` → `IDomainForwardConfig` - - [ ] Update ACME challenge interfaces - - [ ] Standardize storage provider interfaces +4. **Difficult to Understand and Configure**: + - Two separate configuration hierarchies that must work together + - Unclear which settings take precedence -- [ ] Ensure certificate provider compatibility - - [ ] Update provider implementations - - [ ] Rename internal interfaces - - [ ] Maintain public API compatibility +## Proposed Solution: Fully Unified Routing Configuration -- [ ] Test certificate module - - [ ] Verify ACME functionality - - [ ] Test certificate provisioning - - [ ] Validate challenge handling +Replace both port and domain configuration with a single, unified configuration: -## Phase 4: Forwarding System Standardization +```typescript +// The core unified configuration interface +interface IRouteConfig { + // What to match + match: { + // Listen on these ports (required) + ports: number | number[] | Array<{ from: number, to: number }>; + + // Optional domain patterns to match (default: all domains) + domains?: string | string[]; + + // Advanced matching criteria + path?: string; // Match specific paths + clientIp?: string[]; // Match specific client IPs + tlsVersion?: string[]; // Match specific TLS versions + }; + + // What to do with matched traffic + action: { + // Basic routing + type: 'forward' | 'redirect' | 'block'; + + // Target for forwarding + target?: { + host: string | string[]; // Support single host or round-robin + port: number; + preservePort?: boolean; // Use incoming port as target port + }; + + // TLS handling + tls?: { + mode: 'passthrough' | 'terminate' | 'terminate-and-reencrypt'; + certificate?: 'auto' | { // Auto = use ACME + key: string; + cert: string; + }; + }; + + // For redirects + redirect?: { + to: string; // URL or template with {domain}, {port}, etc. + status: 301 | 302 | 307 | 308; + }; + + // Security options + security?: { + allowedIps?: string[]; + blockedIps?: string[]; + maxConnections?: number; + authentication?: { + type: 'basic' | 'digest' | 'oauth'; + // Auth-specific options + }; + }; + + // Advanced options + advanced?: { + timeout?: number; + headers?: Record; + keepAlive?: boolean; + // etc. + }; + }; + + // Optional metadata + name?: string; // Human-readable name for this route + description?: string; // Description of the route's purpose + priority?: number; // Controls matching order (higher = matched first) + tags?: string[]; // Arbitrary tags for categorization +} -- [ ] Update forwarding configuration interfaces - - [ ] Rename interfaces in `ts/forwarding/config/forwarding-types.ts` - - [ ] `TargetConfig` → `ITargetConfig` - - [ ] `HttpOptions` → `IHttpOptions` - - [ ] `HttpsOptions` → `IHttpsOptions` - - [ ] `AcmeForwardingOptions` → `IAcmeForwardingOptions` - - [ ] `SecurityOptions` → `ISecurityOptions` - - [ ] `AdvancedOptions` → `IAdvancedOptions` - - [ ] `ForwardConfig` → `IForwardConfig` - - [ ] Rename type definitions - - [ ] `ForwardingType` → `TForwardingType` - - [ ] Update domain configuration interfaces +// Main SmartProxy options +interface ISmartProxyOptions { + // The unified configuration array (required) + routes: IRouteConfig[]; + + // Global/default settings + defaults?: { + target?: { + host: string; + port: number; + }; + security?: { + // Global security defaults + }; + tls?: { + // Global TLS defaults + }; + // ...other defaults + }; + + // Other global settings remain (acme, etc.) + acme?: IAcmeOptions; + + // Advanced settings remain as well + // ... +} +``` -- [ ] Standardize handler interfaces - - [ ] Update base handler interfaces - - [ ] Rename handler-specific interfaces - - [ ] Update factory interfaces +### Example Configuration -- [ ] Verify forwarding system functionality - - [ ] Test all forwarding types - - [ ] Verify configuration parsing - - [ ] Ensure backward compatibility +```typescript +const proxy = new SmartProxy({ + // All routing is configured in a single array + routes: [ + // Basic HTTPS server with automatic certificates + { + match: { + ports: 443, + domains: ['example.com', '*.example.com'] + }, + action: { + type: 'forward', + target: { + host: 'localhost', + port: 8080 + }, + tls: { + mode: 'terminate', + certificate: 'auto' // Use ACME + } + }, + name: 'Main HTTPS Server' + }, + + // HTTP to HTTPS redirect + { + match: { + ports: 80, + domains: ['example.com', '*.example.com'] + }, + action: { + type: 'redirect', + redirect: { + to: 'https://{domain}{path}', + status: 301 + } + }, + name: 'HTTP to HTTPS Redirect' + }, + + // Admin portal with IP restriction + { + match: { + ports: 8443, + domains: 'admin.example.com' + }, + action: { + type: 'forward', + target: { + host: 'admin-backend', + port: 3000 + }, + tls: { + mode: 'terminate', + certificate: 'auto' + }, + security: { + allowedIps: ['192.168.1.*', '10.0.0.*'], + maxConnections: 10 + } + }, + priority: 100, // Higher priority than default rules + name: 'Admin Portal' + }, + + // Port range for direct forwarding + { + match: { + ports: [{ from: 10000, to: 10010 }], + // No domains = all domains or direct IP + }, + action: { + type: 'forward', + target: { + host: 'backend-server', + port: 10000, + preservePort: true // Use same port number as incoming + }, + tls: { + mode: 'passthrough' // Direct TCP forwarding + } + }, + name: 'Dynamic Port Range' + }, + + // Path-based routing + { + match: { + ports: 443, + domains: 'api.example.com', + path: '/v1/*' + }, + action: { + type: 'forward', + target: { + host: 'api-v1-service', + port: 8001 + }, + tls: { + mode: 'terminate' + } + }, + name: 'API v1 Endpoints' + }, + + // Load balanced backend + { + match: { + ports: 443, + domains: 'app.example.com' + }, + action: { + type: 'forward', + target: { + // Round-robin load balancing + host: [ + 'app-server-1', + 'app-server-2', + 'app-server-3' + ], + port: 8080 + }, + tls: { + mode: 'terminate' + }, + advanced: { + headers: { + 'X-Served-By': '{server}', + 'X-Client-IP': '{clientIp}' + } + } + }, + name: 'Load Balanced App Servers' + } + ], + + // Global defaults + defaults: { + target: { + host: 'localhost', + port: 8080 + }, + security: { + maxConnections: 1000, + // Global security defaults + } + }, + + // ACME configuration for auto certificates + acme: { + enabled: true, + email: 'admin@example.com', + production: true, + renewThresholdDays: 30 + }, + + // Other global settings + // ... +}); +``` -## Phase 5: Proxy Implementation Standardization +## Implementation Plan -- [ ] Update SmartProxy interfaces - - [ ] Rename interfaces in `ts/proxies/smart-proxy/models/interfaces.ts` - - [ ] Update domain configuration interfaces - - [ ] Standardize manager interfaces +### Phase 1: Core Design & Interface Definition -- [ ] Update NetworkProxy interfaces - - [ ] Rename in `ts/proxies/network-proxy/models/types.ts` - - [ ] `NetworkProxyOptions` → `INetworkProxyOptions` - - [ ] `CertificateEntry` → `ICertificateEntry` - - [ ] `ReverseProxyConfig` → `IReverseProxyConfig` - - [ ] `ConnectionEntry` → `IConnectionEntry` - - [ ] `WebSocketWithHeartbeat` → `IWebSocketWithHeartbeat` - - [ ] `Logger` → `ILogger` - - [ ] Update request handler interfaces - - [ ] Standardize connection interfaces +1. **Define New Core Interfaces**: + - Create `IRouteConfig` interface with `match` and `action` branches + - Define all sub-interfaces for matching and actions + - Update `ISmartProxyOptions` to use `routes` array + - Define template variable system for dynamic values -- [ ] Update NfTablesProxy interfaces - - [ ] Rename interfaces in `ts/proxies/nftables-proxy/models/interfaces.ts` - - [ ] Update configuration interfaces - - [ ] Standardize firewall rule interfaces +2. **Create Helper Functions**: + - `createRoute()` - Basic route creation with reasonable defaults + - `createHttpRoute()`, `createHttpsRoute()`, `createRedirect()` - Common scenarios + - `createLoadBalancer()` - For multi-target setups + - `mergeSecurity()`, `mergeDefaults()` - For combining configs -- [ ] Test proxy implementations - - [ ] Verify SmartProxy functionality - - [ ] Test NetworkProxy with renamed interfaces - - [ ] Validate NfTablesProxy operations +3. **Design Router**: + - Decision tree for route matching algorithm + - Priority system for route ordering + - Optimized lookup strategy for fast routing -## Phase 6: HTTP & TLS Module Standardization +### Phase 2: Core Implementation -- [ ] Update HTTP interfaces - - [ ] Rename in `ts/http/port80/acme-interfaces.ts` - - [ ] `SmartAcmeCert` → `ISmartAcmeCert` - - [ ] `SmartAcmeOptions` → `ISmartAcmeOptions` - - [ ] `Http01Challenge` → `IHttp01Challenge` - - [ ] `SmartAcme` → `ISmartAcme` - - [ ] Standardize router interfaces - - [ ] Update port80 handler interfaces - - [ ] Update redirect interfaces +1. **Create RouteManager**: + - Replaces both PortRangeManager and DomainConfigManager + - Handles all routing decisions in one place + - Provides fast lookup from port+domain+path to action + - Manages server instances for different ports -- [ ] Update TLS/SNI interfaces - - [ ] Standardize SNI handler interfaces - - [ ] Update client hello parser types - - [ ] Rename TLS alert interfaces +2. **Update ConnectionHandler**: + - Simplify to work with the unified route system + - Implement templating system for dynamic values + - Support more sophisticated routing rules -- [ ] Test HTTP & TLS functionality - - [ ] Verify router operation - - [ ] Test SNI extraction - - [ ] Validate redirect functionality +3. **Implement New SmartProxy Core**: + - Rewrite initialization to use route-based configuration + - Create network servers based on port specifications + - Manage TLS contexts and certificates -## Phase 7: Backward Compatibility Layer +### Phase 3: Feature Implementation -- [ ] Implement comprehensive type aliases - - [ ] Create aliases for all renamed interfaces - - [ ] Add deprecation notices via JSDoc - - [ ] Ensure all exports include both named versions +1. **Path-Based Routing**: + - Implement HTTP path matching + - Add wildcard and regex support for paths + - Create route differentiation based on HTTP method -- [ ] Update main entry point - - [ ] Update `ts/index.ts` with all exports - - [ ] Include both prefixed and non-prefixed names - - [ ] Organize exports by module +2. **Enhanced Security**: + - Implement per-route security rules + - Add authentication methods (basic, digest, etc.) + - Support for IP-based access control -- [ ] Add compatibility documentation - - [ ] Document renaming strategy - - [ ] Provide migration examples - - [ ] Create deprecation timeline +3. **TLS Management**: + - Support multiple certificate types (auto, manual, wildcard) + - Implement certificate selection based on SNI + - Support different TLS modes per route -## Phase 8: Documentation & Examples +4. **Metrics & Monitoring**: + - Per-route statistics + - Named route tracking for better visibility + - Tag-based grouping of metrics -- [ ] Update README and API documentation - - [ ] Update interface references in README.md - - [ ] Document naming convention in README.md - - [ ] Update API reference documentation +### Phase 4: Backward Compatibility -- [ ] Update examples - - [ ] Modify example code to use new interface names - - [ ] Add compatibility notes - - [ ] Create migration examples +1. **Legacy Adapter Layer**: + - Convert old configuration format to route-based format + - Map fromPort/toPort/domainConfigs to unified routes + - Preserve all functionality during migration -- [ ] Add contributor guidelines - - [ ] Document naming conventions - - [ ] Add interface/type style guide - - [ ] Update PR templates +2. **API Compatibility**: + - Support both old and new configuration methods + - Add deprecation warnings when using legacy properties + - Provide migration utilities -## Phase 9: Testing & Validation +3. **Documentation**: + - Clear migration guide for existing users + - Examples mapping old config to new config + - Timeline for deprecation -- [ ] Run comprehensive test suite - - [ ] Run all unit tests - - [ ] Execute integration tests - - [ ] Verify example code +### Phase 5: Documentation & Examples -- [ ] Build type declarations - - [ ] Generate TypeScript declaration files - - [ ] Verify exported types - - [ ] Validate documentation generation +1. **Update Core Documentation**: + - Rewrite README.md with a focus on route-based configuration + - Create interface reference documentation + - Document all template variables -- [ ] Final compatibility check - - [ ] Verify import compatibility - - [ ] Test with existing dependent projects - - [ ] Validate backward compatibility claims +2. **Create Example Library**: + - Common configuration patterns + - Complex use cases for advanced features + - Infrastructure-as-code examples + +3. **Add Validation Tooling**: + - Configuration validator to check for issues + - Schema definitions for IDE autocomplete + - Runtime validation helpers + +### Phase 6: Testing + +1. **Unit Tests**: + - Test route matching logic + - Validate priority handling + - Test template processing + +2. **Integration Tests**: + - Verify full proxy flows + - Test complex routing scenarios + - Check backward compatibility + +3. **Performance Testing**: + - Benchmark routing performance + - Evaluate memory usage + - Test with large numbers of routes + +## Benefits of the New Approach + +1. **Truly Unified Configuration**: + - One "source of truth" for all routing + - Entire routing flow visible in a single configuration + - No overlapping or conflicting configuration systems + +2. **Declarative Intent**: + - Configuration clearly states what to match and what action to take + - Metadata provides context and documentation inline + - Easy to understand the purpose of each route + +3. **Advanced Routing Capabilities**: + - Path-based routing with pattern matching + - Client IP-based conditional routing + - Fine-grained security controls + +4. **Composable and Extensible**: + - Each route is a self-contained unit of configuration + - Routes can be grouped by tags or priority + - New match criteria or actions can be added without breaking changes + +5. **Better Developer Experience**: + - Clear, consistent configuration pattern + - Helper functions for common scenarios + - Better error messages and validation + +## Example Use Cases + +### 1. Complete Reverse Proxy with Auto SSL + +```typescript +const proxy = new SmartProxy({ + routes: [ + // HTTPS server for all domains + { + match: { ports: 443 }, + action: { + type: 'forward', + target: { host: 'localhost', port: 8080 }, + tls: { mode: 'terminate', certificate: 'auto' } + } + }, + // HTTP to HTTPS redirect + { + match: { ports: 80 }, + action: { + type: 'redirect', + redirect: { to: 'https://{domain}{path}', status: 301 } + } + } + ], + acme: { + enabled: true, + email: 'admin@example.com', + production: true + } +}); +``` + +### 2. Microservices API Gateway + +```typescript +const apiGateway = new SmartProxy({ + routes: [ + // Users API + { + match: { + ports: 443, + domains: 'api.example.com', + path: '/users/*' + }, + action: { + type: 'forward', + target: { host: 'users-service', port: 8001 }, + tls: { mode: 'terminate', certificate: 'auto' } + }, + name: 'Users Service' + }, + // Products API + { + match: { + ports: 443, + domains: 'api.example.com', + path: '/products/*' + }, + action: { + type: 'forward', + target: { host: 'products-service', port: 8002 }, + tls: { mode: 'terminate', certificate: 'auto' } + }, + name: 'Products Service' + }, + // Orders API with authentication + { + match: { + ports: 443, + domains: 'api.example.com', + path: '/orders/*' + }, + action: { + type: 'forward', + target: { host: 'orders-service', port: 8003 }, + tls: { mode: 'terminate', certificate: 'auto' }, + security: { + authentication: { + type: 'basic', + users: { 'admin': 'password' } + } + } + }, + name: 'Orders Service (Protected)' + } + ], + acme: { + enabled: true, + email: 'admin@example.com' + } +}); +``` + +### 3. Multi-Environment Setup + +```typescript +const environments = { + production: { + target: { host: 'prod-backend', port: 8080 }, + security: { maxConnections: 1000 } + }, + staging: { + target: { host: 'staging-backend', port: 8080 }, + security: { + allowedIps: ['10.0.0.*', '192.168.1.*'], + maxConnections: 100 + } + }, + development: { + target: { host: 'localhost', port: 3000 }, + security: { + allowedIps: ['127.0.0.1'], + maxConnections: 10 + } + } +}; + +// Select environment based on hostname +const proxy = new SmartProxy({ + routes: [ + // Production environment + { + match: { + ports: [80, 443], + domains: ['app.example.com', 'www.example.com'] + }, + action: { + type: 'forward', + target: environments.production.target, + tls: { mode: 'terminate', certificate: 'auto' }, + security: environments.production.security + }, + name: 'Production Environment' + }, + // Staging environment + { + match: { + ports: [80, 443], + domains: 'staging.example.com' + }, + action: { + type: 'forward', + target: environments.staging.target, + tls: { mode: 'terminate', certificate: 'auto' }, + security: environments.staging.security + }, + name: 'Staging Environment' + }, + // Development environment + { + match: { + ports: [80, 443], + domains: 'dev.example.com' + }, + action: { + type: 'forward', + target: environments.development.target, + tls: { mode: 'terminate', certificate: 'auto' }, + security: environments.development.security + }, + name: 'Development Environment' + } + ], + acme: { enabled: true, email: 'admin@example.com' } +}); +``` ## Implementation Strategy -### Naming Pattern Rules +### Code Organization -1. **Interfaces**: - - All interfaces should be prefixed with "I" - - Example: `DomainConfig` → `IDomainConfig` +1. **New Files**: + - `route-manager.ts` (core routing engine) + - `route-types.ts` (interface definitions) + - `route-helpers.ts` (helper functions) + - `route-matcher.ts` (matching logic) + - `template-engine.ts` (for variable substitution) -2. **Type Aliases**: - - All type aliases should be prefixed with "T" - - Example: `ForwardingType` → `TForwardingType` +2. **Modified Files**: + - `smart-proxy.ts` (update to use route-based configuration) + - `connection-handler.ts` (simplify using route-based approach) + - Replace `port-range-manager.ts` and `domain-config-manager.ts` -3. **Enums**: - - Enums should be named in PascalCase without prefix - - Example: `CertificateSource` +### Backward Compatibility -4. **Backward Compatibility**: - - No Backward compatibility. Remove old names. +The backward compatibility layer will convert the legacy configuration to the new format: -### Module Implementation Order - -1. Core module -2. Certificate module -3. Forwarding module -4. Proxy implementations -5. HTTP & TLS modules -6. Main exports and entry points - -### Testing Strategy - -For each module: -1. Rename interfaces and types -2. Add backward compatibility aliases -3. Update imports throughout the module -4. Run tests to verify functionality -5. Commit changes module by module - -## File-Specific Changes - -### Core Module Files -- `ts/core/models/common-types.ts` - Primary interfaces -- `ts/core/utils/validation-utils.ts` - Validation type definitions -- `ts/core/utils/ip-utils.ts` - IP utility type definitions -- `ts/core/utils/event-utils.ts` - Event type definitions - -### Certificate Module Files -- `ts/certificate/models/certificate-types.ts` - Certificate interfaces -- `ts/certificate/acme/acme-factory.ts` - ACME factory types -- `ts/certificate/providers/cert-provisioner.ts` - Provider interfaces -- `ts/certificate/storage/file-storage.ts` - Storage interfaces - -### Forwarding Module Files -- `ts/forwarding/config/forwarding-types.ts` - Forwarding interfaces and types -- `ts/forwarding/config/domain-config.ts` - Domain configuration -- `ts/forwarding/factory/forwarding-factory.ts` - Factory interfaces -- `ts/forwarding/handlers/*.ts` - Handler interfaces - -### Proxy Module Files -- `ts/proxies/network-proxy/models/types.ts` - NetworkProxy interfaces -- `ts/proxies/smart-proxy/models/interfaces.ts` - SmartProxy interfaces -- `ts/proxies/nftables-proxy/models/interfaces.ts` - NfTables interfaces -- `ts/proxies/smart-proxy/connection-manager.ts` - Connection types - -### HTTP/TLS Module Files -- `ts/http/models/http-types.ts` - HTTP module interfaces -- `ts/http/port80/acme-interfaces.ts` - ACME interfaces -- `ts/tls/sni/client-hello-parser.ts` - TLS parser types -- `ts/tls/alerts/tls-alert.ts` - TLS alert interfaces +```typescript +function convertLegacyConfig(legacy: ILegacySmartProxyOptions): ISmartProxyOptions { + const routes: IRouteConfig[] = []; + + // Convert main port configuration + if (legacy.fromPort) { + // Add main listener for fromPort + routes.push({ + match: { ports: legacy.fromPort }, + action: { + type: 'forward', + target: { host: legacy.targetIP || 'localhost', port: legacy.toPort }, + tls: { mode: legacy.sniEnabled ? 'passthrough' : 'terminate' } + }, + name: 'Main Listener (Legacy)' + }); + + // If ACME is enabled, add HTTP listener for challenges + if (legacy.acme?.enabled) { + routes.push({ + match: { ports: 80 }, + action: { + type: 'forward', + target: { host: 'localhost', port: 80 }, + // Special flag for ACME handler + acmeEnabled: true + }, + name: 'ACME Challenge Handler (Legacy)' + }); + } + } + + // Convert domain configs + if (legacy.domainConfigs) { + for (const domainConfig of legacy.domainConfigs) { + const { domains, forwarding } = domainConfig; + + // Determine action based on forwarding type + let action: Partial = { + type: 'forward', + target: { + host: forwarding.target.host, + port: forwarding.target.port + } + }; + + // Set TLS mode based on forwarding type + switch (forwarding.type) { + case 'http-only': + // No TLS + break; + case 'https-passthrough': + action.tls = { mode: 'passthrough' }; + break; + case 'https-terminate-to-http': + action.tls = { + mode: 'terminate', + certificate: forwarding.https?.customCert || 'auto' + }; + break; + case 'https-terminate-to-https': + action.tls = { + mode: 'terminate-and-reencrypt', + certificate: forwarding.https?.customCert || 'auto' + }; + break; + } + + // Security settings + if (forwarding.security) { + action.security = forwarding.security; + } + + // Add HTTP redirect if needed + if (forwarding.http?.redirectToHttps) { + routes.push({ + match: { ports: 80, domains }, + action: { + type: 'redirect', + redirect: { to: 'https://{domain}{path}', status: 301 } + }, + name: `HTTP Redirect for ${domains.join(', ')} (Legacy)` + }); + } + + // Add main route + routes.push({ + match: { + ports: forwarding.type.startsWith('https') ? 443 : 80, + domains + }, + action: action as IRouteAction, + name: `Route for ${domains.join(', ')} (Legacy)` + }); + + // Add port ranges if specified + if (forwarding.advanced?.portRanges) { + for (const range of forwarding.advanced.portRanges) { + routes.push({ + match: { + ports: { from: range.from, to: range.to }, + domains + }, + action: action as IRouteAction, + name: `Port Range ${range.from}-${range.to} for ${domains.join(', ')} (Legacy)` + }); + } + } + } + } + + // Global port ranges + if (legacy.globalPortRanges) { + for (const range of legacy.globalPortRanges) { + routes.push({ + match: { ports: { from: range.from, to: range.to } }, + action: { + type: 'forward', + target: { + host: legacy.targetIP || 'localhost', + port: legacy.forwardAllGlobalRanges ? 0 : legacy.toPort, + preservePort: !!legacy.forwardAllGlobalRanges + }, + tls: { mode: 'passthrough' } + }, + name: `Global Port Range ${range.from}-${range.to} (Legacy)` + }); + } + } + + return { + routes, + defaults: { + target: { + host: legacy.targetIP || 'localhost', + port: legacy.toPort + } + }, + acme: legacy.acme + }; +} +``` ## Success Criteria -- All interfaces are prefixed with "I" -- All type aliases are prefixed with "T" -- All tests pass with new naming conventions -- Documentation is updated with new naming conventions -- Backward compatibility is maintained through type aliases -- Declaration files correctly export both naming conventions \ No newline at end of file +- All existing functionality works with the new route-based configuration +- Performance is equal or better than the current implementation +- Configuration is more intuitive and easier to understand +- New features can be added without breaking existing code +- Code is more maintainable with clear separation of concerns +- Migration from old configuration to new is straightforward \ No newline at end of file