@push.rocks/smartproxy 13.1.3 → 15.0.1

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 (32) hide show
  1. package/dist_ts/00_commitinfo_data.js +3 -3
  2. package/dist_ts/proxies/smart-proxy/domain-config-manager.d.ts +15 -0
  3. package/dist_ts/proxies/smart-proxy/domain-config-manager.js +140 -9
  4. package/dist_ts/proxies/smart-proxy/index.d.ts +5 -3
  5. package/dist_ts/proxies/smart-proxy/index.js +9 -5
  6. package/dist_ts/proxies/smart-proxy/models/index.d.ts +2 -0
  7. package/dist_ts/proxies/smart-proxy/models/index.js +2 -1
  8. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +82 -15
  9. package/dist_ts/proxies/smart-proxy/models/interfaces.js +11 -1
  10. package/dist_ts/proxies/smart-proxy/models/route-types.d.ts +133 -0
  11. package/dist_ts/proxies/smart-proxy/models/route-types.js +2 -0
  12. package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +55 -0
  13. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +804 -0
  14. package/dist_ts/proxies/smart-proxy/route-helpers.d.ts +127 -0
  15. package/dist_ts/proxies/smart-proxy/route-helpers.js +196 -0
  16. package/dist_ts/proxies/smart-proxy/route-manager.d.ts +103 -0
  17. package/dist_ts/proxies/smart-proxy/route-manager.js +483 -0
  18. package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +19 -8
  19. package/dist_ts/proxies/smart-proxy/smart-proxy.js +250 -46
  20. package/package.json +2 -2
  21. package/readme.md +675 -446
  22. package/readme.plan.md +311 -250
  23. package/ts/00_commitinfo_data.ts +2 -2
  24. package/ts/proxies/smart-proxy/domain-config-manager.ts +157 -14
  25. package/ts/proxies/smart-proxy/index.ts +20 -4
  26. package/ts/proxies/smart-proxy/models/index.ts +4 -0
  27. package/ts/proxies/smart-proxy/models/interfaces.ts +92 -13
  28. package/ts/proxies/smart-proxy/models/route-types.ts +184 -0
  29. package/ts/proxies/smart-proxy/route-connection-handler.ts +1117 -0
  30. package/ts/proxies/smart-proxy/route-helpers.ts +344 -0
  31. package/ts/proxies/smart-proxy/route-manager.ts +587 -0
  32. package/ts/proxies/smart-proxy/smart-proxy.ts +312 -69
@@ -3,6 +3,8 @@ import type { IDomainConfig, ISmartProxyOptions } from './models/interfaces.js';
3
3
  import type { TForwardingType, IForwardConfig } from '../../forwarding/config/forwarding-types.js';
4
4
  import type { ForwardingHandler } from '../../forwarding/handlers/base-handler.js';
5
5
  import { ForwardingHandlerFactory } from '../../forwarding/factory/forwarding-factory.js';
6
+ import type { IRouteConfig } from './models/route-types.js';
7
+ import { RouteManager } from './route-manager.js';
6
8
 
