import net from "node:net"; export interface RelayMapping { listenPort: number; targetHost: string; targetPort: number; listenHost?: string | undefined; serve?: boolean | undefined; funnel?: boolean | undefined; user?: string | undefined; password?: string | undefined; database?: string | undefined; name?: string | undefined; accessMode?: string | undefined; } export interface RelayOptions { listenPort: number; targetHost: string; targetPort: number; listenHost?: string | undefined; /** Timeout (ms) for connecting to the target. Default: 5000. */ connectTimeoutMs?: number | undefined; onConnection?: ((clientAddr: string) => void) | undefined; onError?: ((error: Error) => void) | undefined; } export interface RelayInstance { server: net.Server; close: () => Promise; connectionsCount: () => Promise; } export type RelayEndpointState = "up" | "down" | "bind-failed" | "auth-failed" | "unknown"; export interface RelayEndpointStatus { mapping: RelayMapping; state: RelayEndpointState; instance?: RelayInstance | undefined; lastError?: string | undefined; } export interface MultiRelayInstance { relays: Array<{ mapping: RelayMapping; instance: RelayInstance; }>; /** Present when allowPartial=true and some binds failed. */ degraded?: boolean | undefined; failed?: Array<{ mapping: RelayMapping; error: string; }> | undefined; close: () => Promise; } /** * Parse a relay mapping string. Supported formats: * "listenPort:targetPort" (2-token, no host separator ambiguity) * "listenPort:targetHost:targetPort" * "listenHost:listenPort:targetHost:targetPort" * * IPv6 addresses must be bracketed: "[fd7a::1]:5432" counts as one token. * * The parser first resolves bracketed IPv6 tokens, then splits on remaining * colons — so "[::1]:5432:10.0.0.1:5432" works as expected. * * B9 fix: full IPv6 support via bracket notation. */ export declare function parseRelayMapping(mapStr: string, defaultTargetHost?: string): RelayMapping; /** * Load relay config from a JSON or JSONC file. * * B3 fix: uses jsonc-parser instead of a regex-based strip that corrupts * connection strings containing "//". */ export declare function loadRelayConfigFile(filePath: string): RelayMapping[]; /** * Start a single TCP relay. * * Fixes applied: * - Default listenHost changed to "127.0.0.1" (explicit 0.0.0.0 to expose) * - socket.setKeepAlive(true, 30_000) on both sockets (bug #3 in plan) * - socket.setNoDelay(true) on both sockets (bug #5 in plan / P1) * - connectTimeoutMs (default 5000) applied via socket.setTimeout (bug #4) * - Graceful end() before destroy() when no bytes have passed (bug #6 / P1) */ export declare function startRelay(options: RelayOptions): Promise; /** * Start multiple TCP relays from a list of mappings. * * Degraded mode (allowPartial=true, recommended for long-running daemons): * - Binds what can be bound; collects failures instead of throwing. * - Returns { degraded: true, failed: [...] } when some binds failed. * - Caller can expose this via an envelope with degraded state. * * Strict mode (default, allowPartial=false): * - Original all-or-nothing behaviour: one failure rolls back all. * - Suitable for one-shot invocations where config correctness is required. */ export declare function startMultiRelay(mappings: RelayMapping[], callbacks?: { onConnection?: (mapping: RelayMapping, clientAddr: string) => void; onError?: (mapping: RelayMapping, error: Error) => void; }, opts?: { allowPartial?: boolean; connectTimeoutMs?: number; }): Promise; //# sourceMappingURL=relay.d.ts.map