@push.rocks/smartproxy 15.0.2 → 16.0.2

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 (80) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/certificate/index.d.ts +10 -4
  3. package/dist_ts/certificate/index.js +5 -7
  4. package/dist_ts/certificate/models/certificate-types.d.ts +35 -15
  5. package/dist_ts/certificate/providers/cert-provisioner.d.ts +41 -15
  6. package/dist_ts/certificate/providers/cert-provisioner.js +201 -41
  7. package/dist_ts/forwarding/config/forwarding-types.d.ts +40 -76
  8. package/dist_ts/forwarding/config/forwarding-types.js +19 -18
  9. package/dist_ts/forwarding/config/index.d.ts +4 -2
  10. package/dist_ts/forwarding/config/index.js +5 -3
  11. package/dist_ts/forwarding/handlers/base-handler.js +3 -1
  12. package/dist_ts/forwarding/index.d.ts +5 -6
  13. package/dist_ts/forwarding/index.js +3 -3
  14. package/dist_ts/http/models/http-types.js +1 -1
  15. package/dist_ts/http/port80/acme-interfaces.d.ts +30 -0
  16. package/dist_ts/http/port80/acme-interfaces.js +46 -1
  17. package/dist_ts/http/port80/port80-handler.d.ts +17 -2
  18. package/dist_ts/http/port80/port80-handler.js +49 -11
  19. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +2 -61
  20. package/dist_ts/proxies/smart-proxy/models/interfaces.js +5 -4
  21. package/dist_ts/proxies/smart-proxy/models/route-types.d.ts +118 -4
  22. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.d.ts +70 -4
  23. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.js +193 -43
  24. package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +2 -5
  25. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +25 -146
  26. package/dist_ts/proxies/smart-proxy/route-helpers/index.d.ts +7 -0
  27. package/dist_ts/proxies/smart-proxy/route-helpers/index.js +9 -0
  28. package/dist_ts/proxies/smart-proxy/route-helpers.d.ts +54 -1
  29. package/dist_ts/proxies/smart-proxy/route-helpers.js +102 -1
  30. package/dist_ts/proxies/smart-proxy/route-manager.d.ts +3 -9
  31. package/dist_ts/proxies/smart-proxy/route-manager.js +3 -115
  32. package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +72 -10
  33. package/dist_ts/proxies/smart-proxy/smart-proxy.js +135 -268
  34. package/dist_ts/proxies/smart-proxy/timeout-manager.js +3 -3
  35. package/dist_ts/proxies/smart-proxy/utils/index.d.ts +12 -0
  36. package/dist_ts/proxies/smart-proxy/utils/index.js +19 -0
  37. package/dist_ts/proxies/smart-proxy/utils/route-helpers.d.ts +174 -0
  38. package/dist_ts/proxies/smart-proxy/utils/route-helpers.js +332 -0
  39. package/dist_ts/proxies/smart-proxy/utils/route-migration-utils.d.ts +51 -0
  40. package/dist_ts/proxies/smart-proxy/utils/route-migration-utils.js +124 -0
  41. package/dist_ts/proxies/smart-proxy/utils/route-patterns.d.ts +131 -0
  42. package/dist_ts/proxies/smart-proxy/utils/route-patterns.js +217 -0
  43. package/dist_ts/proxies/smart-proxy/utils/route-utils.d.ts +79 -0
  44. package/dist_ts/proxies/smart-proxy/utils/route-utils.js +266 -0
  45. package/dist_ts/proxies/smart-proxy/utils/route-validators.d.ts +73 -0
  46. package/dist_ts/proxies/smart-proxy/utils/route-validators.js +242 -0
  47. package/package.json +1 -1
  48. package/readme.md +139 -111
  49. package/readme.plan.md +164 -312
  50. package/ts/00_commitinfo_data.ts +1 -1
  51. package/ts/certificate/index.ts +17 -9
  52. package/ts/certificate/models/certificate-types.ts +37 -16
  53. package/ts/certificate/providers/cert-provisioner.ts +247 -54
  54. package/ts/forwarding/config/forwarding-types.ts +79 -107
  55. package/ts/forwarding/config/index.ts +4 -2
  56. package/ts/forwarding/handlers/base-handler.ts +4 -2
  57. package/ts/forwarding/index.ts +3 -2
  58. package/ts/http/models/http-types.ts +0 -1
  59. package/ts/http/port80/acme-interfaces.ts +84 -0
  60. package/ts/http/port80/port80-handler.ts +61 -15
  61. package/ts/proxies/smart-proxy/models/interfaces.ts +7 -64
  62. package/ts/proxies/smart-proxy/models/route-types.ts +152 -22
  63. package/ts/proxies/smart-proxy/network-proxy-bridge.ts +226 -55
  64. package/ts/proxies/smart-proxy/route-connection-handler.ts +36 -205
  65. package/ts/proxies/smart-proxy/route-helpers/index.ts +9 -0
  66. package/ts/proxies/smart-proxy/route-helpers.ts +165 -11
  67. package/ts/proxies/smart-proxy/route-manager.ts +3 -130
  68. package/ts/proxies/smart-proxy/smart-proxy.ts +157 -329
  69. package/ts/proxies/smart-proxy/timeout-manager.ts +2 -2
  70. package/ts/proxies/smart-proxy/utils/index.ts +40 -0
  71. package/ts/proxies/smart-proxy/utils/route-helpers.ts +455 -0
  72. package/ts/proxies/smart-proxy/utils/route-migration-utils.ts +165 -0
  73. package/ts/proxies/smart-proxy/utils/route-patterns.ts +309 -0
  74. package/ts/proxies/smart-proxy/utils/route-utils.ts +330 -0
  75. package/ts/proxies/smart-proxy/utils/route-validators.ts +269 -0
  76. package/ts/forwarding/config/domain-config.ts +0 -28
  77. package/ts/forwarding/config/domain-manager.ts +0 -283
  78. package/ts/proxies/smart-proxy/connection-handler.ts +0 -1240
  79. package/ts/proxies/smart-proxy/port-range-manager.ts +0 -211
  80. /package/ts/proxies/smart-proxy/{domain-config-manager.ts → domain-config-manager.ts.bak} +0 -0
