fix(typescript): Refactor types and interfaces to use consistent I prefix and update related tests

This commit is contained in:
2025-05-09 22:46:53 +00:00
parent d924190680
commit f8647516b5
45 changed files with 403 additions and 392 deletions

View File

@ -2,26 +2,26 @@ import * as plugins from '../../plugins.js';
import * as fs from 'fs';
import * as path from 'path';
import { fileURLToPath } from 'url';
import { type NetworkProxyOptions, type CertificateEntry, type Logger, createLogger } from './models/types.js';
import { type INetworkProxyOptions, type ICertificateEntry, type ILogger, createLogger } from './models/types.js';
import { Port80Handler } from '../../http/port80/port80-handler.js';
import { CertificateEvents } from '../../certificate/events/certificate-events.js';
import { buildPort80Handler } from '../../certificate/acme/acme-factory.js';
import { subscribeToPort80Handler } from '../../core/utils/event-utils.js';
import type { DomainOptions } from '../../certificate/models/certificate-types.js';
import type { IDomainOptions } from '../../certificate/models/certificate-types.js';
/**
* Manages SSL certificates for NetworkProxy including ACME integration
*/
export class CertificateManager {
private defaultCertificates: { key: string; cert: string };
private certificateCache: Map<string, CertificateEntry> = new Map();
private certificateCache: Map<string, ICertificateEntry> = new Map();
private port80Handler: Port80Handler | null = null;
private externalPort80Handler: boolean = false;
private certificateStoreDir: string;
private logger: Logger;
private logger: ILogger;
private httpsServer: plugins.https.Server | null = null;
constructor(private options: NetworkProxyOptions) {
constructor(private options: INetworkProxyOptions) {
this.certificateStoreDir = path.resolve(options.acme?.certificateStore || './certs');
this.logger = createLogger(options.logLevel || 'info');
@ -219,9 +219,9 @@ export class CertificateManager {
if (!certData) {
this.logger.info(`No certificate found for ${domain}, registering for issuance`);
// Register with new domain options format
const domainOptions: DomainOptions = {
const domainOptions: IDomainOptions = {
domainName: domain,
sslRedirect: true,
acmeMaintenance: true
@ -274,7 +274,7 @@ export class CertificateManager {
/**
* Gets a certificate for a domain
*/
public getCertificate(domain: string): CertificateEntry | undefined {
public getCertificate(domain: string): ICertificateEntry | undefined {
return this.certificateCache.get(domain);
}
@ -300,7 +300,7 @@ export class CertificateManager {
try {
// Use the new domain options format
const domainOptions: DomainOptions = {
const domainOptions: IDomainOptions = {
domainName: domain,
sslRedirect: true,
acmeMaintenance: true
@ -341,7 +341,7 @@ export class CertificateManager {
}
// Register the domain for certificate issuance with new domain options format
const domainOptions: DomainOptions = {
const domainOptions: IDomainOptions = {
domainName: domain,
sslRedirect: true,
acmeMaintenance: true

View File

@ -1,15 +1,15 @@
import * as plugins from '../../plugins.js';
import { type NetworkProxyOptions, type ConnectionEntry, type Logger, createLogger } from './models/types.js';
import { type INetworkProxyOptions, type IConnectionEntry, type ILogger, createLogger } from './models/types.js';
/**
* Manages a pool of backend connections for efficient reuse
*/
export class ConnectionPool {
private connectionPool: Map<string, Array<ConnectionEntry>> = new Map();
private connectionPool: Map<string, Array<IConnectionEntry>> = new Map();
private roundRobinPositions: Map<string, number> = new Map();
private logger: Logger;
private logger: ILogger;
constructor(private options: NetworkProxyOptions) {
constructor(private options: INetworkProxyOptions) {
this.logger = createLogger(options.logLevel || 'info');
}

View File

@ -1,10 +1,10 @@
import * as plugins from '../../../plugins.js';
import type { AcmeOptions } from '../../../certificate/models/certificate-types.js';
import type { IAcmeOptions } from '../../../certificate/models/certificate-types.js';
/**
* Configuration options for NetworkProxy
*/
export interface NetworkProxyOptions {
export interface INetworkProxyOptions {
port: number;
maxConnections?: number;
keepAliveTimeout?: number;
@ -16,22 +16,22 @@ export interface NetworkProxyOptions {
allowHeaders?: string;
maxAge?: number;
};
// Settings for SmartProxy integration
connectionPoolSize?: number; // Maximum connections to maintain in the pool to each backend
portProxyIntegration?: boolean; // Flag to indicate this proxy is used by SmartProxy
useExternalPort80Handler?: boolean; // Flag to indicate using external Port80Handler
// Protocol to use when proxying to backends: HTTP/1.x or HTTP/2
backendProtocol?: 'http1' | 'http2';
// ACME certificate management options
acme?: AcmeOptions;
acme?: IAcmeOptions;
}
/**
* Interface for a certificate entry in the cache
*/
export interface CertificateEntry {
export interface ICertificateEntry {
key: string;
cert: string;
expires?: Date;
@ -40,7 +40,7 @@ export interface CertificateEntry {
/**
* Interface for reverse proxy configuration
*/
export interface ReverseProxyConfig {
export interface IReverseProxyConfig {
destinationIps: string[];
destinationPorts: number[];
hostName: string;
@ -62,7 +62,7 @@ export interface ReverseProxyConfig {
/**
* Interface for connection tracking in the pool
*/
export interface ConnectionEntry {
export interface IConnectionEntry {
socket: plugins.net.Socket;
lastUsed: number;
isIdle: boolean;
@ -71,7 +71,7 @@ export interface ConnectionEntry {
/**
* WebSocket with heartbeat interface
*/
export interface WebSocketWithHeartbeat extends plugins.wsDefault {
export interface IWebSocketWithHeartbeat extends plugins.wsDefault {
lastPong: number;
isAlive: boolean;
}
@ -79,7 +79,7 @@ export interface WebSocketWithHeartbeat extends plugins.wsDefault {
/**
* Logger interface for consistent logging across components
*/
export interface Logger {
export interface ILogger {
debug(message: string, data?: any): void;
info(message: string, data?: any): void;
warn(message: string, data?: any): void;
@ -89,14 +89,14 @@ export interface Logger {
/**
* Creates a logger based on the specified log level
*/
export function createLogger(logLevel: string = 'info'): Logger {
export function createLogger(logLevel: string = 'info'): ILogger {
const logLevels = {
error: 0,
warn: 1,
info: 2,
debug: 3
};
return {
debug: (message: string, data?: any) => {
if (logLevels[logLevel] >= logLevels.debug) {
@ -119,12 +119,4 @@ export function createLogger(logLevel: string = 'info'): Logger {
}
}
};
}
// Backward compatibility interfaces
export interface INetworkProxyOptions extends NetworkProxyOptions {}
export interface ICertificateEntry extends CertificateEntry {}
export interface IReverseProxyConfig extends ReverseProxyConfig {}
export interface IConnectionEntry extends ConnectionEntry {}
export interface IWebSocketWithHeartbeat extends WebSocketWithHeartbeat {}
export interface ILogger extends Logger {}
}

View File

@ -3,9 +3,9 @@ import {
createLogger
} from './models/types.js';
import type {
NetworkProxyOptions,
Logger,
ReverseProxyConfig
INetworkProxyOptions,
ILogger,
IReverseProxyConfig
} from './models/types.js';
import { CertificateManager } from './certificate-manager.js';
import { ConnectionPool } from './connection-pool.js';
@ -24,8 +24,8 @@ export class NetworkProxy implements IMetricsTracker {
return {};
}
// Configuration
public options: NetworkProxyOptions;
public proxyConfigs: ReverseProxyConfig[] = [];
public options: INetworkProxyOptions;
public proxyConfigs: IReverseProxyConfig[] = [];
// Server instances (HTTP/2 with HTTP/1 fallback)
public httpsServer: any;
@ -54,12 +54,12 @@ export class NetworkProxy implements IMetricsTracker {
private connectionPoolCleanupInterval: NodeJS.Timeout;
// Logger
private logger: Logger;
private logger: ILogger;
/**
* Creates a new NetworkProxy instance
*/
constructor(optionsArg: NetworkProxyOptions) {
constructor(optionsArg: INetworkProxyOptions) {
// Set default options
this.options = {
port: optionsArg.port,
@ -328,7 +328,7 @@ export class NetworkProxy implements IMetricsTracker {
* Updates proxy configurations
*/
public async updateProxyConfigs(
proxyConfigsArg: ReverseProxyConfig[]
proxyConfigsArg: IReverseProxyConfig[]
): Promise<void> {
this.logger.info(`Updating proxy configurations (${proxyConfigsArg.length} configs)`);
@ -385,8 +385,8 @@ export class NetworkProxy implements IMetricsTracker {
allowedIPs?: string[];
}>,
sslKeyPair?: { key: string; cert: string }
): ReverseProxyConfig[] {
const proxyConfigs: ReverseProxyConfig[] = [];
): IReverseProxyConfig[] {
const proxyConfigs: IReverseProxyConfig[] = [];
// Use default certificates if not provided
const defaultCerts = this.certificateManager.getDefaultCertificates();
@ -478,7 +478,7 @@ export class NetworkProxy implements IMetricsTracker {
/**
* Gets all proxy configurations currently in use
*/
public getProxyConfigs(): ReverseProxyConfig[] {
public getProxyConfigs(): IReverseProxyConfig[] {
return [...this.proxyConfigs];
}
}

View File

@ -1,5 +1,5 @@
import * as plugins from '../../plugins.js';
import { type NetworkProxyOptions, type Logger, createLogger, type ReverseProxyConfig } from './models/types.js';
import { type INetworkProxyOptions, type ILogger, createLogger, type IReverseProxyConfig } from './models/types.js';
import { ConnectionPool } from './connection-pool.js';
import { ProxyRouter } from '../../http/router/index.js';
@ -19,13 +19,13 @@ export type MetricsTracker = IMetricsTracker;
*/
export class RequestHandler {
private defaultHeaders: { [key: string]: string } = {};
private logger: Logger;
private logger: ILogger;
private metricsTracker: IMetricsTracker | null = null;
// HTTP/2 client sessions for backend proxying
private h2Sessions: Map<string, plugins.http2.ClientHttp2Session> = new Map();
constructor(
private options: NetworkProxyOptions,
private options: INetworkProxyOptions,
private connectionPool: ConnectionPool,
private router: ProxyRouter
) {
@ -137,7 +137,7 @@ export class RequestHandler {
this.applyDefaultHeaders(res);
// Determine routing configuration
let proxyConfig: ReverseProxyConfig | undefined;
let proxyConfig: IReverseProxyConfig | undefined;
try {
proxyConfig = this.router.routeReq(req);
} catch (err) {
@ -235,7 +235,7 @@ export class RequestHandler {
// Remove host header to avoid issues with virtual hosts on target server
// The host header should match the target server's expected hostname
if (options.headers && options.headers.host) {
if ((proxyConfig as ReverseProxyConfig).rewriteHostHeader) {
if ((proxyConfig as IReverseProxyConfig).rewriteHostHeader) {
options.headers.host = `${destination.host}:${destination.port}`;
}
}
@ -426,7 +426,7 @@ export class RequestHandler {
outboundHeaders[key] = value;
}
}
if (outboundHeaders.host && (proxyConfig as any).rewriteHostHeader) {
if (outboundHeaders.host && (proxyConfig as IReverseProxyConfig).rewriteHostHeader) {
outboundHeaders.host = `${destination.host}:${destination.port}`;
}
// Create HTTP/1 proxy request

View File

@ -1,5 +1,5 @@
import * as plugins from '../../plugins.js';
import { type NetworkProxyOptions, type WebSocketWithHeartbeat, type Logger, createLogger, type ReverseProxyConfig } from './models/types.js';
import { type INetworkProxyOptions, type IWebSocketWithHeartbeat, type ILogger, createLogger, type IReverseProxyConfig } from './models/types.js';
import { ConnectionPool } from './connection-pool.js';
import { ProxyRouter } from '../../http/router/index.js';
@ -9,10 +9,10 @@ import { ProxyRouter } from '../../http/router/index.js';
export class WebSocketHandler {
private heartbeatInterval: NodeJS.Timeout | null = null;
private wsServer: plugins.ws.WebSocketServer | null = null;
private logger: Logger;
private logger: ILogger;
constructor(
private options: NetworkProxyOptions,
private options: INetworkProxyOptions,
private connectionPool: ConnectionPool,
private router: ProxyRouter
) {
@ -30,7 +30,7 @@ export class WebSocketHandler {
});
// Handle WebSocket connections
this.wsServer.on('connection', (wsIncoming: WebSocketWithHeartbeat, req: plugins.http.IncomingMessage) => {
this.wsServer.on('connection', (wsIncoming: IWebSocketWithHeartbeat, req: plugins.http.IncomingMessage) => {
this.handleWebSocketConnection(wsIncoming, req);
});
@ -56,9 +56,9 @@ export class WebSocketHandler {
}
this.logger.debug(`WebSocket heartbeat check for ${this.wsServer.clients.size} clients`);
this.wsServer.clients.forEach((ws: plugins.wsDefault) => {
const wsWithHeartbeat = ws as WebSocketWithHeartbeat;
const wsWithHeartbeat = ws as IWebSocketWithHeartbeat;
if (wsWithHeartbeat.isAlive === false) {
this.logger.debug('Terminating inactive WebSocket connection');
@ -79,7 +79,7 @@ export class WebSocketHandler {
/**
* Handle a new WebSocket connection
*/
private handleWebSocketConnection(wsIncoming: WebSocketWithHeartbeat, req: plugins.http.IncomingMessage): void {
private handleWebSocketConnection(wsIncoming: IWebSocketWithHeartbeat, req: plugins.http.IncomingMessage): void {
try {
// Initialize heartbeat tracking
wsIncoming.isAlive = true;
@ -127,7 +127,7 @@ export class WebSocketHandler {
}
// Override host header if needed
if ((proxyConfig as ReverseProxyConfig).rewriteHostHeader) {
if ((proxyConfig as IReverseProxyConfig).rewriteHostHeader) {
headers['host'] = `${destination.host}:${destination.port}`;
}