@push.rocks/smartproxy 16.0.4 → 17.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/common/port80-adapter.js +29 -3
  3. package/dist_ts/forwarding/config/forwarding-types.d.ts +3 -29
  4. package/dist_ts/forwarding/config/forwarding-types.js +3 -36
  5. package/dist_ts/forwarding/config/index.d.ts +3 -2
  6. package/dist_ts/forwarding/config/index.js +4 -3
  7. package/dist_ts/forwarding/factory/forwarding-factory.js +9 -3
  8. package/dist_ts/forwarding/handlers/base-handler.d.ts +4 -0
  9. package/dist_ts/forwarding/handlers/base-handler.js +25 -3
  10. package/dist_ts/forwarding/index.d.ts +3 -8
  11. package/dist_ts/forwarding/index.js +4 -13
  12. package/dist_ts/proxies/smart-proxy/models/index.d.ts +0 -1
  13. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +0 -9
  14. package/dist_ts/proxies/smart-proxy/models/interfaces.js +1 -12
  15. package/dist_ts/proxies/smart-proxy/models/route-types.d.ts +0 -42
  16. package/dist_ts/proxies/smart-proxy/models/route-types.js +2 -1
  17. package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +0 -3
  18. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +5 -10
  19. package/dist_ts/proxies/smart-proxy/route-manager.js +2 -3
  20. package/dist_ts/proxies/smart-proxy/smart-proxy.js +2 -3
  21. package/dist_ts/proxies/smart-proxy/utils/index.d.ts +0 -2
  22. package/dist_ts/proxies/smart-proxy/utils/index.js +3 -6
  23. package/dist_ts/proxies/smart-proxy/utils/route-patterns.d.ts +48 -0
  24. package/dist_ts/proxies/smart-proxy/utils/route-patterns.js +106 -2
  25. package/package.json +1 -1
  26. package/readme.plan.md +175 -77
  27. package/ts/00_commitinfo_data.ts +1 -1
  28. package/ts/common/port80-adapter.ts +26 -2
  29. package/ts/forwarding/config/forwarding-types.ts +12 -70
  30. package/ts/forwarding/config/index.ts +19 -2
  31. package/ts/forwarding/factory/forwarding-factory.ts +7 -2
  32. package/ts/forwarding/handlers/base-handler.ts +22 -2
  33. package/ts/forwarding/index.ts +17 -17
  34. package/ts/proxies/smart-proxy/models/index.ts +0 -3
  35. package/ts/proxies/smart-proxy/models/interfaces.ts +1 -17
  36. package/ts/proxies/smart-proxy/models/route-types.ts +1 -58
  37. package/ts/proxies/smart-proxy/route-connection-handler.ts +1 -11
  38. package/ts/proxies/smart-proxy/route-manager.ts +3 -8
  39. package/ts/proxies/smart-proxy/smart-proxy.ts +2 -4
  40. package/ts/proxies/smart-proxy/utils/index.ts +2 -5
  41. package/ts/proxies/smart-proxy/utils/route-patterns.ts +146 -2
  42. package/ts/proxies/smart-proxy/utils/route-migration-utils.ts +0 -165
@@ -55,17 +55,37 @@ export abstract class ForwardingHandler extends plugins.EventEmitter implements
55
55
  const randomIndex = Math.floor(Math.random() * target.host.length);
56
56
  return {
57
57
  host: target.host[randomIndex],
58
- port: target.port
58
+ port: this.resolvePort(target.port)
59
59
  };
60
60
  }
61
61
 
62
62
  // Single host
63
63
  return {
64
64
  host: target.host,
65
- port: target.port
65
+ port: this.resolvePort(target.port)
66
66
  };
67
67
  }
68
68
 
69
+ /**
70
+ * Resolves a port value, handling 'preserve' and function ports
71
+ */
72
+ protected resolvePort(port: number | 'preserve' | ((ctx: any) => number)): number {
73
+ if (typeof port === 'function') {
74
+ try {
75
+ // Create a minimal context for the function
76
+ const ctx = { port: 80 }; // Default port for minimal context
77
+ return port(ctx);
78
+ } catch (err) {
79
+ console.error('Error resolving port function:', err);
80
+ return 80; // Default fallback port
81
+ }
82
+ } else if (port === 'preserve') {
83
+ return 80; // Default port for 'preserve' in base handler
84
+ } else {
85
+ return port;
86
+ }
87
+ }
88
+
69
89
  /**
70
90
  * Redirect an HTTP request to HTTPS
71
91
  * @param req The HTTP request
@@ -3,9 +3,6 @@
3
3
  * Provides a flexible and type-safe way to configure and manage various forwarding strategies
4
4
  */
