@push.rocks/smartproxy 16.0.2 → 16.0.3

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 (115) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/core/models/index.d.ts +2 -0
  3. package/dist_ts/core/models/index.js +3 -1
  4. package/dist_ts/core/models/route-context.d.ts +62 -0
  5. package/dist_ts/core/models/route-context.js +43 -0
  6. package/dist_ts/core/models/socket-augmentation.d.ts +12 -0
  7. package/dist_ts/core/models/socket-augmentation.js +18 -0
  8. package/dist_ts/core/utils/event-system.d.ts +200 -0
  9. package/dist_ts/core/utils/event-system.js +224 -0
  10. package/dist_ts/core/utils/index.d.ts +7 -0
  11. package/dist_ts/core/utils/index.js +8 -1
  12. package/dist_ts/core/utils/route-manager.d.ts +118 -0
  13. package/dist_ts/core/utils/route-manager.js +383 -0
  14. package/dist_ts/core/utils/route-utils.d.ts +94 -0
  15. package/dist_ts/core/utils/route-utils.js +264 -0
  16. package/dist_ts/core/utils/security-utils.d.ts +111 -0
  17. package/dist_ts/core/utils/security-utils.js +212 -0
  18. package/dist_ts/core/utils/shared-security-manager.d.ts +110 -0
  19. package/dist_ts/core/utils/shared-security-manager.js +252 -0
  20. package/dist_ts/core/utils/template-utils.d.ts +37 -0
  21. package/dist_ts/core/utils/template-utils.js +104 -0
  22. package/dist_ts/core/utils/websocket-utils.d.ts +23 -0
  23. package/dist_ts/core/utils/websocket-utils.js +86 -0
  24. package/dist_ts/http/router/index.d.ts +5 -1
  25. package/dist_ts/http/router/index.js +4 -2
  26. package/dist_ts/http/router/route-router.d.ts +108 -0
  27. package/dist_ts/http/router/route-router.js +393 -0
  28. package/dist_ts/index.d.ts +8 -2
  29. package/dist_ts/index.js +10 -3
  30. package/dist_ts/proxies/index.d.ts +7 -2
  31. package/dist_ts/proxies/index.js +10 -4
  32. package/dist_ts/proxies/network-proxy/certificate-manager.d.ts +21 -0
  33. package/dist_ts/proxies/network-proxy/certificate-manager.js +92 -1
  34. package/dist_ts/proxies/network-proxy/context-creator.d.ts +34 -0
  35. package/dist_ts/proxies/network-proxy/context-creator.js +108 -0
  36. package/dist_ts/proxies/network-proxy/function-cache.d.ts +90 -0
  37. package/dist_ts/proxies/network-proxy/function-cache.js +198 -0
  38. package/dist_ts/proxies/network-proxy/http-request-handler.d.ts +40 -0
  39. package/dist_ts/proxies/network-proxy/http-request-handler.js +256 -0
  40. package/dist_ts/proxies/network-proxy/http2-request-handler.d.ts +24 -0
  41. package/dist_ts/proxies/network-proxy/http2-request-handler.js +201 -0
  42. package/dist_ts/proxies/network-proxy/models/types.d.ts +73 -1
  43. package/dist_ts/proxies/network-proxy/models/types.js +242 -1
  44. package/dist_ts/proxies/network-proxy/network-proxy.d.ts +23 -20
  45. package/dist_ts/proxies/network-proxy/network-proxy.js +147 -60
  46. package/dist_ts/proxies/network-proxy/request-handler.d.ts +38 -5
  47. package/dist_ts/proxies/network-proxy/request-handler.js +584 -198
  48. package/dist_ts/proxies/network-proxy/security-manager.d.ts +65 -0
  49. package/dist_ts/proxies/network-proxy/security-manager.js +255 -0
  50. package/dist_ts/proxies/network-proxy/websocket-handler.d.ts +13 -2
  51. package/dist_ts/proxies/network-proxy/websocket-handler.js +238 -20
  52. package/dist_ts/proxies/smart-proxy/index.d.ts +1 -1
  53. package/dist_ts/proxies/smart-proxy/index.js +3 -3
  54. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +3 -5
  55. package/dist_ts/proxies/smart-proxy/models/route-types.d.ts +56 -3
  56. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.d.ts +4 -57
  57. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.js +19 -228
  58. package/dist_ts/proxies/smart-proxy/port-manager.d.ts +81 -0
  59. package/dist_ts/proxies/smart-proxy/port-manager.js +166 -0
  60. package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +5 -0
  61. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +131 -15
  62. package/dist_ts/proxies/smart-proxy/route-helpers/index.d.ts +3 -1
  63. package/dist_ts/proxies/smart-proxy/route-helpers/index.js +5 -3
  64. package/dist_ts/proxies/smart-proxy/route-helpers.d.ts +5 -178
  65. package/dist_ts/proxies/smart-proxy/route-helpers.js +8 -296
  66. package/dist_ts/proxies/smart-proxy/route-manager.d.ts +11 -2
  67. package/dist_ts/proxies/smart-proxy/route-manager.js +79 -10
  68. package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +29 -2
  69. package/dist_ts/proxies/smart-proxy/smart-proxy.js +48 -43
  70. package/dist_ts/proxies/smart-proxy/utils/route-helpers.d.ts +67 -1
  71. package/dist_ts/proxies/smart-proxy/utils/route-helpers.js +120 -1
  72. package/dist_ts/proxies/smart-proxy/utils/route-validators.d.ts +3 -3
  73. package/dist_ts/proxies/smart-proxy/utils/route-validators.js +27 -5
  74. package/package.json +1 -1
  75. package/readme.md +102 -14
  76. package/readme.plan.md +103 -168
  77. package/ts/00_commitinfo_data.ts +1 -1
  78. package/ts/core/models/index.ts +2 -0
  79. package/ts/core/models/route-context.ts +113 -0
  80. package/ts/core/models/socket-augmentation.ts +33 -0
  81. package/ts/core/utils/event-system.ts +376 -0
  82. package/ts/core/utils/index.ts +7 -0
  83. package/ts/core/utils/route-manager.ts +489 -0
  84. package/ts/core/utils/route-utils.ts +312 -0
  85. package/ts/core/utils/security-utils.ts +309 -0
  86. package/ts/core/utils/shared-security-manager.ts +333 -0
  87. package/ts/core/utils/template-utils.ts +124 -0
  88. package/ts/core/utils/websocket-utils.ts +81 -0
  89. package/ts/http/router/index.ts +8 -1
  90. package/ts/http/router/route-router.ts +482 -0
  91. package/ts/index.ts +14 -2
  92. package/ts/proxies/index.ts +12 -3
  93. package/ts/proxies/network-proxy/certificate-manager.ts +114 -10
  94. package/ts/proxies/network-proxy/context-creator.ts +145 -0
  95. package/ts/proxies/network-proxy/function-cache.ts +259 -0
  96. package/ts/proxies/network-proxy/http-request-handler.ts +330 -0
  97. package/ts/proxies/network-proxy/http2-request-handler.ts +255 -0
  98. package/ts/proxies/network-proxy/models/types.ts +312 -1
  99. package/ts/proxies/network-proxy/network-proxy.ts +195 -86
  100. package/ts/proxies/network-proxy/request-handler.ts +698 -246
  101. package/ts/proxies/network-proxy/security-manager.ts +298 -0
  102. package/ts/proxies/network-proxy/websocket-handler.ts +276 -33
  103. package/ts/proxies/smart-proxy/index.ts +2 -12
  104. package/ts/proxies/smart-proxy/models/interfaces.ts +7 -4
  105. package/ts/proxies/smart-proxy/models/route-types.ts +78 -10
  106. package/ts/proxies/smart-proxy/network-proxy-bridge.ts +20 -257
  107. package/ts/proxies/smart-proxy/port-manager.ts +195 -0
  108. package/ts/proxies/smart-proxy/route-connection-handler.ts +156 -21
  109. package/ts/proxies/smart-proxy/route-manager.ts +98 -14
  110. package/ts/proxies/smart-proxy/smart-proxy.ts +56 -55
  111. package/ts/proxies/smart-proxy/utils/route-helpers.ts +167 -1
  112. package/ts/proxies/smart-proxy/utils/route-validators.ts +24 -5
  113. package/ts/proxies/smart-proxy/domain-config-manager.ts.bak +0 -441
  114. package/ts/proxies/smart-proxy/route-helpers/index.ts +0 -9
  115. package/ts/proxies/smart-proxy/route-helpers.ts +0 -498
