@push.rocks/smartproxy 7.1.2 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist_ts/00_commitinfo_data.js +2 -2
  2. package/dist_ts/classes.router.d.ts +9 -10
  3. package/dist_ts/classes.router.js +3 -5
  4. package/dist_ts/common/acmeFactory.d.ts +9 -0
  5. package/dist_ts/common/acmeFactory.js +20 -0
  6. package/dist_ts/common/eventUtils.d.ts +15 -0
  7. package/dist_ts/common/eventUtils.js +19 -0
  8. package/dist_ts/common/types.d.ts +82 -0
  9. package/dist_ts/common/types.js +17 -0
  10. package/dist_ts/networkproxy/classes.np.certificatemanager.js +23 -19
  11. package/dist_ts/networkproxy/classes.np.networkproxy.d.ts +1 -0
  12. package/dist_ts/networkproxy/classes.np.networkproxy.js +5 -1
  13. package/dist_ts/networkproxy/classes.np.types.d.ts +5 -10
  14. package/dist_ts/networkproxy/classes.np.types.js +1 -1
  15. package/dist_ts/plugins.d.ts +6 -3
  16. package/dist_ts/plugins.js +7 -4
  17. package/dist_ts/port80handler/classes.port80handler.d.ts +14 -111
  18. package/dist_ts/port80handler/classes.port80handler.js +94 -373
  19. package/dist_ts/smartproxy/classes.pp.certprovisioner.d.ts +54 -0
  20. package/dist_ts/smartproxy/classes.pp.certprovisioner.js +166 -0
  21. package/dist_ts/smartproxy/classes.pp.interfaces.d.ts +11 -33
  22. package/dist_ts/smartproxy/classes.pp.networkproxybridge.d.ts +5 -0
  23. package/dist_ts/smartproxy/classes.pp.networkproxybridge.js +21 -11
  24. package/dist_ts/smartproxy/classes.pp.portrangemanager.js +1 -11
  25. package/dist_ts/smartproxy/classes.smartproxy.d.ts +3 -5
  26. package/dist_ts/smartproxy/classes.smartproxy.js +94 -180
  27. package/package.json +12 -10
  28. package/readme.hints.md +64 -1
  29. package/readme.md +253 -408
  30. package/readme.plan.md +29 -0
  31. package/ts/00_commitinfo_data.ts +1 -1
  32. package/ts/classes.router.ts +13 -15
  33. package/ts/common/acmeFactory.ts +23 -0
  34. package/ts/common/eventUtils.ts +34 -0
  35. package/ts/common/types.ts +89 -0
  36. package/ts/networkproxy/classes.np.certificatemanager.ts +23 -19
  37. package/ts/networkproxy/classes.np.networkproxy.ts +4 -0
  38. package/ts/networkproxy/classes.np.types.ts +6 -10
  39. package/ts/plugins.ts +17 -4
  40. package/ts/port80handler/classes.port80handler.ts +108 -509
  41. package/ts/smartproxy/classes.pp.certprovisioner.ts +188 -0
  42. package/ts/smartproxy/classes.pp.interfaces.ts +13 -36
  43. package/ts/smartproxy/classes.pp.networkproxybridge.ts +22 -10
  44. package/ts/smartproxy/classes.pp.portrangemanager.ts +0 -10
  45. package/ts/smartproxy/classes.smartproxy.ts +103 -195
