@push.rocks/smartproxy 15.0.1 → 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 +30 -144
  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 +41 -204
  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
@@ -1,12 +1,10 @@
1
1
  import * as plugins from '../../plugins.js';
2
2
  import type {
3
3
  IConnectionRecord,
4
- IDomainConfig,
5
4
  ISmartProxyOptions
6
5
  } from './models/interfaces.js';
7
6
  import {
8
- isRoutedOptions,
9
- isLegacyOptions
7
+ isRoutedOptions
10
8
  } from './models/interfaces.js';
11
9
  import type {
12
10
  IRouteConfig,
@@ -14,13 +12,11 @@ import type {
14
12
  } from './models/route-types.js';
15
13
  import { ConnectionManager } from './connection-manager.js';
16
14
  import { SecurityManager } from './security-manager.js';
17
- import { DomainConfigManager } from './domain-config-manager.js';
18
15
  import { TlsManager } from './tls-manager.js';
19
16
  import { NetworkProxyBridge } from './network-proxy-bridge.js';
20
17
  import { TimeoutManager } from './timeout-manager.js';
21
18
  import { RouteManager } from './route-manager.js';
22
19
  import type { ForwardingHandler } from '../../forwarding/handlers/base-handler.js';
23
- import type { TForwardingType } from '../../forwarding/config/forwarding-types.js';
24
20
 
25
21
  /**
26
22
  * Handles new connection processing and setup logic with support for route-based configuration
@@ -32,7 +28,6 @@ export class RouteConnectionHandler {
32
28
  settings: ISmartProxyOptions,
33
29
  private connectionManager: ConnectionManager,
34
30
  private securityManager: SecurityManager,
35
- private domainConfigManager: DomainConfigManager,
36
31
  private tlsManager: TlsManager,
37
32
  private networkProxyBridge: NetworkProxyBridge,
38
33
  private timeoutManager: TimeoutManager,
@@ -244,37 +239,20 @@ export class RouteConnectionHandler {
244
239
 
245
240
  if (!routeMatch) {
246
241
  console.log(`[${connectionId}] No route found for ${serverName || 'connection'} on port ${localPort}`);
247
-
248
- // Fall back to legacy matching if we're using a hybrid configuration
249
- const domainConfig = serverName
250
- ? this.domainConfigManager.findDomainConfig(serverName)
251
- : this.domainConfigManager.findDomainConfigForPort(localPort);
252
242
 
253
- if (domainConfig) {
254
- if (this.settings.enableDetailedLogging) {
255
- console.log(`[${connectionId}] Using legacy domain configuration for ${serverName || 'port ' + localPort}`);
256
- }
257
-
258
- // Associate this domain config with the connection
259
- record.domainConfig = domainConfig;
260
-
261
- // Handle the connection using the legacy setup
262
- return this.handleLegacyConnection(socket, record, serverName, domainConfig, initialChunk);
263
- }
264
-
265
- // No matching route or domain config, use default/fallback handling
243
+ // No matching route, use default/fallback handling
266
244
  console.log(`[${connectionId}] Using default route handling for connection`);
267
-
245
+
268
246
  // Check default security settings
269
247
  const defaultSecuritySettings = this.settings.defaults?.security;
270
248
  if (defaultSecuritySettings) {
271
- if (defaultSecuritySettings.allowedIPs && defaultSecuritySettings.allowedIPs.length > 0) {
249
+ if (defaultSecuritySettings.allowedIps && defaultSecuritySettings.allowedIps.length > 0) {
272
250
  const isAllowed = this.securityManager.isIPAuthorized(
273
251
  remoteIP,
274
- defaultSecuritySettings.allowedIPs,
275
- defaultSecuritySettings.blockedIPs || []
252
+ defaultSecuritySettings.allowedIps,
253
+ defaultSecuritySettings.blockedIps || []
276
254
  );
277
-
255
+
278
256
  if (!isAllowed) {
279
257
  console.log(`[${connectionId}] IP ${remoteIP} not in default allowed list`);
280
258
  socket.end();
@@ -282,46 +260,31 @@ export class RouteConnectionHandler {
282
260
  return;
283
261
  }
284
262
  }
285
- } else if (this.settings.defaultAllowedIPs && this.settings.defaultAllowedIPs.length > 0) {
286
- // Legacy default IP restrictions
287
- const isAllowed = this.securityManager.isIPAuthorized(
288
- remoteIP,
289
- this.settings.defaultAllowedIPs,
290
- this.settings.defaultBlockedIPs || []
291
- );
292
-
293
- if (!isAllowed) {
294
- console.log(`[${connectionId}] IP ${remoteIP} not in default allowed list`);
295
- socket.end();
296
- this.connectionManager.cleanupConnection(record, 'ip_blocked');
297
- return;
298
- }
299
263
  }
300
264
 
301
265
  // Setup direct connection with default settings
302
- let targetHost: string;
303
- let targetPort: number;
304
-
305
- if (isRoutedOptions(this.settings) && this.settings.defaults?.target) {
306
- // Use defaults from routed configuration
307
- targetHost = this.settings.defaults.target.host;
308
- targetPort = this.settings.defaults.target.port;
266
+ if (this.settings.defaults?.target) {
267
+ // Use defaults from configuration
268
+ const targetHost = this.settings.defaults.target.host;
269
+ const targetPort = this.settings.defaults.target.port;
270
+
271
+ return this.setupDirectConnection(
272
+ socket,
273
+ record,
274
+ undefined,
275
+ serverName,
276
+ initialChunk,
277
+ undefined,
278
+ targetHost,
279
+ targetPort
280
+ );
309
281
  } else {
310
- // Fall back to legacy settings
311
- targetHost = this.settings.targetIP || 'localhost';
312
- targetPort = this.settings.toPort;
282
+ // No default target available, terminate the connection
283
+ console.log(`[${connectionId}] No default target configured. Closing connection.`);
284
+ socket.end();
285
+ this.connectionManager.cleanupConnection(record, 'no_default_target');
286
+ return;
313
287
  }
314
-
315
- return this.setupDirectConnection(
316
- socket,
317
- record,
318
- undefined,
319
- serverName,
320
- initialChunk,
321
- undefined,
322
- targetHost,
323
- targetPort
324
- );
325
288
  }
326
289
 
327
290
  // A matching route was found
@@ -569,114 +532,8 @@ export class RouteConnectionHandler {
569
532
  }
570
533
 
571
534
  /**
572
- * Handle a connection using legacy domain configuration
535
+ * Legacy connection handling has been removed in favor of pure route-based approach
573
536
  */
574
- private handleLegacyConnection(
575
- socket: plugins.net.Socket,
576
- record: IConnectionRecord,
577
- serverName: string,
578
- domainConfig: IDomainConfig,
579
- initialChunk?: Buffer
580
- ): void {
581
- const connectionId = record.id;
582
-
583
- // Get the forwarding type for this domain
584
- const forwardingType = this.domainConfigManager.getForwardingType(domainConfig);
585
-
586
- // IP validation
587
- const ipRules = this.domainConfigManager.getEffectiveIPRules(domainConfig);
588
-
589
- if (!this.securityManager.isIPAuthorized(record.remoteIP, ipRules.allowedIPs, ipRules.blockedIPs)) {
590
- console.log(
591
- `[${connectionId}] Connection rejected: IP ${record.remoteIP} not allowed for domain ${domainConfig.domains.join(', ')}`
592
- );
593
- socket.end();
594
- this.connectionManager.initiateCleanupOnce(record, 'ip_blocked');
595
- return;
596
- }
597
-
598
- // Handle based on forwarding type
599
- switch (forwardingType) {
600
- case 'http-only':
601
- // For HTTP-only configs with TLS traffic
602
- if (record.isTLS) {
603
- console.log(`[${connectionId}] Received TLS connection for HTTP-only domain ${serverName}`);
604
- socket.end();
605
- this.connectionManager.initiateCleanupOnce(record, 'wrong_protocol');
606
- return;
607
- }
608
- break;
609
-
610
- case 'https-passthrough':
611
- // For TLS passthrough with TLS traffic
612
- if (record.isTLS) {
613
- try {
614
- const handler = this.domainConfigManager.getForwardingHandler(domainConfig);
615
-
616
- if (this.settings.enableDetailedLogging) {
617
- console.log(`[${connectionId}] Using forwarding handler for SNI passthrough to ${serverName}`);
618
- }
619
-
620
- // Handle the connection using the handler
621
- return handler.handleConnection(socket);
622
- } catch (err) {
623
- console.log(`[${connectionId}] Error using forwarding handler: ${err}`);
624
- }
625
- }
626
- break;
627
-
628
- case 'https-terminate-to-http':
629
- case 'https-terminate-to-https':
630
- // For TLS termination with TLS traffic
631
- if (record.isTLS) {
632
- const networkProxyPort = this.domainConfigManager.getNetworkProxyPort(domainConfig);
633
-
634
- if (this.settings.enableDetailedLogging) {
635
- console.log(`[${connectionId}] Using TLS termination (${forwardingType}) for ${serverName} on port ${networkProxyPort}`);
636
- }
637
-
638
- // Forward to NetworkProxy with domain-specific port
639
- return this.networkProxyBridge.forwardToNetworkProxy(
640
- connectionId,
641
- socket,
642
- record,
643
- initialChunk!,
644
- networkProxyPort,
645
- (reason) => this.connectionManager.initiateCleanupOnce(record, reason)
646
- );
647
- }
648
- break;
649
- }
650
-
651
- // If we're still here, use the forwarding handler if available
652
- try {
653
- const handler = this.domainConfigManager.getForwardingHandler(domainConfig);
654
-
655
- if (this.settings.enableDetailedLogging) {
656
- console.log(`[${connectionId}] Using general forwarding handler for domain ${serverName || 'unknown'}`);
657
- }
658
-
659
- // Handle the connection using the handler
660
- return handler.handleConnection(socket);
661
- } catch (err) {
662
- console.log(`[${connectionId}] Error using forwarding handler: ${err}`);
663
- }
664
-
665
- // Fallback: set up direct connection
666
- const targetIp = this.domainConfigManager.getTargetIP(domainConfig);
667
- const targetPort = this.domainConfigManager.getTargetPort(domainConfig, this.settings.toPort);
668
-
669
- return this.setupDirectConnection(
670
- socket,
671
- record,
672
- domainConfig,
673
- serverName,
674
- initialChunk,
675
- undefined,
676
- targetIp,
677
- targetPort
678
- );
679
- }
680
537
 
681
538
  /**
682
539
  * Sets up a direct connection to the target
@@ -684,7 +541,7 @@ export class RouteConnectionHandler {
684
541
  private setupDirectConnection(
685
542
  socket: plugins.net.Socket,
686
543
  record: IConnectionRecord,
687
- domainConfig?: IDomainConfig,
544
+ _unused?: any, // kept for backward compatibility
688
545
  serverName?: string,
689
546
  initialChunk?: Buffer,
690
547
  overridePort?: number,
@@ -692,22 +549,15 @@ export class RouteConnectionHandler {
692
549
  targetPort?: number
693
550
  ): void {
694
551
  const connectionId = record.id;
695
-
552
+
696
553
  // Determine target host and port if not provided
697
- const finalTargetHost = targetHost || (domainConfig
698
- ? this.domainConfigManager.getTargetIP(domainConfig)
699
- : this.settings.defaults?.target?.host
700
- ? this.settings.defaults.target.host
701
- : this.settings.targetIP!);
554
+ const finalTargetHost = targetHost ||
555
+ (this.settings.defaults?.target?.host || 'localhost');
702
556
 
703
- // Determine target port - first try explicit port, then forwarding config, then fallback
704
- const finalTargetPort = targetPort || (overridePort !== undefined
705
- ? overridePort
706
- : domainConfig
707
- ? this.domainConfigManager.getTargetPort(domainConfig, this.settings.toPort)
708
- : this.settings.defaults?.target?.port
709
- ? this.settings.defaults.target.port
710
- : this.settings.toPort);
557
+ // Determine target port
558
+ const finalTargetPort = targetPort ||
559
+ (overridePort !== undefined ? overridePort :
560
+ (this.settings.defaults?.target?.port || 443));
711
561
 
712
562
  // Setup connection options
713
563
  const connectionOptions: plugins.net.NetConnectOpts = {
@@ -891,20 +741,7 @@ export class RouteConnectionHandler {
891
741
  this.connectionManager.incrementTerminationStat('outgoing', 'connection_failed');
892
742
  }
893
743
 
894
- // If we have a forwarding handler for this domain, let it handle the error
895
- if (domainConfig) {
896
- try {
897
- const forwardingHandler = this.domainConfigManager.getForwardingHandler(domainConfig);
898
- forwardingHandler.emit('connection_error', {
899
- socket,
900
- error: err,
901
- connectionId
902
- });
903
- } catch (handlerErr) {
904
- // If getting the handler fails, just log and continue with normal cleanup
905
- console.log(`Error getting forwarding handler for error handling: ${handlerErr}`);
906
- }
907
- }
744
+ // Route-based configuration doesn't use domain handlers
908
745
 
909
746
  // Clean up the connection
910
747
  this.connectionManager.initiateCleanupOnce(record, `connection_failed_${code}`);
@@ -1037,8 +874,8 @@ export class RouteConnectionHandler {
1037
874
  `${
1038
875
  serverName
1039
876
  ? ` (SNI: ${serverName})`
1040
- : domainConfig
1041
- ? ` (Port-based for domain: ${domainConfig.domains.join(', ')})`
877
+ : record.lockedDomain
878
+ ? ` (Domain: ${record.lockedDomain})`
1042
879
  : ''
1043
880
  }` +
1044
881
  ` TLS: ${record.isTLS ? 'Yes' : 'No'}, Keep-Alive: ${
@@ -1051,8 +888,8 @@ export class RouteConnectionHandler {
1051
888
  `${
1052
889
  serverName
1053
890
  ? ` (SNI: ${serverName})`
1054
- : domainConfig
1055
- ? ` (Port-based for domain: ${domainConfig.domains.join(', ')})`
891
+ : record.lockedDomain
892
+ ? ` (Domain: ${record.lockedDomain})`
1056
893
  : ''
1057
894
  }`
1058
895
  );
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Route helpers for SmartProxy
3
+ *
4
+ * This module provides helper functions for creating various types of route configurations
5
+ * to be used with the SmartProxy system.
6
+ */
7
+
8
+ // Re-export all functions from the route-helpers.ts file
9
+ export * from '../route-helpers.js';
@@ -1,12 +1,13 @@
1
- import type {
2
- IRouteConfig,
3
- IRouteMatch,
4
- IRouteAction,
1
+ import type {
2
+ IRouteConfig,
3
+ IRouteMatch,
4
+ IRouteAction,
5
5
  IRouteTarget,
6
6
  IRouteTls,
7
7
  IRouteRedirect,
8
8
  IRouteSecurity,
9
- IRouteAdvanced
9
+ IRouteAdvanced,
10
+ TPortRange
10
11
  } from './models/route-types.js';
11
12
 
12
13
  /**
@@ -30,7 +31,7 @@ export function createRoute(
30
31
  }
31
32
 
32
33
  /**
33
- * Create a basic HTTP route configuration
34
+ * Create a basic HTTP route configuration
34
35
  */
35
36
  export function createHttpRoute(
36
37
  options: {
@@ -206,7 +207,7 @@ export function createHttpToHttpsRedirect(
206
207
  }
207
208
  ): IRouteConfig {
208
209
  const domainArray = Array.isArray(options.domains) ? options.domains : [options.domains];
209
-
210
+
210
211
  return createRedirectRoute({
211
212
  ports: 80,
212
213
  domains: options.domains,
@@ -270,7 +271,7 @@ export function createLoadBalancerRoute(
270
271
  ): IRouteConfig {
271
272
  const useTls = options.tlsMode !== undefined;
272
273
  const defaultPort = useTls ? 443 : 80;
273
-
274
+
274
275
  return createRoute(
275
276
  {
276
277
  ports: options.ports || defaultPort,
@@ -321,7 +322,7 @@ export function createHttpsServer(
321
322
  ): IRouteConfig[] {
322
323
  const routes: IRouteConfig[] = [];
323
324
  const domainArray = Array.isArray(options.domains) ? options.domains : [options.domains];
324
-
325
+
325
326
  // Add HTTPS route
326
327
  routes.push(createHttpsRoute({
327
328
  domains: options.domains,
@@ -330,7 +331,7 @@ export function createHttpsServer(
330
331
  security: options.security,
331
332
  name: options.name || `HTTPS Server for ${domainArray.join(', ')}`
332
333
  }));
333
-
334
+
334
335
  // Add HTTP to HTTPS redirect if requested
335
336
  if (options.addHttpRedirect !== false) {
336
337
  routes.push(createHttpToHttpsRedirect({
@@ -339,6 +340,159 @@ export function createHttpsServer(
339
340
  priority: 100
340
341
  }));
341
342
  }
342
-
343
+
343
344
  return routes;
345
+ }
346
+
347
+ /**
348
+ * Create a port range configuration from various input formats
349
+ */
350
+ export function createPortRange(
351
+ ports: number | number[] | string | Array<{ from: number; to: number }>
352
+ ): TPortRange {
353
+ // If it's a string like "80,443" or "8000-9000", parse it
354
+ if (typeof ports === 'string') {
355
+ if (ports.includes('-')) {
356
+ // Handle range like "8000-9000"
357
+ const [start, end] = ports.split('-').map(p => parseInt(p.trim(), 10));
358
+ return [{ from: start, to: end }];
359
+ } else if (ports.includes(',')) {
360
+ // Handle comma-separated list like "80,443,8080"
361
+ return ports.split(',').map(p => parseInt(p.trim(), 10));
362
+ } else {
363
+ // Handle single port as string
364
+ return parseInt(ports.trim(), 10);
365
+ }
366
+ }
367
+
368
+ // Otherwise return as is
369
+ return ports;
370
+ }
371
+
372
+ /**
373
+ * Create a security configuration object
374
+ */
375
+ export function createSecurityConfig(
376
+ options: {
377
+ allowedIps?: string[];
378
+ blockedIps?: string[];
379
+ maxConnections?: number;
380
+ authentication?: {
381
+ type: 'basic' | 'digest' | 'oauth';
382
+ // Auth-specific options
383
+ [key: string]: any;
384
+ };
385
+ }
386
+ ): IRouteSecurity {
387
+ return {
388
+ ...(options.allowedIps ? { allowedIps: options.allowedIps } : {}),
389
+ ...(options.blockedIps ? { blockedIps: options.blockedIps } : {}),
390
+ ...(options.maxConnections ? { maxConnections: options.maxConnections } : {}),
391
+ ...(options.authentication ? { authentication: options.authentication } : {})
392
+ };
393
+ }
394
+
395
+ /**
396
+ * Create a static file server route
397
+ */
398
+ export function createStaticFileRoute(
399
+ options: {
400
+ ports?: number | number[]; // Default: 80
401
+ domains: string | string[];
402
+ path?: string;
403
+ targetDirectory: string;
404
+ tlsMode?: 'terminate' | 'terminate-and-reencrypt';
405
+ certificate?: 'auto' | { key: string; cert: string };
406
+ headers?: Record<string, string>;
407
+ security?: IRouteSecurity;
408
+ name?: string;
409
+ description?: string;
410
+ priority?: number;
411
+ tags?: string[];
412
+ }
413
+ ): IRouteConfig {
414
+ const useTls = options.tlsMode !== undefined;
415
+ const defaultPort = useTls ? 443 : 80;
416
+
417
+ return createRoute(
418
+ {
419
+ ports: options.ports || defaultPort,
420
+ domains: options.domains,
421
+ ...(options.path ? { path: options.path } : {})
422
+ },
423
+ {
424
+ type: 'forward',
425
+ target: {
426
+ host: 'localhost', // Static file serving is typically handled locally
427
+ port: 0, // Special value indicating a static file server
428
+ preservePort: false
429
+ },
430
+ ...(useTls ? {
431
+ tls: {
432
+ mode: options.tlsMode!,
433
+ certificate: options.certificate || 'auto'
434
+ }
435
+ } : {}),
436
+ advanced: {
437
+ ...(options.headers ? { headers: options.headers } : {}),
438
+ staticFiles: {
439
+ root: options.targetDirectory,
440
+ index: ['index.html', 'index.htm'],
441
+ directory: options.targetDirectory // For backward compatibility
442
+ }
443
+ },
444
+ ...(options.security ? { security: options.security } : {})
445
+ },
446
+ {
447
+ name: options.name || 'Static File Server',
448
+ description: options.description || `Serving static files from ${options.targetDirectory}`,
449
+ priority: options.priority,
450
+ tags: options.tags
451
+ }
452
+ );
453
+ }
454
+
455
+ /**
456
+ * Create a test route for debugging purposes
457
+ */
458
+ export function createTestRoute(
459
+ options: {
460
+ ports?: number | number[]; // Default: 8000
461
+ domains?: string | string[];
462
+ path?: string;
463
+ response?: {
464
+ status?: number;
465
+ headers?: Record<string, string>;
466
+ body?: string;
467
+ };
468
+ name?: string;
469
+ }
470
+ ): IRouteConfig {
471
+ return createRoute(
472
+ {
473
+ ports: options.ports || 8000,
474
+ ...(options.domains ? { domains: options.domains } : {}),
475
+ ...(options.path ? { path: options.path } : {})
476
+ },
477
+ {
478
+ type: 'forward',
479
+ target: {
480
+ host: 'test', // Special value indicating a test route
481
+ port: 0
482
+ },
483
+ advanced: {
484
+ testResponse: {
485
+ status: options.response?.status || 200,
486
+ headers: options.response?.headers || { 'Content-Type': 'text/plain' },
487
+ body: options.response?.body || 'Test route is working!'
488
+ }
489
+ }
490
+ },
491
+ {
492
+ name: options.name || 'Test Route',
493
+ description: 'Route for testing and debugging',
494
+ priority: 500,
495
+ tags: ['test', 'debug']
496
+ }
497
+ );
344
498
  }