@@ -0,0 +1,118 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import type { IRouteConfig, TPortRange, IRouteContext } from '../../proxies/smart-proxy/models/route-types.js';
3
+ /**
4
+ * Result of route matching
5
+ */
6
+ export interface IRouteMatchResult {
7
+ route: IRouteConfig;
8
+ params?: Record<string, string>;
9
+ }
10
+ /**
11
+ * Logger interface for RouteManager
12
+ */
13
+ export interface ILogger {
14
+ info: (message: string, ...args: any[]) => void;
15
+ warn: (message: string, ...args: any[]) => void;
16
+ error: (message: string, ...args: any[]) => void;
17
+ debug?: (message: string, ...args: any[]) => void;
18
+ }
19
+ /**
20
+ * Shared RouteManager used by both SmartProxy and NetworkProxy
21
+ *
22
+ * This provides a unified implementation for route management,
23
+ * route matching, and port handling.
24
+ */
25
+ export declare class SharedRouteManager extends plugins.EventEmitter {
26
+ private routes;
27
+ private portMap;
28
+ private logger;
29
+ private enableDetailedLogging;
30
+ /**
31
+ * Memoization cache for expanded port ranges
32
+ */
33
+ private portRangeCache;
34
+ constructor(options: {
35
+ logger?: ILogger;
36
+ enableDetailedLogging?: boolean;
37
+ routes?: IRouteConfig[];
38
+ });
39
+ /**
40
+ * Update routes with new configuration
41
+ */
42
+ updateRoutes(routes?: IRouteConfig[]): void;
43
+ /**
44
+ * Get all routes
45
+ */
46
+ getRoutes(): IRouteConfig[];
47
+ /**
48
+ * Rebuild the port mapping for fast lookups
49
+ * Also logs information about the ports being listened on
50
+ */
51
+ private rebuildPortMap;
52
+ /**
53
+ * Expand a port range specification into an array of individual ports
54
+ * Uses caching to improve performance for frequently used port ranges
55
+ *
56
+ * @public - Made public to allow external code to interpret port ranges
57
+ */
58
+ expandPortRange(portRange: TPortRange): number[];
59
+ /**
60
+ * Get all ports that should be listened on
61
+ * This method automatically infers all required ports from route configurations
62
+ */
63
+ getListeningPorts(): number[];
64
+ /**
65
+ * Get all routes for a given port
66
+ */
67
+ getRoutesForPort(port: number): IRouteConfig[];
68
+ /**
69
+ * Find the matching route for a connection
70
+ */
71
+ findMatchingRoute(context: IRouteContext): IRouteMatchResult | null;
72
+ /**
73
+ * Check if a route matches the given context
74
+ */
75
+ private matchesRoute;
76
+ /**
77
+ * Match a domain pattern against a domain
78
+ * @deprecated Use the matchDomain function from route-utils.js instead
79
+ */
80
+ matchDomain(pattern: string, domain: string): boolean;
81
+ /**
82
+ * Match a path pattern against a path
83
+ * @deprecated Use the matchPath function from route-utils.js instead
84
+ */
85
+ matchPath(pattern: string, path: string): boolean;
86
+ /**
87
+ * Match an IP pattern against a pattern
88
+ * @deprecated Use the matchIpPattern function from route-utils.js instead
89
+ */
90
+ matchIpPattern(pattern: string, ip: string): boolean;
91
+ /**
92
+ * Match an IP against a CIDR pattern
93
+ * @deprecated Use the matchIpCidr function from route-utils.js instead
94
+ */
95
+ matchIpCidr(cidr: string, ip: string): boolean;
96
+ /**
97
+ * Convert an IP address to a numeric value
98
+ * @deprecated Use the ipToNumber function from route-utils.js instead
99
+ */
100
+ private ipToNumber;
101
+ /**
102
+ * Validate the route configuration and return any warnings
103
+ */
104
+ validateConfiguration(): string[];
105
+ /**
106
+ * Check if two route matches are similar (potential conflict)
107
+ */
108
+ private areMatchesSimilar;
109
+ /**
110
+ * Check if a route is completely shadowed by a higher priority route
111
+ */
112
+ private isRouteShadowed;
113
+ /**
114
+ * Check if route1 is more specific than route2
115
+ * @deprecated Use the calculateRouteSpecificity function from route-utils.js instead
116
+ */
117
+ private isRouteMoreSpecific;
118
+ }
@@ -0,0 +1,383 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import { matchDomain, matchRouteDomain, matchPath, matchIpPattern, matchIpCidr, ipToNumber, isIpAuthorized, calculateRouteSpecificity } from './route-utils.js';
3
+ /**
4
+ * Shared RouteManager used by both SmartProxy and NetworkProxy
5
+ *
6
+ * This provides a unified implementation for route management,
7
+ * route matching, and port handling.
8
+ */
9
+ export class SharedRouteManager extends plugins.EventEmitter {
10
+ constructor(options) {
11
+ super();
12
+ this.routes = [];
13
+ this.portMap = new Map();
14
+ /**
15
+ * Memoization cache for expanded port ranges
16
+ */
17
+ this.portRangeCache = new Map();
18
+ // Set up logger (use console if not provided)
19
+ this.logger = options.logger || {
20
+ info: console.log,
21
+ warn: console.warn,
22
+ error: console.error,
23
+ debug: options.enableDetailedLogging ? console.log : undefined
24
+ };
25
+ this.enableDetailedLogging = options.enableDetailedLogging || false;
26
+ // Initialize routes if provided
27
+ if (options.routes) {
28
+ this.updateRoutes(options.routes);
29
+ }
30
+ }
31
+ /**
32
+ * Update routes with new configuration
33
+ */
34
+ updateRoutes(routes = []) {
35
+ // Sort routes by priority (higher first)
36
+ this.routes = [...(routes || [])].sort((a, b) => {
37
+ const priorityA = a.priority ?? 0;
38
+ const priorityB = b.priority ?? 0;
39
+ return priorityB - priorityA;
40
+ });
41
+ // Rebuild port mapping for fast lookups
42
+ this.rebuildPortMap();
43
+ this.logger.info(`Updated RouteManager with ${this.routes.length} routes`);
44
+ }
45
+ /**
46
+ * Get all routes
47
+ */
48
+ getRoutes() {
49
+ return [...this.routes];
50
+ }
51
+ /**
52
+ * Rebuild the port mapping for fast lookups
53
+ * Also logs information about the ports being listened on
54
+ */
55
+ rebuildPortMap() {
56
+ this.portMap.clear();
57
+ this.portRangeCache.clear(); // Clear cache when rebuilding
58
+ // Track ports for logging
59
+ const portToRoutesMap = new Map();
60
+ for (const route of this.routes) {
61
+ const ports = this.expandPortRange(route.match.ports);
62
+ // Skip if no ports were found
63
+ if (ports.length === 0) {
64
+ this.logger.warn(`Route ${route.name || 'unnamed'} has no valid ports to listen on`);
65
+ continue;
66
+ }
67
+ for (const port of ports) {
68
+ // Add to portMap for routing
69
+ if (!this.portMap.has(port)) {
70
+ this.portMap.set(port, []);
71
+ }
72
+ this.portMap.get(port).push(route);
73
+ // Add to tracking for logging
74
+ if (!portToRoutesMap.has(port)) {
75
+ portToRoutesMap.set(port, []);
76
+ }
77
+ portToRoutesMap.get(port).push(route.name || 'unnamed');
78
+ }
79
+ }
80
+ // Log summary of ports and routes
81
+ const totalPorts = this.portMap.size;
82
+ const totalRoutes = this.routes.length;
83
+ this.logger.info(`Route manager configured with ${totalRoutes} routes across ${totalPorts} ports`);
84
+ // Log port details if detailed logging is enabled
85
+ if (this.enableDetailedLogging) {
86
+ for (const [port, routes] of this.portMap.entries()) {
87
+ this.logger.info(`Port ${port}: ${routes.length} routes (${portToRoutesMap.get(port).join(', ')})`);
88
+ }
89
+ }
90
+ }
91
+ /**
92
+ * Expand a port range specification into an array of individual ports
93
+ * Uses caching to improve performance for frequently used port ranges
94
+ *
95
+ * @public - Made public to allow external code to interpret port ranges
96
+ */
97
+ expandPortRange(portRange) {
98
+ // For simple number, return immediately
99
+ if (typeof portRange === 'number') {
100
+ return [portRange];
101
+ }
102
+ // Create a cache key for this port range
103
+ const cacheKey = JSON.stringify(portRange);
104
+ // Check if we have a cached result
105
+ if (this.portRangeCache.has(cacheKey)) {
106
+ return this.portRangeCache.get(cacheKey);
107
+ }
108
+ // Process the port range
109
+ let result = [];
110
+ if (Array.isArray(portRange)) {
111
+ // Handle array of port objects or numbers
112
+ result = portRange.flatMap(item => {
113
+ if (typeof item === 'number') {
114
+ return [item];
115
+ }
116
+ else if (typeof item === 'object' && 'from' in item && 'to' in item) {
117
+ // Handle port range object - check valid range
118
+ if (item.from > item.to) {
119
+ this.logger.warn(`Invalid port range: from (${item.from}) > to (${item.to})`);
120
+ return [];
121
+ }
122
+ // Handle port range object
123
+ const ports = [];
124
+ for (let p = item.from; p <= item.to; p++) {
125
+ ports.push(p);
126
+ }
127
+ return ports;
128
+ }
129
+ return [];
130
+ });
131
+ }
132
+ // Cache the result
133
+ this.portRangeCache.set(cacheKey, result);
134
+ return result;
135
+ }
136
+ /**
137
+ * Get all ports that should be listened on
138
+ * This method automatically infers all required ports from route configurations
139
+ */
140
+ getListeningPorts() {
141
+ // Return the unique set of ports from all routes
142
+ return Array.from(this.portMap.keys());
143
+ }
144
+ /**
145
+ * Get all routes for a given port
146
+ */
147
+ getRoutesForPort(port) {
148
+ return this.portMap.get(port) || [];
149
+ }
150
+ /**
151
+ * Find the matching route for a connection
152
+ */
153
+ findMatchingRoute(context) {
154
+ // Get routes for this port if using port-based filtering
155
+ const routesToCheck = context.port
156
+ ? (this.portMap.get(context.port) || [])
157
+ : this.routes;
158
+ // Find the first matching route based on priority order
159
+ for (const route of routesToCheck) {
160
+ if (this.matchesRoute(route, context)) {
161
+ return { route };
162
+ }
163
+ }
164
+ return null;
165
+ }
166
+ /**
167
+ * Check if a route matches the given context
168
+ */
169
+ matchesRoute(route, context) {
170
+ // Skip disabled routes
171
+ if (route.enabled === false) {
172
+ return false;
173
+ }
174
+ // Check port match if provided in context
175
+ if (context.port !== undefined) {
176
+ const ports = this.expandPortRange(route.match.ports);
177
+ if (!ports.includes(context.port)) {
178
+ return false;
179
+ }
180
+ }
181
+ // Check domain match if specified
182
+ if (route.match.domains && context.domain) {
183
+ const domains = Array.isArray(route.match.domains)
184
+ ? route.match.domains
185
+ : [route.match.domains];
186
+ if (!domains.some(domainPattern => this.matchDomain(domainPattern, context.domain))) {
187
+ return false;
188
+ }
189
+ }
190
+ // Check path match if specified
191
+ if (route.match.path && context.path) {
192
+ if (!this.matchPath(route.match.path, context.path)) {
193
+ return false;
194
+ }
195
+ }
196
+ // Check client IP match if specified
197
+ if (route.match.clientIp && context.clientIp) {
198
+ if (!route.match.clientIp.some(ip => this.matchIpPattern(ip, context.clientIp))) {
199
+ return false;
200
+ }
201
+ }
202
+ // Check TLS version match if specified
203
+ if (route.match.tlsVersion && context.tlsVersion) {
204
+ if (!route.match.tlsVersion.includes(context.tlsVersion)) {
205
+ return false;
206
+ }
207
+ }
208
+ // Check header match if specified
209
+ if (route.match.headers && context.headers) {
210
+ for (const [headerName, expectedValue] of Object.entries(route.match.headers)) {
211
+ const actualValue = context.headers[headerName.toLowerCase()];
212
+ // If header doesn't exist, no match
213
+ if (actualValue === undefined) {
214
+ return false;
215
+ }
216
+ // Match against string or regex
217
+ if (typeof expectedValue === 'string') {
218
+ if (actualValue !== expectedValue) {
219
+ return false;
220
+ }
221
+ }
222
+ else if (expectedValue instanceof RegExp) {
223
+ if (!expectedValue.test(actualValue)) {
224
+ return false;
225
+ }
226
+ }
227
+ }
228
+ }
229
+ // All criteria matched
230
+ return true;
231
+ }
232
+ /**
233
+ * Match a domain pattern against a domain
234
+ * @deprecated Use the matchDomain function from route-utils.js instead
235
+ */
236
+ matchDomain(pattern, domain) {
237
+ return matchDomain(pattern, domain);
238
+ }
239
+ /**
240
+ * Match a path pattern against a path
241
+ * @deprecated Use the matchPath function from route-utils.js instead
242
+ */
243
+ matchPath(pattern, path) {
244
+ return matchPath(pattern, path);
245
+ }
246
+ /**
247
+ * Match an IP pattern against a pattern
248
+ * @deprecated Use the matchIpPattern function from route-utils.js instead
249
+ */
250
+ matchIpPattern(pattern, ip) {
251
+ return matchIpPattern(pattern, ip);
252
+ }
253
+ /**
254
+ * Match an IP against a CIDR pattern
255
+ * @deprecated Use the matchIpCidr function from route-utils.js instead
256
+ */
257
+ matchIpCidr(cidr, ip) {
258
+ return matchIpCidr(cidr, ip);
259
+ }
260
+ /**
261
+ * Convert an IP address to a numeric value
262
+ * @deprecated Use the ipToNumber function from route-utils.js instead
263
+ */
264
+ ipToNumber(ip) {
265
+ return ipToNumber(ip);
266
+ }
267
+ /**
268
+ * Validate the route configuration and return any warnings
269
+ */
270
+ validateConfiguration() {
271
+ const warnings = [];
272
+ const duplicatePorts = new Map();
273
+ // Check for routes with the same exact match criteria
274
+ for (let i = 0; i < this.routes.length; i++) {
275
+ for (let j = i + 1; j < this.routes.length; j++) {
276
+ const route1 = this.routes[i];
277
+ const route2 = this.routes[j];
278
+ // Check if route match criteria are the same
279
+ if (this.areMatchesSimilar(route1.match, route2.match)) {
280
+ warnings.push(`Routes "${route1.name || i}" and "${route2.name || j}" have similar match criteria. ` +
281
+ `The route with higher priority (${Math.max(route1.priority || 0, route2.priority || 0)}) will be used.`);
282
+ }
283
+ }
284
+ }
285
+ // Check for routes that may never be matched due to priority
286
+ for (let i = 0; i < this.routes.length; i++) {
287
+ const route = this.routes[i];
288
+ const higherPriorityRoutes = this.routes.filter(r => (r.priority || 0) > (route.priority || 0));
289
+ for (const higherRoute of higherPriorityRoutes) {
290
+ if (this.isRouteShadowed(route, higherRoute)) {
291
+ warnings.push(`Route "${route.name || i}" may never be matched because it is shadowed by ` +
292
+ `higher priority route "${higherRoute.name || 'unnamed'}"`);
293
+ break;
294
+ }
295
+ }
296
+ }
297
+ return warnings;
298
+ }
299
+ /**
300
+ * Check if two route matches are similar (potential conflict)
301
+ */
302
+ areMatchesSimilar(match1, match2) {
303
+ // Check port overlap
304
+ const ports1 = new Set(this.expandPortRange(match1.ports));
305
+ const ports2 = new Set(this.expandPortRange(match2.ports));
306
+ let havePortOverlap = false;
307
+ for (const port of ports1) {
308
+ if (ports2.has(port)) {
309
+ havePortOverlap = true;
310
+ break;
311
+ }
312
+ }
313
+ if (!havePortOverlap) {
314
+ return false;
315
+ }
316
+ // Check domain overlap
317
+ if (match1.domains && match2.domains) {
318
+ const domains1 = Array.isArray(match1.domains) ? match1.domains : [match1.domains];
319
+ const domains2 = Array.isArray(match2.domains) ? match2.domains : [match2.domains];
320
+ // Check if any domain pattern from match1 could match any from match2
321
+ let haveDomainOverlap = false;
322
+ for (const domain1 of domains1) {
323
+ for (const domain2 of domains2) {
324
+ if (domain1 === domain2 ||
325
+ (domain1.includes('*') || domain2.includes('*'))) {
326
+ haveDomainOverlap = true;
327
+ break;
328
+ }
329
+ }
330
+ if (haveDomainOverlap)
331
+ break;
332
+ }
333
+ if (!haveDomainOverlap) {
334
+ return false;
335
+ }
336
+ }
337
+ else if (match1.domains || match2.domains) {
338
+ // One has domains, the other doesn't - they could overlap
339
+ // The one with domains is more specific, so it's not exactly a conflict
340
+ return false;
341
+ }
342
+ // Check path overlap
343
+ if (match1.path && match2.path) {
344
+ // This is a simplified check - in a real implementation,
345
+ // you'd need to check if the path patterns could match the same paths
346
+ return match1.path === match2.path ||
347
+ match1.path.includes('*') ||
348
+ match2.path.includes('*');
349
+ }
350
+ else if (match1.path || match2.path) {
351
+ // One has a path, the other doesn't
352
+ return false;
353
+ }
354
+ // If we get here, the matches have significant overlap
355
+ return true;
356
+ }
357
+ /**
358
+ * Check if a route is completely shadowed by a higher priority route
359
+ */
360
+ isRouteShadowed(route, higherPriorityRoute) {
361
+ // If they don't have similar match criteria, no shadowing occurs
362
+ if (!this.areMatchesSimilar(route.match, higherPriorityRoute.match)) {
363
+ return false;
364
+ }
365
+ // If higher priority route has more specific criteria, no shadowing
366
+ const routeSpecificity = calculateRouteSpecificity(route.match);
367
+ const higherRouteSpecificity = calculateRouteSpecificity(higherPriorityRoute.match);
368
+ if (higherRouteSpecificity > routeSpecificity) {
369
+ return false;
370
+ }
371
+ // If higher priority route is equally or less specific but has higher priority,
372
+ // it shadows the lower priority route
373
+ return true;
374
+ }
375
+ /**
376
+ * Check if route1 is more specific than route2
377
+ * @deprecated Use the calculateRouteSpecificity function from route-utils.js instead
378
+ */
379
+ isRouteMoreSpecific(match1, match2) {
380
+ return calculateRouteSpecificity(match1) > calculateRouteSpecificity(match2);
381
+ }
382
+ }
383
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUtbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL2NvcmUvdXRpbHMvcm91dGUtbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBUTVDLE9BQU8sRUFDTCxXQUFXLEVBQ1gsZ0JBQWdCLEVBQ2hCLFNBQVMsRUFDVCxjQUFjLEVBQ2QsV0FBVyxFQUNYLFVBQVUsRUFDVixjQUFjLEVBQ2QseUJBQXlCLEVBQzFCLE1BQU0sa0JBQWtCLENBQUM7QUFxQjFCOzs7OztHQUtHO0FBQ0gsTUFBTSxPQUFPLGtCQUFtQixTQUFRLE9BQU8sQ0FBQyxZQUFZO0lBVzFELFlBQVksT0FJWDtRQUNDLEtBQUssRUFBRSxDQUFDO1FBZkYsV0FBTSxHQUFtQixFQUFFLENBQUM7UUFDNUIsWUFBTyxHQUFnQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBSXpEOztXQUVHO1FBQ0ssbUJBQWMsR0FBMEIsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQVN4RCw4Q0FBOEM7UUFDOUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJO1lBQzlCLElBQUksRUFBRSxPQUFPLENBQUMsR0FBRztZQUNqQixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7WUFDbEIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLO1lBQ3BCLEtBQUssRUFBRSxPQUFPLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLFNBQVM7U0FDL0QsQ0FBQztRQUVGLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxPQUFPLENBQUMscUJBQXFCLElBQUksS0FBSyxDQUFDO1FBRXBFLGdDQUFnQztRQUNoQyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztR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
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Route matching utilities for SmartProxy components
3
+ *
4
+ * Contains shared logic for domain matching, path matching, and IP matching
5
+ * to be used by different proxy components throughout the system.
6
+ */
7
+ /**
8
+ * Match a domain pattern against a domain
9
+ *
10
+ * @param pattern Domain pattern with optional wildcards (e.g., "*.example.com")
11
+ * @param domain Domain to match against the pattern
12
+ * @returns Whether the domain matches the pattern
13
+ */
14
+ export declare function matchDomain(pattern: string, domain: string): boolean;
15
+ /**
16
+ * Match domains from a route against a given domain
17
+ *
18
+ * @param domains Array or single domain pattern to match against
19
+ * @param domain Domain to match
20
+ * @returns Whether the domain matches any of the patterns
21
+ */
22
+ export declare function matchRouteDomain(domains: string | string[] | undefined, domain: string | undefined): boolean;
23
+ /**
24
+ * Match a path pattern against a path
25
+ *
26
+ * @param pattern Path pattern with optional wildcards
27
+ * @param path Path to match against the pattern
28
+ * @returns Whether the path matches the pattern
29
+ */
30
+ export declare function matchPath(pattern: string, path: string): boolean;
31
+ /**
32
+ * Parse CIDR notation into subnet and mask bits
33
+ *
34
+ * @param cidr CIDR string (e.g., "192.168.1.0/24")
35
+ * @returns Object with subnet and bits, or null if invalid
36
+ */
37
+ export declare function parseCidr(cidr: string): {
38
+ subnet: string;
39
+ bits: number;
40
+ } | null;
41
+ /**
42
+ * Convert an IP address to a numeric value
43
+ *
44
+ * @param ip IPv4 address string (e.g., "192.168.1.1")
45
+ * @returns Numeric representation of the IP
46
+ */
47
+ export declare function ipToNumber(ip: string): number;
48
+ /**
49
+ * Match an IP against a CIDR pattern
50
+ *
51
+ * @param cidr CIDR pattern (e.g., "192.168.1.0/24")
52
+ * @param ip IP to match against the pattern
53
+ * @returns Whether the IP is in the CIDR range
54
+ */
55
+ export declare function matchIpCidr(cidr: string, ip: string): boolean;
56
+ /**
57
+ * Match an IP pattern against an IP
58
+ *
59
+ * @param pattern IP pattern (exact, CIDR, or with wildcards)
60
+ * @param ip IP to match against the pattern
61
+ * @returns Whether the IP matches the pattern
62
+ */
63
+ export declare function matchIpPattern(pattern: string, ip: string): boolean;
64
+ /**
65
+ * Match an IP against allowed and blocked IP patterns
66
+ *
67
+ * @param ip IP to check
68
+ * @param allowedIps Array of allowed IP patterns
69
+ * @param blockedIps Array of blocked IP patterns
70
+ * @returns Whether the IP is allowed
71
+ */
72
+ export declare function isIpAuthorized(ip: string, allowedIps?: string[], blockedIps?: string[]): boolean;
73
+ /**
74
+ * Match an HTTP header pattern against a header value
75
+ *
76
+ * @param pattern Expected header value (string or RegExp)
77
+ * @param value Actual header value
78
+ * @returns Whether the header matches the pattern
79
+ */
80
+ export declare function matchHeader(pattern: string | RegExp, value: string): boolean;
81
+ /**
82
+ * Calculate route specificity score
83
+ * Higher score means more specific matching criteria
84
+ *
85
+ * @param match Match criteria to evaluate
86
+ * @returns Numeric specificity score
87
+ */
88
+ export declare function calculateRouteSpecificity(match: {
89
+ domains?: string | string[];
90
+ path?: string;
91
+ clientIp?: string[];
92
+ tlsVersion?: string[];
93
+ headers?: Record<string, string | RegExp>;
94
+ }): number;