package/readme.plan.md ADDED
@@ -0,0 +1,29 @@
1
+ # Project Simplification Plan
2
+
3
+ This document outlines a roadmap to simplify and refactor the SmartProxy & NetworkProxy codebase for better maintainability, reduced duplication, and clearer configuration.
4
+
5
+ ## Goals
6
+ - Eliminate duplicate code and shared types
7
+ - Unify certificate management flow across components
8
+ - Simplify configuration schemas and option handling
9
+ - Centralize plugin imports and module interfaces
10
+ - Strengthen type safety and linting
11
+ - Improve test coverage and CI integration
12
+
13
+ ## Plan
14
+ - [x] Extract all shared interfaces and types (e.g., certificate, proxy, domain configs) into a common `ts/common` module
15
+ - [x] Consolidate ACME/Port80Handler logic:
16
+ - [x] Merge standalone Port80Handler into a single certificate service
17
+ - [x] Remove duplicate ACME setup in SmartProxy and NetworkProxy
18
+ - [x] Unify configuration options:
19
+ - [x] Merge `INetworkProxyOptions.acme`, `IPort80HandlerOptions`, and `port80HandlerConfig` into one schema
20
+ - [x] Deprecate old option names and provide clear upgrade path
21
+ - [ ] Centralize plugin imports in `ts/plugins.ts` and update all modules to use it
22
+ - [x] Remove legacy or unused code paths (e.g., old HTTP/2 fallback logic if obsolete)
23
+ - [ ] Enhance and expand test coverage:
24
+ - Add unit tests for certificate issuance, renewal, and error handling
25
+ - Add integration tests for HTTP challenge routing and request forwarding
26
+ - [ ] Update main README.md with architecture overview and configuration guide
27
+ - [ ] Review and prune external dependencies no longer needed
28
+
29
+ Once these steps are complete, the project will be cleaner, easier to understand, and simpler to extend.
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartproxy',
6
- version: '7.1.2',
6
+ version: '10.0.0',
7
7
  description: 'A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, dynamic routing with authentication options, and automatic ACME certificate management.'
8
8
  }
@@ -1,6 +1,4 @@
1
- import * as http from 'http';
2
- import * as url from 'url';
3
- import * as tsclass from '@tsclass/tsclass';
1
+ import * as plugins from './plugins.js';
4
2
 
5
3
  /**
6
4
  * Optional path pattern configuration that can be added to proxy configs
@@ -13,7 +11,7 @@ export interface IPathPatternConfig {
13
11
  * Interface for router result with additional metadata
14
12
  */
