UNPKG

@stacksjs/rpx

Version:

A modern and smart reverse proxy.

77 lines (76 loc) 3.81 kB
import { execSync } from 'node:child_process'; import type { MultiProxyConfig, PathRewrite, ProxyConfigs, ProxyOption, ProxyOptions, SingleProxyConfig } from './types'; /** * Get sudo password from environment variable if set */ export declare function getSudoPassword(): string | undefined; /** True when the process can write system paths without `sudo` (e.g. rpx daemon started via sudo). */ export declare function isProcessElevated(): boolean; /** * Ensure rpx may perform its privileged setup work without hiding a prompt in * daemon startup. Normal dev-server probes are non-interactive and return * false immediately. Explicit setup commands opt into one visible `sudo -v` * prompt, which also seeds sudo's credential cache for the daemon launch. */ export declare function authorizeSystemAccess(options?: SystemAuthorizationOptions): boolean; /** * Execute a command with sudo, using SUDO_PASSWORD if available */ export declare function execSudoSync(command: string): string; export declare function debugLog(category: string, message: string, verbose?: boolean): void; /** * Whether the proxy's listeners should set `reusePort`. Off by default: rpx is a * single-instance local-dev proxy, and one instance gains nothing from * `SO_REUSEPORT` while losing the helpful "port 443 already in use" guard. * * Opt in with `RPX_REUSE_PORT=1` when running **multiple** rpx instances behind a * process manager (systemd/pm2/k8s) on **Linux**, where the kernel load-balances * accepted connections across them for multi-core scaling. It is a no-op on * macOS/BSD, whose `SO_REUSEPORT` does not load-balance across processes — so * rpx never spawns a worker cluster itself; scaling is left to the OS + your * supervisor, which is where it belongs for a dev proxy. */ export declare function shouldReusePort(): boolean; export declare function redactSensitive(value: unknown): unknown; export declare function safeStringify(value: unknown, space?: number): string; /** * Extracts hostnames from proxy configuration */ export declare function extractHostname(options: ProxyOption | ProxyOptions): string[]; export declare function isValidRootCA(value: unknown): value is RootCA; export declare function getPrimaryDomain(options?: ProxyOption | ProxyOptions): string; /** * Type guard for multi-proxy configuration */ export declare function isMultiProxyConfig(options: ProxyConfigs | ProxyOptions): options is MultiProxyConfig; /** * Type guard to check if options are for multi-proxy configuration */ export declare function isMultiProxyOptions(options: ProxyOption | ProxyOptions): options is MultiProxyConfig; /** * Type guard to check if options are for single-proxy configuration */ export declare function isSingleProxyOptions(options: ProxyOption | ProxyOptions): options is SingleProxyConfig; export declare function isSingleProxyConfig(options: ProxyConfigs | ProxyOptions): options is SingleProxyConfig; /** * Resolve a path against a list of `pathRewrites`. * * Returns `null` if no rewrite matches; otherwise returns `{ targetHost, targetPath }` * with the prefix preserved by default (or stripped when `stripPrefix === true`). * * Matching rule: rewrite matches if `pathname` is exactly `from` OR starts with * `from + '/'`. So `/api` matches `/api`, `/api/`, `/api/cart` — but not `/apidocs`. */ export declare function resolvePathRewrite(pathname: string, rewrites: PathRewrite[] | undefined): { targetHost: string, targetPath: string } | null; /** * Safely delete a file if it exists */ export declare function safeDeleteFile(filePath: string, verbose?: boolean): Promise<void>; export declare interface SystemAuthorizationOptions { interactive?: boolean exec?: typeof execSync } declare interface RootCA { certificate: string privateKey: string }