7
9
  /**
8
10
  * Manages domain configurations and target selection
@@ -14,13 +16,112 @@ export class DomainConfigManager {
14
16
  // Cache forwarding handlers for each domain config
15
17
  private forwardingHandlers: Map<IDomainConfig, ForwardingHandler> = new Map();
16
18
 
17
- constructor(private settings: ISmartProxyOptions) {}
18
-
19
+ // Store derived domain configs from routes
20
+ private derivedDomainConfigs: IDomainConfig[] = [];
21
+
22
+ // Reference to RouteManager for route-based configuration
23
+ private routeManager?: RouteManager;
24
+
25
+ constructor(private settings: ISmartProxyOptions) {
26
+ // Initialize with derived domain configs if using route-based configuration
27
+ if (settings.routes && !settings.domainConfigs) {
28
+ this.generateDomainConfigsFromRoutes();
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Set the route manager reference for route-based queries
34
+ */
35
+ public setRouteManager(routeManager: RouteManager): void {
36
+ this.routeManager = routeManager;
37
+
38
+ // Regenerate domain configs from routes if needed
39
+ if (this.settings.routes && (!this.settings.domainConfigs || this.settings.domainConfigs.length === 0)) {
40
+ this.generateDomainConfigsFromRoutes();
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Generate domain configs from routes
46
+ */
47
+ public generateDomainConfigsFromRoutes(): void {
48
+ this.derivedDomainConfigs = [];
49
+
50
+ if (!this.settings.routes) return;
51
+
52
+ for (const route of this.settings.routes) {
53
+ if (route.action.type !== 'forward' || !route.match.domains) continue;
54
+
55
+ // Convert route to domain config
56
+ const domainConfig = this.routeToDomainConfig(route);
57
+ if (domainConfig) {
58
+ this.derivedDomainConfigs.push(domainConfig);
59
+ }
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Convert a route to a domain config
65
+ */
66
+ private routeToDomainConfig(route: IRouteConfig): IDomainConfig | null {
67
+ if (route.action.type !== 'forward' || !route.action.target) return null;
68
+
69
+ // Get domains from route
70
+ const domains = Array.isArray(route.match.domains) ?
71
+ route.match.domains :
72
+ (route.match.domains ? [route.match.domains] : []);
73
+
74
+ if (domains.length === 0) return null;
75
+
76
+ // Determine forwarding type based on TLS mode
77
+ let forwardingType: TForwardingType = 'http-only';
78
+ if (route.action.tls) {
79
+ switch (route.action.tls.mode) {
80
+ case 'passthrough':
81
+ forwardingType = 'https-passthrough';
82
+ break;
83
+ case 'terminate':
84
+ forwardingType = 'https-terminate-to-http';
85
+ break;
86
+ case 'terminate-and-reencrypt':
87
+ forwardingType = 'https-terminate-to-https';
88
+ break;
89
+ }
90
+ }
91
+
92
+ // Create domain config
93
+ return {
94
+ domains,
95
+ forwarding: {
96
+ type: forwardingType,
97
+ target: {
98
+ host: route.action.target.host,
99
+ port: route.action.target.port
100
+ },
101
+ security: route.action.security ? {
102
+ allowedIps: route.action.security.allowedIps,
103
+ blockedIps: route.action.security.blockedIps,
104
+ maxConnections: route.action.security.maxConnections
105
+ } : undefined,
106
+ https: route.action.tls && route.action.tls.certificate !== 'auto' ? {
107
+ customCert: route.action.tls.certificate
108
+ } : undefined,
109
+ advanced: route.action.advanced
110
+ }
111
+ };
112
+ }
113
+
19
114
  /**
20
115
  * Updates the domain configurations
21
116
  */
22
117
  public updateDomainConfigs(newDomainConfigs: IDomainConfig[]): void {
23
- this.settings.domainConfigs = newDomainConfigs;
118
+ // If we're using domainConfigs property, update it
119
+ if (this.settings.domainConfigs) {
120
+ this.settings.domainConfigs = newDomainConfigs;
121
+ } else {
122
+ // Otherwise update our derived configs
123
+ this.derivedDomainConfigs = newDomainConfigs;
124
+ }
24
125
 
25
126
  // Reset target indices for removed configs
26
127
  const currentConfigSet = new Set(newDomainConfigs);
@@ -60,7 +161,8 @@ export class DomainConfigManager {
60
161
  * Get all domain configurations
61
162
  */
62
163
  public getDomainConfigs(): IDomainConfig[] {
63
- return this.settings.domainConfigs;
164
+ // Use domainConfigs from settings if available, otherwise use derived configs
165
+ return this.settings.domainConfigs || this.derivedDomainConfigs;
64
166
  }
65
167
 
66
168
  /**
@@ -69,23 +171,64 @@ export class DomainConfigManager {
69
171
  public findDomainConfig(serverName: string): IDomainConfig | undefined {
70
172
  if (!serverName) return undefined;
71
173
 
72
- return this.settings.domainConfigs.find((config) =>
73
- config.domains.some((d) => plugins.minimatch(serverName, d))
74
- );
174
+ // Get domain configs from the appropriate source
175
+ const domainConfigs = this.getDomainConfigs();
176
+
177
+ // Check for direct match
178
+ for (const config of domainConfigs) {
179
+ if (config.domains.some(d => plugins.minimatch(serverName, d))) {
180
+ return config;
181
+ }
182
+ }
183
+
184
+ // No match found
185
+ return undefined;
75
186
  }
76
187
 
77
188
  /**
78
189
  * Find domain config for a specific port
79
190
  */
80
191
  public findDomainConfigForPort(port: number): IDomainConfig | undefined {
81
- return this.settings.domainConfigs.find(
82
- (domain) => {
83
- const portRanges = domain.forwarding?.advanced?.portRanges;
84
- return portRanges &&
85
- portRanges.length > 0 &&
86
- this.isPortInRanges(port, portRanges);
192
+ // Get domain configs from the appropriate source
193
+ const domainConfigs = this.getDomainConfigs();
194
+
195
+ // Check if any domain config has a matching port range
196
+ for (const domain of domainConfigs) {
197
+ const portRanges = domain.forwarding?.advanced?.portRanges;
198
+ if (portRanges && portRanges.length > 0 && this.isPortInRanges(port, portRanges)) {
199
+ return domain;
87
200
  }
88
- );
201
+ }
202
+
203
+ // If we're in route-based mode, also check routes for this port
204
+ if (this.settings.routes && (!this.settings.domainConfigs || this.settings.domainConfigs.length === 0)) {
205
+ const routesForPort = this.settings.routes.filter(route => {
206
+ // Check if this port is in the route's ports
207
+ if (typeof route.match.ports === 'number') {
208
+ return route.match.ports === port;
209
+ } else if (Array.isArray(route.match.ports)) {
210
+ return route.match.ports.some(p => {
211
+ if (typeof p === 'number') {
212
+ return p === port;
213
+ } else if (p.from && p.to) {
214
+ return port >= p.from && port <= p.to;
215
+ }
216
+ return false;
217
+ });
218
+ }
219
+ return false;
220
+ });
221
+
222
+ // If we found any routes for this port, convert the first one to a domain config
223
+ if (routesForPort.length > 0 && routesForPort[0].action.type === 'forward') {
224
+ const domainConfig = this.routeToDomainConfig(routesForPort[0]);
225
+ if (domainConfig) {
226
+ return domainConfig;
227
+ }
228
+ }
229
+ }
230
+
231
+ return undefined;
89
232
  }
90
233
 
91
234
  /**
@@ -1,5 +1,7 @@
1
1
  /**
2
2
  * SmartProxy implementation
3
+ *
4
+ * Version 14.0.0: Unified Route-Based Configuration API
3
5
  */
4
6
  // Re-export models
5
7
  export * from './models/index.js';
@@ -7,12 +9,26 @@ export * from './models/index.js';
7
9
  // Export the main SmartProxy class
8
10
  export { SmartProxy } from './smart-proxy.js';
9
11
 
10
- // Export supporting classes
12
+ // Export core supporting classes
11
13
  export { ConnectionManager } from './connection-manager.js';
12
14
  export { SecurityManager } from './security-manager.js';
13
- export { DomainConfigManager } from './domain-config-manager.js';
14
15
  export { TimeoutManager } from './timeout-manager.js';
15
16
  export { TlsManager } from './tls-manager.js';
16
17
  export { NetworkProxyBridge } from './network-proxy-bridge.js';
17
- export { PortRangeManager } from './port-range-manager.js';
18
- export { ConnectionHandler } from './connection-handler.js';
18
+
19
+ // Export route-based components
20
+ export { RouteManager } from './route-manager.js';
21
+ export { RouteConnectionHandler } from './route-connection-handler.js';
22
+
23
+ // Export route helpers for configuration
24
+ export {
25
+ createRoute,
26
+ createHttpRoute,
27
+ createHttpsRoute,
28
+ createPassthroughRoute,
29
+ createRedirectRoute,
30
+ createHttpToHttpsRedirect,
31
+ createBlockRoute,
32
+ createLoadBalancerRoute,
33
+ createHttpsServer
34
+ } from './route-helpers.js';
@@ -2,3 +2,7 @@
2
2
  * SmartProxy models
3
3
  */
4
4
  export * from './interfaces.js';
5
+ export * from './route-types.js';
6
+
7
+ // Re-export IRoutedSmartProxyOptions explicitly to avoid ambiguity
8
+ export type { ISmartProxyOptions as IRoutedSmartProxyOptions } from './interfaces.js';
@@ -1,5 +1,7 @@
1
1
  import * as plugins from '../../../plugins.js';
2
- import type { IForwardConfig } from '../../../forwarding/config/forwarding-types.js';
2
+ import type { IAcmeOptions } from '../../../certificate/models/certificate-types.js';
3
+ import type { IRouteConfig } from './route-types.js';
4
+ import type { TForwardingType } from '../../../forwarding/config/forwarding-types.js';
3
5
 
4
6
  /**
5
7
  * Provision object for static or HTTP-01 certificate
@@ -7,27 +9,103 @@ import type { IForwardConfig } from '../../../forwarding/config/forwarding-types
7
9
  export type TSmartProxyCertProvisionObject = plugins.tsclass.network.ICert | 'http01';
8
10
 
9
11
  /**
10
- * Domain configuration with forwarding configuration
12
+ * Alias for backward compatibility with code that uses IRoutedSmartProxyOptions
13
+ */
14
+ export type IRoutedSmartProxyOptions = ISmartProxyOptions;
15
+
16
+ /**
17
+ * Legacy domain configuration interface for backward compatibility
11
18
  */
12
19
  export interface IDomainConfig {
13
- domains: string[]; // Glob patterns for domain(s)
14
- forwarding: IForwardConfig; // Unified forwarding configuration
20
+ domains: string[];
21
+ forwarding: {
22
+ type: TForwardingType;
23
+ target: {
24
+ host: string | string[];
25
+ port: number;
26
+ };
27
+ acme?: {
28
+ enabled?: boolean;
29
+ maintenance?: boolean;
30
+ production?: boolean;
31
+ forwardChallenges?: {
32
+ host: string;
33
+ port: number;
34
+ useTls?: boolean;
35
+ };
36
+ };
37
+ http?: {
38
+ enabled?: boolean;
39
+ redirectToHttps?: boolean;
40
+ headers?: Record<string, string>;
41
+ };
42
+ https?: {
43
+ customCert?: {
44
+ key: string;
45
+ cert: string;
46
+ };
47
+ forwardSni?: boolean;
48
+ };
49
+ security?: {
50
+ allowedIps?: string[];
51
+ blockedIps?: string[];
52
+ maxConnections?: number;
53
+ };
54
+ advanced?: {
55
+ portRanges?: Array<{ from: number; to: number }>;
56
+ networkProxyPort?: number;
57
+ keepAlive?: boolean;
58
+ timeout?: number;
59
+ headers?: Record<string, string>;
60
+ };
61
+ };
15
62
  }
16
63
 
17
64
  /**
18
- * Configuration options for the SmartProxy
65
+ * Helper functions for type checking configuration types
66
+ */
67
+ export function isLegacyOptions(options: any): boolean {
68
+ return !!(options.domainConfigs && options.domainConfigs.length > 0 &&
69
+ (!options.routes || options.routes.length === 0));
70
+ }
71
+
72
+ export function isRoutedOptions(options: any): boolean {
73
+ return !!(options.routes && options.routes.length > 0);
74
+ }
75
+
76
+ /**
77
+ * SmartProxy configuration options
19
78
  */
20
- import type { IAcmeOptions } from '../../../certificate/models/certificate-types.js';
21
79
  export interface ISmartProxyOptions {
22
- fromPort: number;
23
- toPort: number;
24
- targetIP?: string; // Global target host to proxy to, defaults to 'localhost'
25
- domainConfigs: IDomainConfig[];
80
+ // The unified configuration array (required)
81
+ routes: IRouteConfig[];
82
+
83
+ // Legacy options for backward compatibility
84
+ fromPort?: number;
85
+ toPort?: number;
26
86
  sniEnabled?: boolean;
87
+ domainConfigs?: IDomainConfig[];
88
+ targetIP?: string;
27
89
  defaultAllowedIPs?: string[];
28
90
  defaultBlockedIPs?: string[];
91
+ globalPortRanges?: Array<{ from: number; to: number }>;
92
+ forwardAllGlobalRanges?: boolean;
29
93
  preserveSourceIP?: boolean;
30
94
 
95
+ // Global/default settings
96
+ defaults?: {
97
+ target?: {
98
+ host: string; // Default host to use when not specified in routes
99
+ port: number; // Default port to use when not specified in routes
100
+ };
101
+ security?: {
102
+ allowedIPs?: string[]; // Default allowed IPs
103
+ blockedIPs?: string[]; // Default blocked IPs
104
+ maxConnections?: number; // Default max connections
105
+ };
106
+ preserveSourceIP?: boolean; // Default source IP preservation
107
+ };
108
+
31
109
  // TLS options
32
110
  pfx?: Buffer;
33
111
  key?: string | Buffer | Array<Buffer | string>;
@@ -50,8 +128,6 @@ export interface ISmartProxyOptions {
50
128
  inactivityTimeout?: number; // Inactivity timeout (ms), default: 14400000 (4h)
51
129
 
52
130
  gracefulShutdownTimeout?: number; // (ms) maximum time to wait for connections to close during shutdown
53
- globalPortRanges: Array<{ from: number; to: number }>; // Global allowed port ranges
54
- forwardAllGlobalRanges?: boolean; // When true, forwards all connections on global port ranges to the global targetIP
55
131
 
56
132
  // Socket optimization settings
57
133
  noDelay?: boolean; // Disable Nagle's algorithm (default: true)
@@ -108,6 +184,9 @@ export interface IConnectionRecord {
108
184
  pendingData: Buffer[]; // Buffer to hold data during connection setup
109
185
  pendingDataSize: number; // Track total size of pending data
110
186
 
187
+ // Legacy property for backward compatibility
188
+ domainConfig?: IDomainConfig;
189
+
111
190
  // Enhanced tracking fields
112
191
  bytesReceived: number; // Total bytes received
113
192
  bytesSent: number; // Total bytes sent
@@ -116,7 +195,7 @@ export interface IConnectionRecord {
116
195
  isTLS: boolean; // Whether this connection is a TLS connection
117
196
  tlsHandshakeComplete: boolean; // Whether the TLS handshake is complete
118
197
  hasReceivedInitialData: boolean; // Whether initial data has been received
119
- domainConfig?: IDomainConfig; // Associated domain config for this connection
198
+ routeConfig?: IRouteConfig; // Associated route config for this connection
120
199
 
121
200
  // Keep-alive tracking
122
201
  hasKeepAlive: boolean; // Whether keep-alive is enabled for this connection
@@ -0,0 +1,184 @@
1
+ import * as plugins from '../../../plugins.js';
2
+ import type { IAcmeOptions } from '../../../certificate/models/certificate-types.js';
3
+ import type { TForwardingType } from '../../../forwarding/config/forwarding-types.js';
4
+
5
+ /**
6
+ * Supported action types for route configurations
7
+ */
8
+ export type TRouteActionType = 'forward' | 'redirect' | 'block';
9
+
10
+ /**
11
+ * TLS handling modes for route configurations
12
+ */
13
+ export type TTlsMode = 'passthrough' | 'terminate' | 'terminate-and-reencrypt';
14
+
15
+ /**
16
+ * Port range specification format
17
+ */
18
+ export type TPortRange = number | number[] | Array<{ from: number; to: number }>;
19
+
20
+ /**
21
+ * Route match criteria for incoming requests
22
+ */
23
+ export interface IRouteMatch {
24
+ // Listen on these ports (required)
25
+ ports: TPortRange;
26
+
27
+ // Optional domain patterns to match (default: all domains)
28
+ domains?: string | string[];
29
+
30
+ // Advanced matching criteria
31
+ path?: string; // Match specific paths
32
+ clientIp?: string[]; // Match specific client IPs
33
+ tlsVersion?: string[]; // Match specific TLS versions
34
+ }
35
+
36
+ /**
37
+ * Target configuration for forwarding
38
+ */
39
+ export interface IRouteTarget {
40
+ host: string | string[]; // Support single host or round-robin
41
+ port: number;
42
+ preservePort?: boolean; // Use incoming port as target port
43
+ }
44
+
45
+ /**
46
+ * TLS configuration for route actions
47
+ */
48
+ export interface IRouteTls {
49
+ mode: TTlsMode;
50
+ certificate?: 'auto' | { // Auto = use ACME
51
+ key: string;
52
+ cert: string;
53
+ };
54
+ }
55
+
56
+ /**
57
+ * Redirect configuration for route actions
58
+ */
59
+ export interface IRouteRedirect {
60
+ to: string; // URL or template with {domain}, {port}, etc.
61
+ status: 301 | 302 | 307 | 308;
62
+ }
63
+
64
+ /**
65
+ * Security options for route actions
66
+ */
67
+ export interface IRouteSecurity {
68
+ allowedIps?: string[];
69
+ blockedIps?: string[];
70
+ maxConnections?: number;
71
+ authentication?: {
72
+ type: 'basic' | 'digest' | 'oauth';
73
+ // Auth-specific options would go here
74
+ };
75
+ }
76
+
77
+ /**
78
+ * Advanced options for route actions
79
+ */
80
+ export interface IRouteAdvanced {
81
+ timeout?: number;
82
+ headers?: Record<string, string>;
83
+ keepAlive?: boolean;
84
+ // Additional advanced options would go here
85
+ }
86
+
87
+ /**
88
+ * Action configuration for route handling
89
+ */
90
+ export interface IRouteAction {
91
+ // Basic routing
92
+ type: TRouteActionType;
93
+
94
+ // Target for forwarding
95
+ target?: IRouteTarget;
96
+
97
+ // TLS handling
98
+ tls?: IRouteTls;
99
+
100
+ // For redirects
101
+ redirect?: IRouteRedirect;
102
+
103
+ // Security options
104
+ security?: IRouteSecurity;
105
+
106
+ // Advanced options
107
+ advanced?: IRouteAdvanced;
108
+ }
109
+
110
+ /**
111
+ * The core unified configuration interface
112
+ */
113
+ export interface IRouteConfig {
114
+ // What to match
115
+ match: IRouteMatch;
116
+
117
+ // What to do with matched traffic
118
+ action: IRouteAction;
119
+
120
+ // Optional metadata
121
+ name?: string; // Human-readable name for this route
122
+ description?: string; // Description of the route's purpose
123
+ priority?: number; // Controls matching order (higher = matched first)
124
+ tags?: string[]; // Arbitrary tags for categorization
125
+ }
126
+
127
+ /**
128
+ * Unified SmartProxy options with routes-based configuration
129
+ */
130
+ export interface IRoutedSmartProxyOptions {
131
+ // The unified configuration array (required)
132
+ routes: IRouteConfig[];
133
+
134
+ // Global/default settings
135
+ defaults?: {
136
+ target?: {
137
+ host: string;
138
+ port: number;
139
+ };
140
+ security?: IRouteSecurity;
141
+ tls?: IRouteTls;
142
+ // ...other defaults
143
+ };
144
+
145
+ // Other global settings remain (acme, etc.)
146
+ acme?: IAcmeOptions;
147
+
148
+ // Connection timeouts and other global settings
149
+ initialDataTimeout?: number;
150
+ socketTimeout?: number;
151
+ inactivityCheckInterval?: number;
152
+ maxConnectionLifetime?: number;
153
+ inactivityTimeout?: number;
154
+ gracefulShutdownTimeout?: number;
155
+
156
+ // Socket optimization settings
157
+ noDelay?: boolean;
158
+ keepAlive?: boolean;
159
+ keepAliveInitialDelay?: number;
160
+ maxPendingDataSize?: number;
161
+
162
+ // Enhanced features
163
+ disableInactivityCheck?: boolean;
164
+ enableKeepAliveProbes?: boolean;
165
+ enableDetailedLogging?: boolean;
166
+ enableTlsDebugLogging?: boolean;
167
+ enableRandomizedTimeouts?: boolean;
168
+ allowSessionTicket?: boolean;
169
+
170
+ // Rate limiting and security
171
+ maxConnectionsPerIP?: number;
172
+ connectionRateLimitPerMinute?: number;
173
+
174
+ // Enhanced keep-alive settings
175
+ keepAliveTreatment?: 'standard' | 'extended' | 'immortal';
176
+ keepAliveInactivityMultiplier?: number;
177
+ extendedKeepAliveLifetime?: number;
178
+
179
+ /**
180
+ * Optional certificate provider callback. Return 'http01' to use HTTP-01 challenges,
181
+ * or a static certificate object for immediate provisioning.
182
+ */
183
+ certProvisionFunction?: (domain: string) => Promise<any>;
184
+ }