15
13
  export interface IRouterResult {
16
- config: tsclass.network.IReverseProxyConfig;
14
+ config: plugins.tsclass.network.IReverseProxyConfig;
17
15
  pathMatch?: string;
18
16
  pathParams?: Record<string, string>;
19
17
  pathRemainder?: string;
@@ -36,11 +34,11 @@ export interface IRouterResult {
36
34
  */
37
35
  export class ProxyRouter {
38
36
  // Store original configs for reference
39
- private reverseProxyConfigs: tsclass.network.IReverseProxyConfig[] = [];
37
+ private reverseProxyConfigs: plugins.tsclass.network.IReverseProxyConfig[] = [];
40
38
  // Default config to use when no match is found (optional)
41
- private defaultConfig?: tsclass.network.IReverseProxyConfig;
39
+ private defaultConfig?: plugins.tsclass.network.IReverseProxyConfig;
42
40
  // Store path patterns separately since they're not in the original interface
43
- private pathPatterns: Map<tsclass.network.IReverseProxyConfig, string> = new Map();
41
+ private pathPatterns: Map<plugins.tsclass.network.IReverseProxyConfig, string> = new Map();
44
42
  // Logger interface
45
43
  private logger: {
46
44
  error: (message: string, data?: any) => void;
@@ -50,7 +48,7 @@ export class ProxyRouter {
50
48
  };
51
49
 
52
50
  constructor(
53
- configs?: tsclass.network.IReverseProxyConfig[],
51
+ configs?: plugins.tsclass.network.IReverseProxyConfig[],
54
52
  logger?: {
55
53
  error: (message: string, data?: any) => void;
56
54
  warn: (message: string, data?: any) => void;
@@ -68,7 +66,7 @@ export class ProxyRouter {
68
66
  * Sets a new set of reverse configs to be routed to
69
67
  * @param reverseCandidatesArg Array of reverse proxy configurations
70
68
  */
71
- public setNewProxyConfigs(reverseCandidatesArg: tsclass.network.IReverseProxyConfig[]): void {
69
+ public setNewProxyConfigs(reverseCandidatesArg: plugins.tsclass.network.IReverseProxyConfig[]): void {
72
70
  this.reverseProxyConfigs = [...reverseCandidatesArg];
73
71
 
74
72
  // Find default config if any (config with "*" as hostname)
@@ -82,7 +80,7 @@ export class ProxyRouter {
82
80
  * @param req The incoming HTTP request
83
81
  * @returns The matching proxy config or undefined if no match found
84
82
  */
85
- public routeReq(req: http.IncomingMessage): tsclass.network.IReverseProxyConfig {
83
+ public routeReq(req: plugins.http.IncomingMessage): plugins.tsclass.network.IReverseProxyConfig {
86
84
  const result = this.routeReqWithDetails(req);
87
85
  return result ? result.config : undefined;
88
86
  }
@@ -92,7 +90,7 @@ export class ProxyRouter {
92
90
  * @param req The incoming HTTP request
93
91
  * @returns Detailed routing result including matched config and path information
94
92
  */
95
- public routeReqWithDetails(req: http.IncomingMessage): IRouterResult | undefined {
93
+ public routeReqWithDetails(req: plugins.http.IncomingMessage): IRouterResult | undefined {
96
94
  // Extract and validate host header
97
95
  const originalHost = req.headers.host;
98
96
  if (!originalHost) {
@@ -101,7 +99,7 @@ export class ProxyRouter {
101
99
  }
102
100
 
103
101
  // Parse URL for path matching
104
- const parsedUrl = url.parse(req.url || '/');
102
+ const parsedUrl = plugins.url.parse(req.url || '/');
105
103
  const urlPath = parsedUrl.pathname || '/';
106
104
 
107
105
  // Extract hostname without port
@@ -351,7 +349,7 @@ export class ProxyRouter {
351
349
  * Gets all currently active proxy configurations
352
350
  * @returns Array of all active configurations
353
351
  */
354
- public getProxyConfigs(): tsclass.network.IReverseProxyConfig[] {
352
+ public getProxyConfigs(): plugins.tsclass.network.IReverseProxyConfig[] {
355
353
  return [...this.reverseProxyConfigs];
356
354
  }
357
355
 
@@ -375,7 +373,7 @@ export class ProxyRouter {
375
373
  * @param pathPattern Optional path pattern for route matching
376
374
  */
377
375
  public addProxyConfig(
378
- config: tsclass.network.IReverseProxyConfig,
376
+ config: plugins.tsclass.network.IReverseProxyConfig,
379
377
  pathPattern?: string
380
378
  ): void {
381
379
  this.reverseProxyConfigs.push(config);
@@ -393,7 +391,7 @@ export class ProxyRouter {
393
391
  * @returns Boolean indicating if the config was found and updated
394
392
  */
395
393
  public setPathPattern(
396
- config: tsclass.network.IReverseProxyConfig,
394
+ config: plugins.tsclass.network.IReverseProxyConfig,
397
395
  pathPattern: string
398
396
  ): boolean {
399
397
  const exists = this.reverseProxyConfigs.includes(config);
@@ -0,0 +1,23 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import type { IAcmeOptions } from './types.js';
4
+ import { Port80Handler } from '../port80handler/classes.port80handler.js';
5
+
6
+ /**
7
+ * Factory to create a Port80Handler with common setup.
8
+ * Ensures the certificate store directory exists and instantiates the handler.
9
+ * @param options Port80Handler configuration options
10
+ * @returns A new Port80Handler instance
11
+ */
12
+ export function buildPort80Handler(
13
+ options: IAcmeOptions
14
+ ): Port80Handler {
15
+ if (options.certificateStore) {
16
+ const certStorePath = path.resolve(options.certificateStore);
17
+ if (!fs.existsSync(certStorePath)) {
18
+ fs.mkdirSync(certStorePath, { recursive: true });
19
+ console.log(`Created certificate store directory: ${certStorePath}`);
20
+ }
21
+ }
22
+ return new Port80Handler(options);
23
+ }
@@ -0,0 +1,34 @@
1
+ import type { Port80Handler } from '../port80handler/classes.port80handler.js';
2
+ import { Port80HandlerEvents } from './types.js';
3
+ import type { ICertificateData, ICertificateFailure, ICertificateExpiring } from './types.js';
4
+
5
+ /**
6
+ * Subscribers callback definitions for Port80Handler events
7
+ */
8
+ export interface Port80HandlerSubscribers {
9
+ onCertificateIssued?: (data: ICertificateData) => void;
10
+ onCertificateRenewed?: (data: ICertificateData) => void;
11
+ onCertificateFailed?: (data: ICertificateFailure) => void;
12
+ onCertificateExpiring?: (data: ICertificateExpiring) => void;
13
+ }
14
+
15
+ /**
16
+ * Subscribes to Port80Handler events based on provided callbacks
17
+ */
18
+ export function subscribeToPort80Handler(
19
+ handler: Port80Handler,
20
+ subscribers: Port80HandlerSubscribers
21
+ ): void {
22
+ if (subscribers.onCertificateIssued) {
23
+ handler.on(Port80HandlerEvents.CERTIFICATE_ISSUED, subscribers.onCertificateIssued);
24
+ }
25
+ if (subscribers.onCertificateRenewed) {
26
+ handler.on(Port80HandlerEvents.CERTIFICATE_RENEWED, subscribers.onCertificateRenewed);
27
+ }
28
+ if (subscribers.onCertificateFailed) {
29
+ handler.on(Port80HandlerEvents.CERTIFICATE_FAILED, subscribers.onCertificateFailed);
30
+ }
31
+ if (subscribers.onCertificateExpiring) {
32
+ handler.on(Port80HandlerEvents.CERTIFICATE_EXPIRING, subscribers.onCertificateExpiring);
33
+ }
34
+ }
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Shared types for certificate management and domain options
3
+ */
4
+
5
+ /**
6
+ * Domain forwarding configuration
7
+ */
8
+ export interface IForwardConfig {
9
+ ip: string;
10
+ port: number;
11
+ }
12
+
13
+ /**
14
+ * Domain configuration options
15
+ */
16
+ export interface IDomainOptions {
17
+ domainName: string;
18
+ sslRedirect: boolean; // if true redirects the request to port 443
19
+ acmeMaintenance: boolean; // tries to always have a valid cert for this domain
20
+ forward?: IForwardConfig; // forwards all http requests to that target
21
+ acmeForward?: IForwardConfig; // forwards letsencrypt requests to this config
22
+ }
23
+
24
+ /**
25
+ * Certificate data that can be emitted via events or set from outside
26
+ */
27
+ export interface ICertificateData {
28
+ domain: string;
29
+ certificate: string;
30
+ privateKey: string;
31
+ expiryDate: Date;
32
+ }
33
+
34
+ /**
35
+ * Events emitted by the Port80Handler
36
+ */
37
+ export enum Port80HandlerEvents {
38
+ CERTIFICATE_ISSUED = 'certificate-issued',
39
+ CERTIFICATE_RENEWED = 'certificate-renewed',
40
+ CERTIFICATE_FAILED = 'certificate-failed',
41
+ CERTIFICATE_EXPIRING = 'certificate-expiring',
42
+ MANAGER_STARTED = 'manager-started',
43
+ MANAGER_STOPPED = 'manager-stopped',
44
+ REQUEST_FORWARDED = 'request-forwarded',
45
+ }
46
+
47
+ /**
48
+ * Certificate failure payload type
49
+ */
50
+ export interface ICertificateFailure {
51
+ domain: string;
52
+ error: string;
53
+ isRenewal: boolean;
54
+ }
55
+
56
+ /**
57
+ * Certificate expiry payload type
58
+ */
59
+ export interface ICertificateExpiring {
60
+ domain: string;
61
+ expiryDate: Date;
62
+ daysRemaining: number;
63
+ }
64
+ /**
65
+ * Forwarding configuration for specific domains in ACME setup
66
+ */
67
+ export interface IDomainForwardConfig {
68
+ domain: string;
69
+ forwardConfig?: IForwardConfig;
70
+ acmeForwardConfig?: IForwardConfig;
71
+ sslRedirect?: boolean;
72
+ }
73
+
74
+ /**
75
+ * Unified ACME configuration options used across proxies and handlers
76
+ */
77
+ export interface IAcmeOptions {
78
+ enabled?: boolean; // Whether ACME is enabled
79
+ port?: number; // Port to listen on for ACME challenges (default: 80)
80
+ contactEmail?: string; // Email for Let's Encrypt account
81
+ useProduction?: boolean; // Use production environment (default: staging)
82
+ httpsRedirectPort?: number; // Port to redirect HTTP requests to HTTPS (default: 443)
83
+ renewThresholdDays?: number; // Days before expiry to renew certificates
84
+ renewCheckIntervalHours?: number; // How often to check for renewals (in hours)
85
+ autoRenew?: boolean; // Whether to automatically renew certificates
86
+ certificateStore?: string; // Directory to store certificates
87
+ skipConfiguredCerts?: boolean; // Skip domains with existing certificates
88
+ domainForwards?: IDomainForwardConfig[]; // Domain-specific forwarding configs
89
+ }
@@ -3,7 +3,11 @@ import * as fs from 'fs';
3
3
  import * as path from 'path';
4
4
  import { fileURLToPath } from 'url';
5
5
  import { type INetworkProxyOptions, type ICertificateEntry, type ILogger, createLogger } from './classes.np.types.js';
6
- import { Port80Handler, Port80HandlerEvents, type IDomainOptions } from '../port80handler/classes.port80handler.js';
6
+ import { Port80Handler } from '../port80handler/classes.port80handler.js';
7
+ import { Port80HandlerEvents } from '../common/types.js';
8
+ import { buildPort80Handler } from '../common/acmeFactory.js';
9
+ import { subscribeToPort80Handler } from '../common/eventUtils.js';
10
+ import type { IDomainOptions } from '../common/types.js';
7
11
 
8
12
  /**
9
13
  * Manages SSL certificates for NetworkProxy including ACME integration
@@ -101,12 +105,14 @@ export class CertificateManager {
101
105
  this.port80Handler = handler;
102
106
  this.externalPort80Handler = true;
103
107
 
104
- // Register event handlers
105
- this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_ISSUED, this.handleCertificateIssued.bind(this));
106
- this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_RENEWED, this.handleCertificateIssued.bind(this));
107
- this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_FAILED, this.handleCertificateFailed.bind(this));
108
- this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_EXPIRING, (data) => {
109
- this.logger.info(`Certificate for ${data.domain} expires in ${data.daysRemaining} days`);
108
+ // Subscribe to Port80Handler events
109
+ subscribeToPort80Handler(this.port80Handler, {
110
+ onCertificateIssued: this.handleCertificateIssued.bind(this),
111
+ onCertificateRenewed: this.handleCertificateIssued.bind(this),
112
+ onCertificateFailed: this.handleCertificateFailed.bind(this),
113
+ onCertificateExpiring: (data) => {
114
+ this.logger.info(`Certificate for ${data.domain} expires in ${data.daysRemaining} days`);
115
+ }
110
116
  });
111
117
 
112
118
  this.logger.info('External Port80Handler connected to CertificateManager');
@@ -348,26 +354,24 @@ export class CertificateManager {
348
354
  return null;
349
355
  }
350
356
 
351
- // Create certificate manager
352
- this.port80Handler = new Port80Handler({
357
+ // Build and configure Port80Handler
358
+ this.port80Handler = buildPort80Handler({
353
359
  port: this.options.acme.port,
354
360
  contactEmail: this.options.acme.contactEmail,
355
361
  useProduction: this.options.acme.useProduction,
356
- renewThresholdDays: this.options.acme.renewThresholdDays,
357
362
  httpsRedirectPort: this.options.port, // Redirect to our HTTPS port
358
- renewCheckIntervalHours: 24, // Check daily for renewals
359
363
  enabled: this.options.acme.enabled,
360
- autoRenew: this.options.acme.autoRenew,
361
364
  certificateStore: this.options.acme.certificateStore,
362
365
  skipConfiguredCerts: this.options.acme.skipConfiguredCerts
363
366
  });
364
-
365
- // Register event handlers
366
- this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_ISSUED, this.handleCertificateIssued.bind(this));
367
- this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_RENEWED, this.handleCertificateIssued.bind(this));
368
- this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_FAILED, this.handleCertificateFailed.bind(this));
369
- this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_EXPIRING, (data) => {
370
- this.logger.info(`Certificate for ${data.domain} expires in ${data.daysRemaining} days`);
367
+ // Subscribe to Port80Handler events
368
+ subscribeToPort80Handler(this.port80Handler, {
369
+ onCertificateIssued: this.handleCertificateIssued.bind(this),
370
+ onCertificateRenewed: this.handleCertificateIssued.bind(this),
371
+ onCertificateFailed: this.handleCertificateFailed.bind(this),
372
+ onCertificateExpiring: (data) => {
373
+ this.logger.info(`Certificate for ${data.domain} expires in ${data.daysRemaining} days`);
374
+ }
371
375
  });
372
376
 
373
377
  // Start the handler
@@ -12,6 +12,10 @@ import { Port80Handler } from '../port80handler/classes.port80handler.js';
12
12
  * automatic certificate management, and high-performance connection pooling.
13
13
  */
14
14
  export class NetworkProxy implements IMetricsTracker {
15
+ // Provide a minimal JSON representation to avoid circular references during deep equality checks
16
+ public toJSON(): any {
17
+ return {};
18
+ }
15
19
  // Configuration
16
20
  public options: INetworkProxyOptions;
17
21
  public proxyConfigs: IReverseProxyConfig[] = [];
@@ -1,5 +1,10 @@
1
1
  import * as plugins from '../plugins.js';
2
2
 
3
+ /**
4
+ * Configuration options for NetworkProxy
5
+ */
6
+ import type { IAcmeOptions } from '../common/types.js';
7
+
3
8
  /**
4
9
  * Configuration options for NetworkProxy
5
10
  */
@@ -24,16 +29,7 @@ export interface INetworkProxyOptions {
24
29
  backendProtocol?: 'http1' | 'http2';
25
30
 
26
31
  // ACME certificate management options
27
- acme?: {
28
- enabled?: boolean; // Whether to enable automatic certificate management
29
- port?: number; // Port to listen on for ACME challenges (default: 80)
30
- contactEmail?: string; // Email for Let's Encrypt account
31
- useProduction?: boolean; // Whether to use Let's Encrypt production (default: false for staging)
32
- renewThresholdDays?: number; // Days before expiry to renew certificates (default: 30)
33
- autoRenew?: boolean; // Whether to automatically renew certificates (default: true)
34
- certificateStore?: string; // Directory to store certificates (default: ./certs)
35
- skipConfiguredCerts?: boolean; // Skip domains that already have certificates configured
36
- };
32
+ acme?: IAcmeOptions;
37
33
  }
38
34
 
39
35
  /**
package/ts/plugins.ts CHANGED
@@ -7,7 +7,6 @@ import * as tls from 'tls';
7
7
  import * as url from 'url';
8
8
  import * as http2 from 'http2';
9
9
 
10
-
11
10
  export { EventEmitter, http, https, net, tls, url, http2 };
12
11
 
13
12
  // tsclass scope
@@ -22,13 +21,27 @@ import * as smartpromise from '@push.rocks/smartpromise';
22
21
  import * as smartrequest from '@push.rocks/smartrequest';
23
22
  import * as smartstring from '@push.rocks/smartstring';
24
23
 
25
- export { lik, smartdelay, smartrequest, smartpromise, smartstring };
24
+ import * as smartacme from '@push.rocks/smartacme';
25
+ import * as smartacmePlugins from '@push.rocks/smartacme/dist_ts/smartacme.plugins.js';
26
+ import * as smartacmeHandlers from '@push.rocks/smartacme/dist_ts/handlers/index.js';
27
+ import * as taskbuffer from '@push.rocks/taskbuffer';
28
+
29
+ export {
30
+ lik,
31
+ smartdelay,
32
+ smartrequest,
33
+ smartpromise,
34
+ smartstring,
35
+ smartacme,
36
+ smartacmePlugins,
37
+ smartacmeHandlers,
38
+ taskbuffer,
39
+ };
26
40
 
27
41
  // third party scope
28
- import * as acme from 'acme-client';
29
42
  import prettyMs from 'pretty-ms';
30
43
  import * as ws from 'ws';
31
44
  import wsDefault from 'ws';
32
45
  import { minimatch } from 'minimatch';
33
46
 
34
- export { acme, prettyMs, ws, wsDefault, minimatch };
47
+ export { prettyMs, ws, wsDefault, minimatch };