BREAKING CHANGE(smartproxy): Update documentation and refactor core proxy components; remove legacy performRenewals method from SmartProxy; update router type imports and adjust test suites for improved coverage

This commit is contained in:
2025-05-03 13:19:23 +00:00
parent 32b4e32bf0
commit 0e634c46a6
8 changed files with 276 additions and 534 deletions

View File

@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@push.rocks/smartproxy',
version: '9.0.0',
version: '10.0.0',
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.'
}

View File

@ -1,6 +1,4 @@
import * as http from 'http';
import * as url from 'url';
import * as tsclass from '@tsclass/tsclass';
import * as plugins from './plugins.js';
/**
* Optional path pattern configuration that can be added to proxy configs
@ -13,7 +11,7 @@ export interface IPathPatternConfig {
* Interface for router result with additional metadata
*/
export interface IRouterResult {
config: tsclass.network.IReverseProxyConfig;
config: plugins.tsclass.network.IReverseProxyConfig;
pathMatch?: string;
pathParams?: Record<string, string>;
pathRemainder?: string;
@ -36,11 +34,11 @@ export interface IRouterResult {
*/
export class ProxyRouter {
// Store original configs for reference
private reverseProxyConfigs: tsclass.network.IReverseProxyConfig[] = [];
private reverseProxyConfigs: plugins.tsclass.network.IReverseProxyConfig[] = [];
// Default config to use when no match is found (optional)
private defaultConfig?: tsclass.network.IReverseProxyConfig;
private defaultConfig?: plugins.tsclass.network.IReverseProxyConfig;
// Store path patterns separately since they're not in the original interface
private pathPatterns: Map<tsclass.network.IReverseProxyConfig, string> = new Map();
private pathPatterns: Map<plugins.tsclass.network.IReverseProxyConfig, string> = new Map();
// Logger interface
private logger: {
error: (message: string, data?: any) => void;
@ -50,7 +48,7 @@ export class ProxyRouter {
};
constructor(
configs?: tsclass.network.IReverseProxyConfig[],
configs?: plugins.tsclass.network.IReverseProxyConfig[],
logger?: {
error: (message: string, data?: any) => void;
warn: (message: string, data?: any) => void;
@ -68,7 +66,7 @@ export class ProxyRouter {
* Sets a new set of reverse configs to be routed to
* @param reverseCandidatesArg Array of reverse proxy configurations
*/
public setNewProxyConfigs(reverseCandidatesArg: tsclass.network.IReverseProxyConfig[]): void {
public setNewProxyConfigs(reverseCandidatesArg: plugins.tsclass.network.IReverseProxyConfig[]): void {
this.reverseProxyConfigs = [...reverseCandidatesArg];
// Find default config if any (config with "*" as hostname)
@ -82,7 +80,7 @@ export class ProxyRouter {
* @param req The incoming HTTP request
* @returns The matching proxy config or undefined if no match found
*/
public routeReq(req: http.IncomingMessage): tsclass.network.IReverseProxyConfig {
public routeReq(req: plugins.http.IncomingMessage): plugins.tsclass.network.IReverseProxyConfig {
const result = this.routeReqWithDetails(req);
return result ? result.config : undefined;
}
@ -92,7 +90,7 @@ export class ProxyRouter {
* @param req The incoming HTTP request
* @returns Detailed routing result including matched config and path information
*/
public routeReqWithDetails(req: http.IncomingMessage): IRouterResult | undefined {
public routeReqWithDetails(req: plugins.http.IncomingMessage): IRouterResult | undefined {
// Extract and validate host header
const originalHost = req.headers.host;
if (!originalHost) {
@ -101,7 +99,7 @@ export class ProxyRouter {
}
// Parse URL for path matching
const parsedUrl = url.parse(req.url || '/');
const parsedUrl = plugins.url.parse(req.url || '/');
const urlPath = parsedUrl.pathname || '/';
// Extract hostname without port
@ -351,7 +349,7 @@ export class ProxyRouter {
* Gets all currently active proxy configurations
* @returns Array of all active configurations
*/
public getProxyConfigs(): tsclass.network.IReverseProxyConfig[] {
public getProxyConfigs(): plugins.tsclass.network.IReverseProxyConfig[] {
return [...this.reverseProxyConfigs];
}
@ -375,7 +373,7 @@ export class ProxyRouter {
* @param pathPattern Optional path pattern for route matching
*/
public addProxyConfig(
config: tsclass.network.IReverseProxyConfig,
config: plugins.tsclass.network.IReverseProxyConfig,
pathPattern?: string
): void {
this.reverseProxyConfigs.push(config);
@ -393,7 +391,7 @@ export class ProxyRouter {
* @returns Boolean indicating if the config was found and updated
*/
public setPathPattern(
config: tsclass.network.IReverseProxyConfig,
config: plugins.tsclass.network.IReverseProxyConfig,
pathPattern: string
): boolean {
const exists = this.reverseProxyConfigs.includes(config);

View File

@ -422,27 +422,6 @@ export class SmartProxy extends plugins.EventEmitter {
}
/**
* Perform scheduled renewals for managed domains
*/
private async performRenewals(): Promise<void> {
if (!this.port80Handler) return;
const statuses = this.port80Handler.getDomainCertificateStatus();
const threshold = this.settings.acme?.renewThresholdDays ?? 30;
const now = new Date();
for (const [domain, status] of statuses.entries()) {
if (!status.certObtained || status.obtainingInProgress || !status.expiryDate) continue;
const msRemaining = status.expiryDate.getTime() - now.getTime();
const daysRemaining = Math.ceil(msRemaining / (24 * 60 * 60 * 1000));
if (daysRemaining <= threshold) {
try {
await this.port80Handler.renewCertificate(domain);
} catch (err) {
console.error(`Error renewing certificate for ${domain}:`, err);
}
}
}
}
/**
* Request a certificate for a specific domain
*/