5
5
 
6
- // Export types and configuration
7
- export * from './config/forwarding-types.js';
8
-
9
6
  // Export handlers
10
7
  export { ForwardingHandler } from './handlers/base-handler.js';
11
8
  export * from './handlers/http-handler.js';
@@ -16,20 +13,23 @@ export * from './handlers/https-terminate-to-https-handler.js';
16
13
  // Export factory
17
14
  export * from './factory/forwarding-factory.js';
18
15
 
19
- // Helper functions as a convenience object
20
- import {
21
- httpOnly,
22
- tlsTerminateToHttp,
23
- tlsTerminateToHttps,
24
- httpsPassthrough
16
+ // Export types - these include TForwardingType and IForwardConfig
17
+ export type {
18
+ TForwardingType,
19
+ IForwardConfig,
20
+ IForwardingHandler
25
21
  } from './config/forwarding-types.js';
26
22
 
27
- // Export route-based helpers from smart-proxy
28
- export * from '../proxies/smart-proxy/utils/route-helpers.js';
23
+ export {
24
+ ForwardingHandlerEvents
25
+ } from './config/forwarding-types.js';
29
26
 
30
- export const helpers = {
31
- httpOnly,
32
- tlsTerminateToHttp,
33
- tlsTerminateToHttps,
34
- httpsPassthrough
35
- };
27
+ // Export route helpers directly from route-patterns
28
+ export {
29
+ createHttpRoute,
30
+ createHttpsTerminateRoute,
31
+ createHttpsPassthroughRoute,
32
+ createHttpToHttpsRedirect,
33
+ createCompleteHttpsServer,
34
+ createLoadBalancerRoute
35
+ } from '../proxies/smart-proxy/utils/route-patterns.js';
@@ -3,6 +3,3 @@
3
3
  */
4
4
  export * from './interfaces.js';
5
5
  export * from './route-types.js';
6
-
7
- // Re-export IRoutedSmartProxyOptions explicitly to avoid ambiguity
8
- export type { ISmartProxyOptions as IRoutedSmartProxyOptions } from './interfaces.js';
@@ -8,23 +8,7 @@ import type { TForwardingType } from '../../../forwarding/config/forwarding-type
8
8
  */
9
9
  export type TSmartProxyCertProvisionObject = plugins.tsclass.network.ICert | 'http01';
10
10
 
11
- /**
12
- * Alias for backward compatibility with code that uses IRoutedSmartProxyOptions
13
- */
14
- export type IRoutedSmartProxyOptions = ISmartProxyOptions;
15
-
16
- /**
17
- * Helper functions for type checking configuration types
18
- */
19
- export function isLegacyOptions(options: any): boolean {
20
- // Legacy options are no longer supported
21
- return false;
22
- }
23
-
24
- export function isRoutedOptions(options: any): boolean {
25
- // All configurations are now route-based
26
- return true;
27
- }
11
+ // Legacy options and type checking functions have been removed
28
12
 
29
13
  /**
30
14
  * SmartProxy configuration options
@@ -321,61 +321,4 @@ export interface IRouteConfig {
321
321
  enabled?: boolean; // Whether the route is active (default: true)
322
322
  }
323
323
 
324
- /**
325
- * Unified SmartProxy options with routes-based configuration
326
- */
327
- export interface IRoutedSmartProxyOptions {
328
- // The unified configuration array (required)
329
- routes: IRouteConfig[];
330
-
331
- // Global/default settings
332
- defaults?: {
333
- target?: {
334
- host: string;
335
- port: number;
336
- };
337
- security?: IRouteSecurity;
338
- tls?: IRouteTls;
339
- // ...other defaults
340
- };
341
-
342
- // Other global settings remain (acme, etc.)
343
- acme?: IAcmeOptions;
344
-
345
- // Connection timeouts and other global settings
346
- initialDataTimeout?: number;
347
- socketTimeout?: number;
348
- inactivityCheckInterval?: number;
349
- maxConnectionLifetime?: number;
350
- inactivityTimeout?: number;
351
- gracefulShutdownTimeout?: number;
352
-
353
- // Socket optimization settings
354
- noDelay?: boolean;
355
- keepAlive?: boolean;
356
- keepAliveInitialDelay?: number;
357
- maxPendingDataSize?: number;
358
-
359
- // Enhanced features
360
- disableInactivityCheck?: boolean;
361
- enableKeepAliveProbes?: boolean;
362
- enableDetailedLogging?: boolean;
363
- enableTlsDebugLogging?: boolean;
364
- enableRandomizedTimeouts?: boolean;
365
- allowSessionTicket?: boolean;
366
-
367
- // Rate limiting and security
368
- maxConnectionsPerIP?: number;
369
- connectionRateLimitPerMinute?: number;
370
-
371
- // Enhanced keep-alive settings
372
- keepAliveTreatment?: 'standard' | 'extended' | 'immortal';
373
- keepAliveInactivityMultiplier?: number;
374
- extendedKeepAliveLifetime?: number;
375
-
376
- /**
377
- * Optional certificate provider callback. Return 'http01' to use HTTP-01 challenges,
378
- * or a static certificate object for immediate provisioning.
379
- */
380
- certProvisionFunction?: (domain: string) => Promise<any>;
381
- }
324
+ // Configuration moved to models/interfaces.ts as ISmartProxyOptions
@@ -3,9 +3,7 @@ import type {
3
3
  IConnectionRecord,
4
4
  ISmartProxyOptions
5
5
  } from './models/interfaces.js';
6
- import {
7
- isRoutedOptions
8
- } from './models/interfaces.js';
6
+ // Route checking functions have been removed
9
7
  import type {
10
8
  IRouteConfig,
11
9
  IRouteAction,
@@ -316,7 +314,6 @@ export class RouteConnectionHandler {
316
314
  return this.setupDirectConnection(
317
315
  socket,
318
316
  record,
319
- undefined,
320
317
  serverName,
321
318
  initialChunk,
322
319
  undefined,
@@ -457,7 +454,6 @@ export class RouteConnectionHandler {
457
454
  return this.setupDirectConnection(
458
455
  socket,
459
456
  record,
460
- undefined,
461
457
  record.lockedDomain,
462
458
  initialChunk,
463
459
  undefined,
@@ -538,7 +534,6 @@ export class RouteConnectionHandler {
538
534
  return this.setupDirectConnection(
539
535
  socket,
540
536
  record,
541
- undefined,
542
537
  record.lockedDomain,
543
538
  initialChunk,
544
539
  undefined,
@@ -656,17 +651,12 @@ export class RouteConnectionHandler {
656
651
  this.connectionManager.initiateCleanupOnce(record, 'route_blocked');
657
652
  }
658
653
 
659
- /**
660
- * Legacy connection handling has been removed in favor of pure route-based approach
661
- */
662
-
663
654
  /**
664
655
  * Sets up a direct connection to the target
665
656
  */
666
657
  private setupDirectConnection(
667
658
  socket: plugins.net.Socket,
668
659
  record: IConnectionRecord,
669
- _unused?: any, // kept for backward compatibility
670
660
  serverName?: string,
671
661
  initialChunk?: Buffer,
672
662
  overridePort?: number,
@@ -6,12 +6,7 @@ import type {
6
6
  TPortRange
7
7
  } from './models/route-types.js';
8
8
  import type {
9
- ISmartProxyOptions,
10
- IRoutedSmartProxyOptions
11
- } from './models/interfaces.js';
12
- import {
13
- isRoutedOptions,
14
- isLegacyOptions
9
+ ISmartProxyOptions
15
10
  } from './models/interfaces.js';
16
11
 
17
12
  /**
@@ -29,12 +24,12 @@ export interface IRouteMatchResult {
29
24
  export class RouteManager extends plugins.EventEmitter {
30
25
  private routes: IRouteConfig[] = [];
31
26
  private portMap: Map<number, IRouteConfig[]> = new Map();
32
- private options: IRoutedSmartProxyOptions;
27
+ private options: ISmartProxyOptions;
33
28
 
34
29
  constructor(options: ISmartProxyOptions) {
35
30
  super();
36
31
 
37
- // We no longer support legacy options, always use provided options
32
+ // Store options
38
33
  this.options = options;
39
34
 
40
35
  // Initialize routes from either source
@@ -19,10 +19,8 @@ import { createPort80HandlerOptions } from '../../common/port80-adapter.js';
19
19
 
20
20
  // Import types and utilities
21
21
  import type {
22
- ISmartProxyOptions,
23
- IRoutedSmartProxyOptions
22
+ ISmartProxyOptions
24
23
  } from './models/interfaces.js';
25
- import { isRoutedOptions, isLegacyOptions } from './models/interfaces.js';
26
24
  import type { IRouteConfig } from './models/route-types.js';
27
25
 
28
26
  /**
@@ -650,7 +648,7 @@ export class SmartProxy extends plugins.EventEmitter {
650
648
  const domains: string[] = [];
651
649
 
652
650
  // Get domains from routes
653
- const routes = isRoutedOptions(this.settings) ? this.settings.routes : [];
651
+ const routes = this.settings.routes || [];
654
652
 
655
653
  for (const route of routes) {
656
654
  if (!route.match.domains) continue;
@@ -5,8 +5,7 @@
5
5
  * including helpers, validators, utilities, and patterns for working with routes.
6
6
  */
7
7
 
8
- // Export route helpers for creating routes
9
- export * from './route-helpers.js';
8
+ // Route helpers have been consolidated in route-patterns.js
10
9
 
11
10
  // Export route validators for validating route configurations
12
11
  export * from './route-validators.js';
@@ -35,6 +34,4 @@ export {
35
34
  addJwtAuth
36
35
  };
37
36
 
38
- // Export migration utilities for transitioning from domain-based to route-based configs
39
- // Note: These will be removed in a future version once migration is complete
40
- export * from './route-migration-utils.js';
37
+ // Migration utilities have been removed as they are no longer needed
@@ -5,10 +5,154 @@
5
5
  * These patterns can be used as templates for creating route configurations.
6
6
  */
7
7
 
8
- import type { IRouteConfig } from '../models/route-types.js';
9
- import { createHttpRoute, createHttpsTerminateRoute, createHttpsPassthroughRoute, createCompleteHttpsServer } from './route-helpers.js';
8
+ import type { IRouteConfig, IRouteMatch, IRouteAction, IRouteTarget } from '../models/route-types.js';
10
9
  import { mergeRouteConfigs } from './route-utils.js';
11
10
 
11
+ /**
12
+ * Create a basic HTTP route configuration
13
+ */
14
+ export function createHttpRoute(
15
+ domains: string | string[],
16
+ target: { host: string | string[]; port: number | 'preserve' | ((ctx: any) => number) },
17
+ options: Partial<IRouteConfig> = {}
18
+ ): IRouteConfig {
19
+ const route: IRouteConfig = {
20
+ match: {
21
+ domains,
22
+ ports: 80
23
+ },
24
+ action: {
25
+ type: 'forward',
26
+ target: {
27
+ host: target.host,
28
+ port: target.port
29
+ }
30
+ },
31
+ name: options.name || `HTTP: ${Array.isArray(domains) ? domains.join(', ') : domains}`
32
+ };
33
+
34
+ return mergeRouteConfigs(route, options);
35
+ }
36
+
37
+ /**
38
+ * Create an HTTPS route with TLS termination
39
+ */
40
+ export function createHttpsTerminateRoute(
41
+ domains: string | string[],
42
+ target: { host: string | string[]; port: number | 'preserve' | ((ctx: any) => number) },
43
+ options: Partial<IRouteConfig> & {
44
+ certificate?: 'auto' | { key: string; cert: string };
45
+ reencrypt?: boolean;
46
+ } = {}
47
+ ): IRouteConfig {
48
+ const route: IRouteConfig = {
49
+ match: {
50
+ domains,
51
+ ports: 443
52
+ },
53
+ action: {
54
+ type: 'forward',
55
+ target: {
56
+ host: target.host,
57
+ port: target.port
58
+ },
59
+ tls: {
60
+ mode: options.reencrypt ? 'terminate-and-reencrypt' : 'terminate',
61
+ certificate: options.certificate || 'auto'
62
+ }
63
+ },
64
+ name: options.name || `HTTPS (terminate): ${Array.isArray(domains) ? domains.join(', ') : domains}`
65
+ };
66
+
67
+ return mergeRouteConfigs(route, options);
68
+ }
69
+
70
+ /**
71
+ * Create an HTTPS route with TLS passthrough
72
+ */
73
+ export function createHttpsPassthroughRoute(
74
+ domains: string | string[],
75
+ target: { host: string | string[]; port: number | 'preserve' | ((ctx: any) => number) },
76
+ options: Partial<IRouteConfig> = {}
77
+ ): IRouteConfig {
78
+ const route: IRouteConfig = {
79
+ match: {
80
+ domains,
81
+ ports: 443
82
+ },
83
+ action: {
84
+ type: 'forward',
85
+ target: {
86
+ host: target.host,
87
+ port: target.port
88
+ },
89
+ tls: {
90
+ mode: 'passthrough'
91
+ }
92
+ },
93
+ name: options.name || `HTTPS (passthrough): ${Array.isArray(domains) ? domains.join(', ') : domains}`
94
+ };
95
+
96
+ return mergeRouteConfigs(route, options);
97
+ }
98
+
99
+ /**
100
+ * Create an HTTP to HTTPS redirect route
101
+ */
102
+ export function createHttpToHttpsRedirect(
103
+ domains: string | string[],
104
+ options: Partial<IRouteConfig> & {
105
+ redirectCode?: 301 | 302 | 307 | 308;
106
+ preservePath?: boolean;
107
+ } = {}
108
+ ): IRouteConfig {
109
+ const route: IRouteConfig = {
110
+ match: {
111
+ domains,
112
+ ports: 80
113
+ },
114
+ action: {
115
+ type: 'redirect',
116
+ redirect: {
117
+ to: options.preservePath ? 'https://{domain}{path}' : 'https://{domain}',
118
+ status: options.redirectCode || 301
119
+ }
120
+ },
121
+ name: options.name || `HTTP to HTTPS redirect: ${Array.isArray(domains) ? domains.join(', ') : domains}`
122
+ };
123
+
124
+ return mergeRouteConfigs(route, options);
125
+ }
126
+
127
+ /**
128
+ * Create a complete HTTPS server with redirect from HTTP
129
+ */
130
+ export function createCompleteHttpsServer(
131
+ domains: string | string[],
132
+ target: { host: string | string[]; port: number | 'preserve' | ((ctx: any) => number) },
133
+ options: Partial<IRouteConfig> & {
134
+ certificate?: 'auto' | { key: string; cert: string };
135
+ tlsMode?: 'terminate' | 'passthrough' | 'terminate-and-reencrypt';
136
+ redirectCode?: 301 | 302 | 307 | 308;
137
+ } = {}
138
+ ): IRouteConfig[] {
139
+ // Create the TLS route based on the selected mode
140
+ const tlsRoute = options.tlsMode === 'passthrough'
141
+ ? createHttpsPassthroughRoute(domains, target, options)
142
+ : createHttpsTerminateRoute(domains, target, {
143
+ ...options,
144
+ reencrypt: options.tlsMode === 'terminate-and-reencrypt'
145
+ });
146
+
147
+ // Create the HTTP to HTTPS redirect route
148
+ const redirectRoute = createHttpToHttpsRedirect(domains, {
149
+ redirectCode: options.redirectCode,
150
+ preservePath: true
151
+ });
152
+
153
+ return [tlsRoute, redirectRoute];
154
+ }
155
+
12
156
  /**
13
157
  * Create an API Gateway route pattern
14
158
  * @param domains Domain(s) to match
@@ -1,165 +0,0 @@
1
- /**
2
- * Route Migration Utilities
3
- *
4
- * This file provides utility functions for migrating from legacy domain-based
5
- * configuration to the new route-based configuration system. These functions
6
- * are temporary and will be removed after the migration is complete.
7
- */
8
-
9
- import type { TForwardingType } from '../../../forwarding/config/forwarding-types.js';
10
- import type { IRouteConfig, IRouteMatch, IRouteAction, IRouteTarget } from '../models/route-types.js';
11
-
12
- /**
13
- * Legacy domain config interface (for migration only)
14
- * @deprecated This interface will be removed in a future version
15
- */
16
- export interface ILegacyDomainConfig {
17
- domains: string[];
18
- forwarding: {
19
- type: TForwardingType;
20
- target: {
21
- host: string | string[];
22
- port: number;
23
- };
24
- [key: string]: any;
25
- };
26
- }
27
-
28
- /**
29
- * Convert a legacy domain config to a route-based config
30
- * @param domainConfig Legacy domain configuration
31
- * @param additionalOptions Additional options to add to the route
32
- * @returns Route configuration
33
- * @deprecated This function will be removed in a future version
34
- */
35
- export function domainConfigToRouteConfig(
36
- domainConfig: ILegacyDomainConfig,
37
- additionalOptions: Partial<IRouteConfig> = {}
38
- ): IRouteConfig {
39
- // Default port based on forwarding type
40
- let defaultPort = 80;
41
- let tlsMode: 'passthrough' | 'terminate' | 'terminate-and-reencrypt' | undefined;
42
-
43
- switch (domainConfig.forwarding.type) {
44
- case 'http-only':
45
- defaultPort = 80;
46
- break;
47
- case 'https-passthrough':
48
- defaultPort = 443;
49
- tlsMode = 'passthrough';
50
- break;
51
- case 'https-terminate-to-http':
52
- defaultPort = 443;
53
- tlsMode = 'terminate';
54
- break;
55
- case 'https-terminate-to-https':
56
- defaultPort = 443;
57
- tlsMode = 'terminate-and-reencrypt';
58
- break;
59
- }
60
-
61
- // Create route match criteria
62
- const match: IRouteMatch = {
63
- ports: additionalOptions.match?.ports || defaultPort,
64
- domains: domainConfig.domains
65
- };
66
-
67
- // Create route target
68
- const target: IRouteTarget = {
69
- host: domainConfig.forwarding.target.host,
70
- port: domainConfig.forwarding.target.port
71
- };
72
-
73
- // Create route action
74
- const action: IRouteAction = {
75
- type: 'forward',
76
- target
77
- };
78
-
79
- // Add TLS configuration if needed
80
- if (tlsMode) {
81
- action.tls = {
82
- mode: tlsMode,
83
- certificate: 'auto'
84
- };
85
-
86
- // If the legacy config has custom certificates, use them
87
- if (domainConfig.forwarding.https?.customCert) {
88
- action.tls.certificate = {
89
- key: domainConfig.forwarding.https.customCert.key,
90
- cert: domainConfig.forwarding.https.customCert.cert
91
- };
92
- }
93
- }
94
-
95
- // Add security options if present
96
- if (domainConfig.forwarding.security) {
97
- action.security = domainConfig.forwarding.security;
98
- }
99
-
100
- // Create the route config
101
- const routeConfig: IRouteConfig = {
102
- match,
103
- action,
104
- // Include a name based on domains if not provided
105
- name: additionalOptions.name || `Legacy route for ${domainConfig.domains.join(', ')}`,
106
- // Include a note that this was converted from a legacy config
107
- description: additionalOptions.description || 'Converted from legacy domain configuration'
108
- };
109
-
110
- // Add optional properties if provided
111
- if (additionalOptions.priority !== undefined) {
112
- routeConfig.priority = additionalOptions.priority;
113
- }
114
-
115
- if (additionalOptions.tags) {
116
- routeConfig.tags = additionalOptions.tags;
117
- }
118
-
119
- return routeConfig;
120
- }
121
-
122
- /**
123
- * Convert an array of legacy domain configs to route configurations
124
- * @param domainConfigs Array of legacy domain configurations
125
- * @returns Array of route configurations
126
- * @deprecated This function will be removed in a future version
127
- */
128
- export function domainConfigsToRouteConfigs(
129
- domainConfigs: ILegacyDomainConfig[]
130
- ): IRouteConfig[] {
131
- return domainConfigs.map(config => domainConfigToRouteConfig(config));
132
- }
133
-
134
- /**
135
- * Extract domains from a route configuration
136
- * @param route Route configuration
137
- * @returns Array of domains
138
- */
139
- export function extractDomainsFromRoute(route: IRouteConfig): string[] {
140
- if (!route.match.domains) {
141
- return [];
142
- }
143
-
144
- return Array.isArray(route.match.domains)
145
- ? route.match.domains
146
- : [route.match.domains];
147
- }
148
-
149
- /**
150
- * Extract domains from an array of route configurations
151
- * @param routes Array of route configurations
152
- * @returns Array of unique domains
153
- */
154
- export function extractDomainsFromRoutes(routes: IRouteConfig[]): string[] {
155
- const domains = new Set<string>();
156
-
157
- for (const route of routes) {
158
- const routeDomains = extractDomainsFromRoute(route);
159
- for (const domain of routeDomains) {
160
- domains.add(domain);
161
- }
162
- }
163
-
164
- return Array.from(domains);
165
- }