@@ -0,0 +1,40 @@
1
+ /**
2
+ * SmartProxy Route Utilities
3
+ *
4
+ * This file exports all route-related utilities for the SmartProxy module,
5
+ * including helpers, validators, utilities, and patterns for working with routes.
6
+ */
7
+
8
+ // Export route helpers for creating routes
9
+ export * from './route-helpers.js';
10
+
11
+ // Export route validators for validating route configurations
12
+ export * from './route-validators.js';
13
+
14
+ // Export route utilities for route operations
15
+ export * from './route-utils.js';
16
+
17
+ // Export route patterns with renamed exports to avoid conflicts
18
+ import {
19
+ createWebSocketRoute as createWebSocketPatternRoute,
20
+ createLoadBalancerRoute as createLoadBalancerPatternRoute,
21
+ createApiGatewayRoute,
22
+ createStaticFileServerRoute,
23
+ addRateLimiting,
24
+ addBasicAuth,
25
+ addJwtAuth
26
+ } from './route-patterns.js';
27
+
28
+ export {
29
+ createWebSocketPatternRoute,
30
+ createLoadBalancerPatternRoute,
31
+ createApiGatewayRoute,
32
+ createStaticFileServerRoute,
33
+ addRateLimiting,
34
+ addBasicAuth,
35
+ addJwtAuth
36
+ };
37
+
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';
@@ -0,0 +1,455 @@
1
+ /**
2
+ * Route Helper Functions
3
+ *
4
+ * This file provides utility functions for creating route configurations for common scenarios.
5
+ * These functions aim to simplify the creation of route configurations for typical use cases.
6
+ *
7
+ * This module includes helper functions for creating:
8
+ * - HTTP routes (createHttpRoute)
9
+ * - HTTPS routes with TLS termination (createHttpsTerminateRoute)
10
+ * - HTTP to HTTPS redirects (createHttpToHttpsRedirect)
11
+ * - HTTPS passthrough routes (createHttpsPassthroughRoute)
12
+ * - Complete HTTPS servers with redirects (createCompleteHttpsServer)
13
+ * - Load balancer routes (createLoadBalancerRoute)
14
+ * - Static file server routes (createStaticFileRoute)
15
+ * - API routes (createApiRoute)
16
+ * - WebSocket routes (createWebSocketRoute)
17
+ */
18
+
19
+ import type { IRouteConfig, IRouteMatch, IRouteAction, IRouteTarget, TPortRange } from '../models/route-types.js';
20
+
21
+ /**
22
+ * Create an HTTP-only route configuration
23
+ * @param domains Domain(s) to match
24
+ * @param target Target host and port
25
+ * @param options Additional route options
26
+ * @returns Route configuration object
27
+ */
28
+ export function createHttpRoute(
29
+ domains: string | string[],
30
+ target: { host: string | string[]; port: number },
31
+ options: Partial<IRouteConfig> = {}
32
+ ): IRouteConfig {
33
+ // Create route match
34
+ const match: IRouteMatch = {
35
+ ports: options.match?.ports || 80,
36
+ domains
37
+ };
38
+
39
+ // Create route action
40
+ const action: IRouteAction = {
41
+ type: 'forward',
42
+ target
43
+ };
44
+
45
+ // Create the route config
46
+ return {
47
+ match,
48
+ action,
49
+ name: options.name || `HTTP Route for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
50
+ ...options
51
+ };
52
+ }
53
+
54
+ /**
55
+ * Create an HTTPS route with TLS termination (including HTTP redirect to HTTPS)
56
+ * @param domains Domain(s) to match
57
+ * @param target Target host and port
58
+ * @param options Additional route options
59
+ * @returns Route configuration object
60
+ */
61
+ export function createHttpsTerminateRoute(
62
+ domains: string | string[],
63
+ target: { host: string | string[]; port: number },
64
+ options: {
65
+ certificate?: 'auto' | { key: string; cert: string };
66
+ httpPort?: number | number[];
67
+ httpsPort?: number | number[];
68
+ reencrypt?: boolean;
69
+ name?: string;
70
+ [key: string]: any;
71
+ } = {}
72
+ ): IRouteConfig {
73
+ // Create route match
74
+ const match: IRouteMatch = {
75
+ ports: options.httpsPort || 443,
76
+ domains
77
+ };
78
+
79
+ // Create route action
80
+ const action: IRouteAction = {
81
+ type: 'forward',
82
+ target,
83
+ tls: {
84
+ mode: options.reencrypt ? 'terminate-and-reencrypt' : 'terminate',
85
+ certificate: options.certificate || 'auto'
86
+ }
87
+ };
88
+
89
+ // Create the route config
90
+ return {
91
+ match,
92
+ action,
93
+ name: options.name || `HTTPS Route for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
94
+ ...options
95
+ };
96
+ }
97
+
98
+ /**
99
+ * Create an HTTP to HTTPS redirect route
100
+ * @param domains Domain(s) to match
101
+ * @param httpsPort HTTPS port to redirect to (default: 443)
102
+ * @param options Additional route options
103
+ * @returns Route configuration object
104
+ */
105
+ export function createHttpToHttpsRedirect(
106
+ domains: string | string[],
107
+ httpsPort: number = 443,
108
+ options: Partial<IRouteConfig> = {}
109
+ ): IRouteConfig {
110
+ // Create route match
111
+ const match: IRouteMatch = {
112
+ ports: options.match?.ports || 80,
113
+ domains
114
+ };
115
+
116
+ // Create route action
117
+ const action: IRouteAction = {
118
+ type: 'redirect',
119
+ redirect: {
120
+ to: `https://{domain}:${httpsPort}{path}`,
121
+ status: 301
122
+ }
123
+ };
124
+
125
+ // Create the route config
126
+ return {
127
+ match,
128
+ action,
129
+ name: options.name || `HTTP to HTTPS Redirect for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
130
+ ...options
131
+ };
132
+ }
133
+
134
+ /**
135
+ * Create an HTTPS passthrough route (SNI-based forwarding without TLS termination)
136
+ * @param domains Domain(s) to match
137
+ * @param target Target host and port
138
+ * @param options Additional route options
139
+ * @returns Route configuration object
140
+ */
141
+ export function createHttpsPassthroughRoute(
142
+ domains: string | string[],
143
+ target: { host: string | string[]; port: number },
144
+ options: Partial<IRouteConfig> = {}
145
+ ): IRouteConfig {
146
+ // Create route match
147
+ const match: IRouteMatch = {
148
+ ports: options.match?.ports || 443,
149
+ domains
150
+ };
151
+
152
+ // Create route action
153
+ const action: IRouteAction = {
154
+ type: 'forward',
155
+ target,
156
+ tls: {
157
+ mode: 'passthrough'
158
+ }
159
+ };
160
+
161
+ // Create the route config
162
+ return {
163
+ match,
164
+ action,
165
+ name: options.name || `HTTPS Passthrough for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
166
+ ...options
167
+ };
168
+ }
169
+
170
+ /**
171
+ * Create a complete HTTPS server with HTTP to HTTPS redirects
172
+ * @param domains Domain(s) to match
173
+ * @param target Target host and port
174
+ * @param options Additional configuration options
175
+ * @returns Array of two route configurations (HTTPS and HTTP redirect)
176
+ */
177
+ export function createCompleteHttpsServer(
178
+ domains: string | string[],
179
+ target: { host: string | string[]; port: number },
180
+ options: {
181
+ certificate?: 'auto' | { key: string; cert: string };
182
+ httpPort?: number | number[];
183
+ httpsPort?: number | number[];
184
+ reencrypt?: boolean;
185
+ name?: string;
186
+ [key: string]: any;
187
+ } = {}
188
+ ): IRouteConfig[] {
189
+ // Create the HTTPS route
190
+ const httpsRoute = createHttpsTerminateRoute(domains, target, options);
191
+
192
+ // Create the HTTP redirect route
193
+ const httpRedirectRoute = createHttpToHttpsRedirect(
194
+ domains,
195
+ // Extract the HTTPS port from the HTTPS route - ensure it's a number
196
+ typeof options.httpsPort === 'number' ? options.httpsPort :
197
+ Array.isArray(options.httpsPort) ? options.httpsPort[0] : 443,
198
+ {
199
+ // Set the HTTP port
200
+ match: {
201
+ ports: options.httpPort || 80,
202
+ domains
203
+ },
204
+ name: `HTTP to HTTPS Redirect for ${Array.isArray(domains) ? domains.join(', ') : domains}`
205
+ }
206
+ );
207
+
208
+ return [httpsRoute, httpRedirectRoute];
209
+ }
210
+
211
+ /**
212
+ * Create a load balancer route (round-robin between multiple backend hosts)
213
+ * @param domains Domain(s) to match
214
+ * @param hosts Array of backend hosts to load balance between
215
+ * @param port Backend port
216
+ * @param options Additional route options
217
+ * @returns Route configuration object
218
+ */
219
+ export function createLoadBalancerRoute(
220
+ domains: string | string[],
221
+ hosts: string[],
222
+ port: number,
223
+ options: {
224
+ tls?: {
225
+ mode: 'passthrough' | 'terminate' | 'terminate-and-reencrypt';
226
+ certificate?: 'auto' | { key: string; cert: string };
227
+ };
228
+ [key: string]: any;
229
+ } = {}
230
+ ): IRouteConfig {
231
+ // Create route match
232
+ const match: IRouteMatch = {
233
+ ports: options.match?.ports || (options.tls ? 443 : 80),
234
+ domains
235
+ };
236
+
237
+ // Create route target
238
+ const target: IRouteTarget = {
239
+ host: hosts,
240
+ port
241
+ };
242
+
243
+ // Create route action
244
+ const action: IRouteAction = {
245
+ type: 'forward',
246
+ target
247
+ };
248
+
249
+ // Add TLS configuration if provided
250
+ if (options.tls) {
251
+ action.tls = {
252
+ mode: options.tls.mode,
253
+ certificate: options.tls.certificate || 'auto'
254
+ };
255
+ }
256
+
257
+ // Create the route config
258
+ return {
259
+ match,
260
+ action,
261
+ name: options.name || `Load Balancer for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
262
+ ...options
263
+ };
264
+ }
265
+
266
+ /**
267
+ * Create a static file server route
268
+ * @param domains Domain(s) to match
269
+ * @param rootDir Root directory path for static files
270
+ * @param options Additional route options
271
+ * @returns Route configuration object
272
+ */
273
+ export function createStaticFileRoute(
274
+ domains: string | string[],
275
+ rootDir: string,
276
+ options: {
277
+ indexFiles?: string[];
278
+ serveOnHttps?: boolean;
279
+ certificate?: 'auto' | { key: string; cert: string };
280
+ httpPort?: number | number[];
281
+ httpsPort?: number | number[];
282
+ name?: string;
283
+ [key: string]: any;
284
+ } = {}
285
+ ): IRouteConfig {
286
+ // Create route match
287
+ const match: IRouteMatch = {
288
+ ports: options.serveOnHttps
289
+ ? (options.httpsPort || 443)
290
+ : (options.httpPort || 80),
291
+ domains
292
+ };
293
+
294
+ // Create route action
295
+ const action: IRouteAction = {
296
+ type: 'static',
297
+ static: {
298
+ root: rootDir,
299
+ index: options.indexFiles || ['index.html', 'index.htm']
300
+ }
301
+ };
302
+
303
+ // Add TLS configuration if serving on HTTPS
304
+ if (options.serveOnHttps) {
305
+ action.tls = {
306
+ mode: 'terminate',
307
+ certificate: options.certificate || 'auto'
308
+ };
309
+ }
310
+
311
+ // Create the route config
312
+ return {
313
+ match,
314
+ action,
315
+ name: options.name || `Static Files for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
316
+ ...options
317
+ };
318
+ }
319
+
320
+ /**
321
+ * Create an API route configuration
322
+ * @param domains Domain(s) to match
323
+ * @param apiPath API base path (e.g., "/api")
324
+ * @param target Target host and port
325
+ * @param options Additional route options
326
+ * @returns Route configuration object
327
+ */
328
+ export function createApiRoute(
329
+ domains: string | string[],
330
+ apiPath: string,
331
+ target: { host: string | string[]; port: number },
332
+ options: {
333
+ useTls?: boolean;
334
+ certificate?: 'auto' | { key: string; cert: string };
335
+ addCorsHeaders?: boolean;
336
+ httpPort?: number | number[];
337
+ httpsPort?: number | number[];
338
+ name?: string;
339
+ [key: string]: any;
340
+ } = {}
341
+ ): IRouteConfig {
342
+ // Normalize API path
343
+ const normalizedPath = apiPath.startsWith('/') ? apiPath : `/${apiPath}`;
344
+ const pathWithWildcard = normalizedPath.endsWith('/')
345
+ ? `${normalizedPath}*`
346
+ : `${normalizedPath}/*`;
347
+
348
+ // Create route match
349
+ const match: IRouteMatch = {
350
+ ports: options.useTls
351
+ ? (options.httpsPort || 443)
352
+ : (options.httpPort || 80),
353
+ domains,
354
+ path: pathWithWildcard
355
+ };
356
+
357
+ // Create route action
358
+ const action: IRouteAction = {
359
+ type: 'forward',
360
+ target
361
+ };
362
+
363
+ // Add TLS configuration if using HTTPS
364
+ if (options.useTls) {
365
+ action.tls = {
366
+ mode: 'terminate',
367
+ certificate: options.certificate || 'auto'
368
+ };
369
+ }
370
+
371
+ // Add CORS headers if requested
372
+ const headers: Record<string, Record<string, string>> = {};
373
+ if (options.addCorsHeaders) {
374
+ headers.response = {
375
+ 'Access-Control-Allow-Origin': '*',
376
+ 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
377
+ 'Access-Control-Allow-Headers': 'Content-Type, Authorization',
378
+ 'Access-Control-Max-Age': '86400'
379
+ };
380
+ }
381
+
382
+ // Create the route config
383
+ return {
384
+ match,
385
+ action,
386
+ headers: Object.keys(headers).length > 0 ? headers : undefined,
387
+ name: options.name || `API Route ${normalizedPath} for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
388
+ priority: options.priority || 100, // Higher priority for specific path matches
389
+ ...options
390
+ };
391
+ }
392
+
393
+ /**
394
+ * Create a WebSocket route configuration
395
+ * @param domains Domain(s) to match
396
+ * @param wsPath WebSocket path (e.g., "/ws")
397
+ * @param target Target WebSocket server host and port
398
+ * @param options Additional route options
399
+ * @returns Route configuration object
400
+ */
401
+ export function createWebSocketRoute(
402
+ domains: string | string[],
403
+ wsPath: string,
404
+ target: { host: string | string[]; port: number },
405
+ options: {
406
+ useTls?: boolean;
407
+ certificate?: 'auto' | { key: string; cert: string };
408
+ httpPort?: number | number[];
409
+ httpsPort?: number | number[];
410
+ pingInterval?: number;
411
+ pingTimeout?: number;
412
+ name?: string;
413
+ [key: string]: any;
414
+ } = {}
415
+ ): IRouteConfig {
416
+ // Normalize WebSocket path
417
+ const normalizedPath = wsPath.startsWith('/') ? wsPath : `/${wsPath}`;
418
+
419
+ // Create route match
420
+ const match: IRouteMatch = {
421
+ ports: options.useTls
422
+ ? (options.httpsPort || 443)
423
+ : (options.httpPort || 80),
424
+ domains,
425
+ path: normalizedPath
426
+ };
427
+
428
+ // Create route action
429
+ const action: IRouteAction = {
430
+ type: 'forward',
431
+ target,
432
+ websocket: {
433
+ enabled: true,
434
+ pingInterval: options.pingInterval || 30000, // 30 seconds
435
+ pingTimeout: options.pingTimeout || 5000 // 5 seconds
436
+ }
437
+ };
438
+
439
+ // Add TLS configuration if using HTTPS
440
+ if (options.useTls) {
441
+ action.tls = {
442
+ mode: 'terminate',
443
+ certificate: options.certificate || 'auto'
444
+ };
445
+ }
446
+
447
+ // Create the route config
448
+ return {
449
+ match,
450
+ action,
451
+ name: options.name || `WebSocket Route ${normalizedPath} for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
452
+ priority: options.priority || 100, // Higher priority for WebSocket routes
453
+ ...options
454
+ };
455
+ }
@@ -0,0 +1,165 @@
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
+ }