service-keepalive 1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/duration.ts","../src/utils/redact.ts","../src/logger.ts","../src/http-client.ts","../src/retry.ts","../src/keepalive.ts","../src/multi-keepalive.ts","../src/config.ts","../src/cli.ts"],"names":["resolve","EventEmitter","existsSync","readFileSync","pathToFileURL"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Multipliers in milliseconds for various duration units.\n */\nconst TIME_UNITS: Record<string, number> = {\n ms: 1,\n millisecond: 1,\n milliseconds: 1,\n s: 1000,\n sec: 1000,\n second: 1000,\n seconds: 1000,\n m: 60 * 1000,\n min: 60 * 1000,\n minute: 60 * 1000,\n minutes: 60 * 1000,\n h: 60 * 60 * 1000,\n hr: 60 * 60 * 1000,\n hour: 60 * 60 * 1000,\n hours: 60 * 60 * 1000,\n d: 24 * 60 * 60 * 1000,\n day: 24 * 60 * 60 * 1000,\n days: 24 * 60 * 60 * 1000,\n};\n\n/**\n * Regex matching compound or single duration components (e.g. '10m', '30s', '1h30m', '500ms').\n */\nconst DURATION_REGEX = /^(\\s*(\\d+(?:\\.\\d+)?)\\s*([a-zA-Z]+)\\s*)+$/;\nconst DURATION_PART_REGEX = /(\\d+(?:\\.\\d+)?)\\s*([a-zA-Z]+)/g;\n\n/**\n * Parses a human-readable duration string or millisecond number into milliseconds.\n *\n * Supported formats:\n * - Number: `5000` (treated as 5000ms)\n * - String: `'10s'`, `'30s'`, `'1m'`, `'5m'`, `'10m'`, `'1h'`, `'500ms'`, `'1m30s'`\n *\n * @throws {TypeError | RangeError} If the duration is invalid, zero, or negative.\n */\nexport function parseDuration(value: string | number, fieldName = 'Duration'): number {\n if (value === null || value === undefined) {\n throw new TypeError(`${fieldName} must be provided as a string or number.`);\n }\n\n if (typeof value === 'number') {\n if (!Number.isFinite(value) || Number.isNaN(value)) {\n throw new RangeError(`${fieldName} must be a finite number, received ${value}.`);\n }\n if (value <= 0) {\n throw new RangeError(`${fieldName} must be greater than 0, received ${value}.`);\n }\n return Math.round(value);\n }\n\n if (typeof value !== 'string') {\n throw new TypeError(`${fieldName} must be a string or number, received ${typeof value}.`);\n }\n\n const trimmed = value.trim();\n if (trimmed.length === 0) {\n throw new RangeError(`${fieldName} cannot be an empty string.`);\n }\n\n // If the string is purely digits, parse as milliseconds\n if (/^\\d+$/.test(trimmed)) {\n const parsedNumber = Number(trimmed);\n if (parsedNumber <= 0) {\n throw new RangeError(`${fieldName} must be greater than 0.`);\n }\n return parsedNumber;\n }\n\n if (!DURATION_REGEX.test(trimmed)) {\n throw new RangeError(\n `Invalid ${fieldName} format: \"${value}\". Expected formats like \"10s\", \"1m\", \"5m\", \"1h\", \"500ms\".`,\n );\n }\n\n let totalMs = 0;\n let match: RegExpExecArray | null;\n DURATION_PART_REGEX.lastIndex = 0;\n\n while ((match = DURATION_PART_REGEX.exec(trimmed)) !== null) {\n const amountStr = match[1];\n const unitStr = match[2];\n\n if (!amountStr || !unitStr) {\n throw new RangeError(`Failed parsing ${fieldName} segment \"${match[0]}\".`);\n }\n\n const amount = parseFloat(amountStr);\n const unit = unitStr.toLowerCase();\n const multiplier = TIME_UNITS[unit];\n\n if (!multiplier) {\n throw new RangeError(\n `Unknown time unit \"${unit}\" in ${fieldName}. Supported units: ms, s, m, h, d.`,\n );\n }\n\n if (amount < 0 || !Number.isFinite(amount)) {\n throw new RangeError(`Invalid amount \"${amount}\" for unit \"${unit}\" in ${fieldName}.`);\n }\n\n totalMs += amount * multiplier;\n }\n\n const rounded = Math.round(totalMs);\n if (rounded <= 0) {\n throw new RangeError(`${fieldName} must evaluate to greater than 0ms.`);\n }\n\n return rounded;\n}\n\n/**\n * Formats a duration in milliseconds into a concise human-readable string.\n *\n * Examples:\n * - `142` -> `'142ms'`\n * - `5000` -> `'5s'`\n * - `60000` -> `'1m'`\n * - `90000` -> `'1m 30s'`\n * - `3600000` -> `'1h'`\n */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${Math.round(ms)}ms`;\n }\n\n const seconds = Math.floor((ms / 1000) % 60);\n const minutes = Math.floor((ms / (1000 * 60)) % 60);\n const hours = Math.floor((ms / (1000 * 60 * 60)) % 24);\n const days = Math.floor(ms / (1000 * 60 * 60 * 24));\n\n const parts: string[] = [];\n\n if (days > 0) parts.push(`${days}d`);\n if (hours > 0) parts.push(`${hours}h`);\n if (minutes > 0) parts.push(`${minutes}m`);\n if (seconds > 0) parts.push(`${seconds}s`);\n\n return parts.length > 0 ? parts.join(' ') : `${ms}ms`;\n}\n","const SENSITIVE_HEADER_PATTERNS = [\n /authorization/i,\n /cookie/i,\n /token/i,\n /secret/i,\n /password/i,\n /api[_-]?key/i,\n /auth/i,\n /session/i,\n /credential/i,\n /private[_-]?key/i,\n];\n\nconst SENSITIVE_QUERY_PARAMS = [\n 'token',\n 'key',\n 'api_key',\n 'apikey',\n 'secret',\n 'password',\n 'passwd',\n 'auth',\n 'access_token',\n 'bearer',\n 'session',\n];\n\n/**\n * Returns a shallow copy of headers with sensitive values masked.\n */\nexport function redactHeaders(headers?: Record<string, string> | null): Record<string, string> {\n if (!headers) return {};\n\n const sanitized: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(headers)) {\n const isSensitive = SENSITIVE_HEADER_PATTERNS.some(pattern => pattern.test(key));\n if (isSensitive) {\n sanitized[key] = '[REDACTED]';\n } else {\n sanitized[key] = value;\n }\n }\n\n return sanitized;\n}\n\n/**\n * Masks sensitive query parameters in a URL string for safe logging.\n */\nexport function redactUrl(urlStr: string): string {\n try {\n const url = new URL(urlStr);\n let modified = false;\n\n for (const param of SENSITIVE_QUERY_PARAMS) {\n if (url.searchParams.has(param)) {\n url.searchParams.set(param, '[REDACTED]');\n modified = true;\n }\n }\n\n return modified ? url.toString() : urlStr;\n } catch {\n // If URL parsing fails, return as-is\n return urlStr;\n }\n}\n","import { LoggerInterface, LogLevel } from './types.js';\n\n/**\n * ANSI Color Escape Codes\n */\nconst COLORS = {\n reset: '\\x1b[0m',\n dim: '\\x1b[2m',\n bold: '\\x1b[1m',\n green: '\\x1b[32m',\n red: '\\x1b[31m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n cyan: '\\x1b[36m',\n gray: '\\x1b[90m',\n};\n\nfunction supportsColor(): boolean {\n if (typeof process === 'undefined') return false;\n if ('NO_COLOR' in process.env && process.env['NO_COLOR'] !== '') return false;\n if ('FORCE_COLOR' in process.env && process.env['FORCE_COLOR'] !== '0') return true;\n return Boolean(process.stdout && process.stdout.isTTY);\n}\n\nconst isColorSupported = supportsColor();\n\nfunction colorize(text: string, color: keyof typeof COLORS): string {\n if (!isColorSupported) return text;\n return `${COLORS[color]}${text}${COLORS.reset}`;\n}\n\nexport function formatTimestamp(date = new Date()): string {\n const pad = (n: number) => n.toString().padStart(2, '0');\n const h = pad(date.getHours());\n const m = pad(date.getMinutes());\n const s = pad(date.getSeconds());\n return `${h}:${m}:${s}`;\n}\n\nexport class Logger implements LoggerInterface {\n private logLevel: LogLevel;\n private prefix?: string;\n\n constructor(options: { logLevel?: LogLevel; prefix?: string } = {}) {\n this.logLevel = options.logLevel ?? 'normal';\n this.prefix = options.prefix;\n }\n\n public setLevel(level: LogLevel): void {\n this.logLevel = level;\n }\n\n public setPrefix(prefix: string | undefined): void {\n this.prefix = prefix;\n }\n\n private shouldLog(level: LogLevel): boolean {\n if (this.logLevel === 'quiet') {\n return level === 'quiet';\n }\n if (this.logLevel === 'normal') {\n return level !== 'verbose';\n }\n return true; // verbose logs everything\n }\n\n private formatLine(content: string, timeColor: keyof typeof COLORS = 'gray'): string {\n const timeStr = colorize(`[${formatTimestamp()}]`, timeColor);\n const prefixStr = this.prefix ? colorize(`[${this.prefix}] `, 'cyan') : '';\n return `${timeStr} ${prefixStr}${content}`;\n }\n\n public info(message: string, ...args: unknown[]): void {\n if (!this.shouldLog('normal')) return;\n const formatted = this.formatLine(message);\n if (args.length > 0) {\n console.log(formatted, ...args);\n } else {\n console.log(formatted);\n }\n }\n\n public success(message: string, ...args: unknown[]): void {\n if (!this.shouldLog('normal')) return;\n const symbol = colorize('✓', 'green');\n const formatted = this.formatLine(`${symbol} ${colorize(message, 'green')}`);\n if (args.length > 0) {\n console.log(formatted, ...args);\n } else {\n console.log(formatted);\n }\n }\n\n public warn(message: string, ...args: unknown[]): void {\n if (!this.shouldLog('normal')) return;\n const symbol = colorize('⚠', 'yellow');\n const formatted = this.formatLine(`${symbol} ${colorize(message, 'yellow')}`);\n if (args.length > 0) {\n console.warn(formatted, ...args);\n } else {\n console.warn(formatted);\n }\n }\n\n public error(message: string, ...args: unknown[]): void {\n // Errors are logged even in quiet mode\n const symbol = colorize('✗', 'red');\n const formatted = this.formatLine(`${symbol} ${colorize(message, 'red')}`, 'red');\n if (args.length > 0) {\n console.error(formatted, ...args);\n } else {\n console.error(formatted);\n }\n }\n\n public retry(message: string, ...args: unknown[]): void {\n if (!this.shouldLog('normal')) return;\n const symbol = colorize('↻', 'yellow');\n const formatted = this.formatLine(`${symbol} ${colorize(message, 'yellow')}`);\n if (args.length > 0) {\n console.log(formatted, ...args);\n } else {\n console.log(formatted);\n }\n }\n\n public debug(message: string, ...args: unknown[]): void {\n if (!this.shouldLog('verbose')) return;\n const label = colorize('[DEBUG]', 'dim');\n const formatted = this.formatLine(`${label} ${colorize(message, 'dim')}`);\n if (args.length > 0) {\n console.debug(formatted, ...args);\n } else {\n console.debug(formatted);\n }\n }\n}\n","import { HttpMethod, PingResult } from './types.js';\nimport { redactHeaders } from './utils/redact.js';\n\nexport interface ExecutePingOptions {\n serviceName: string;\n url: string;\n method: HttpMethod;\n headers?: Record<string, string>;\n body?: string | null;\n timeoutMs: number;\n attempt?: number;\n expectedStatusCodes?: number[] | ((status: number) => boolean);\n externalSignal?: AbortSignal;\n}\n\n/**\n * Checks whether an HTTP status code is considered successful.\n */\nexport function isStatusSuccessful(\n status: number,\n expected?: number[] | ((status: number) => boolean),\n): boolean {\n if (typeof expected === 'function') {\n return expected(status);\n }\n if (Array.isArray(expected) && expected.length > 0) {\n return expected.includes(status);\n }\n // Default: 2xx standard status range\n return status >= 200 && status < 300;\n}\n\n/**\n * Executes a single HTTP ping request with timeout and cancellation protection.\n */\nexport async function executePing(options: ExecutePingOptions): Promise<PingResult> {\n const {\n serviceName,\n url,\n method = 'GET',\n headers = {},\n body = null,\n timeoutMs,\n attempt = 1,\n expectedStatusCodes,\n externalSignal,\n } = options;\n\n const controller = new AbortController();\n let timeoutId: NodeJS.Timeout | null = null;\n let didTimeout = false;\n\n const onExternalAbort = () => {\n controller.abort(new Error('Operation cancelled'));\n };\n\n if (externalSignal) {\n if (externalSignal.aborted) {\n controller.abort(new Error('Operation cancelled'));\n } else {\n externalSignal.addEventListener('abort', onExternalAbort, { once: true });\n }\n }\n\n // Set timeout abort timer\n timeoutId = setTimeout(() => {\n didTimeout = true;\n controller.abort(new Error(`Request timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n\n const requestHeaders: Record<string, string> = {\n 'User-Agent': 'service-keepalive/1.0.0',\n Accept: '*/*',\n ...headers,\n };\n\n const startTime = performance.now();\n const timestamp = new Date();\n\n try {\n const fetchOptions: RequestInit = {\n method,\n headers: requestHeaders,\n signal: controller.signal,\n };\n\n if (body && method !== 'GET' && method !== 'HEAD') {\n fetchOptions.body = body;\n }\n\n const response = await fetch(url, fetchOptions);\n const durationMs = Math.round(performance.now() - startTime);\n\n const isOk = isStatusSuccessful(response.status, expectedStatusCodes);\n\n // Consume body stream to free sockets\n try {\n if (response.body) {\n // Read text or discard to avoid leaking sockets\n await response.text();\n }\n } catch {\n // Ignore drain errors\n }\n\n // Extract response headers (sanitized)\n const resHeaders: Record<string, string> = {};\n response.headers.forEach((val, key) => {\n resHeaders[key] = val;\n });\n\n return {\n serviceName,\n url,\n method,\n status: response.status,\n statusText: response.statusText || `${response.status}`,\n ok: isOk,\n durationMs,\n attempt,\n timestamp,\n headers: redactHeaders(resHeaders),\n error: isOk ? undefined : `HTTP ${response.status} ${response.statusText || 'Error'}`,\n };\n } catch (err: unknown) {\n const durationMs = Math.round(performance.now() - startTime);\n let errorMessage = 'Unknown network error';\n\n if (didTimeout) {\n errorMessage = `Request timed out after ${timeoutMs}ms`;\n } else if (err instanceof Error) {\n if (err.name === 'AbortError' || err.message.includes('aborted')) {\n errorMessage = externalSignal?.aborted\n ? 'Request cancelled by user'\n : `Request timed out after ${timeoutMs}ms`;\n } else {\n errorMessage = err.message;\n }\n }\n\n return {\n serviceName,\n url,\n method,\n status: 0,\n statusText: 'Network Error',\n ok: false,\n durationMs,\n attempt,\n timestamp,\n error: errorMessage,\n };\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n if (externalSignal) {\n externalSignal.removeEventListener('abort', onExternalAbort);\n }\n }\n}\n","import { RetryStrategy } from './types.js';\n\nexport interface BackoffOptions {\n attempt: number;\n baseDelayMs: number;\n strategy?: RetryStrategy;\n maxDelayMs?: number;\n jitter?: boolean;\n}\n\n/**\n * Calculates the backoff delay in milliseconds for a given attempt.\n *\n * @param options Calculation parameters\n * @returns Delay in milliseconds\n */\nexport function calculateBackoff(options: BackoffOptions): number {\n const {\n attempt,\n baseDelayMs,\n strategy = 'exponential',\n maxDelayMs = 60000,\n jitter = true,\n } = options;\n\n if (attempt <= 0) return 0;\n\n let delay = baseDelayMs;\n\n switch (strategy) {\n case 'exponential':\n // 2^(attempt - 1) * baseDelay\n delay = baseDelayMs * Math.pow(2, attempt - 1);\n break;\n case 'linear':\n // attempt * baseDelay\n delay = baseDelayMs * attempt;\n break;\n case 'fixed':\n default:\n delay = baseDelayMs;\n break;\n }\n\n // Cap at maximum configured delay\n delay = Math.min(delay, maxDelayMs);\n\n // Apply ±20% randomized jitter if enabled to prevent thundering herd\n if (jitter) {\n const jitterFactor = 0.8 + Math.random() * 0.4; // between 0.8 and 1.2\n delay = Math.round(delay * jitterFactor);\n } else {\n delay = Math.round(delay);\n }\n\n return Math.max(0, delay);\n}\n\n/**\n * Asynchronously sleeps for the given duration, cancellable via AbortSignal.\n *\n * @param ms Duration in milliseconds\n * @param signal Optional AbortSignal to cancel waiting\n */\nexport function sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (signal?.aborted) {\n return reject(new Error('Operation aborted'));\n }\n\n let timer: NodeJS.Timeout | null = null;\n\n const onAbort = () => {\n if (timer) clearTimeout(timer);\n reject(new Error('Operation aborted'));\n };\n\n if (signal) {\n signal.addEventListener('abort', onAbort, { once: true });\n }\n\n timer = setTimeout(() => {\n if (signal) {\n signal.removeEventListener('abort', onAbort);\n }\n resolve();\n }, ms);\n });\n}\n","import { EventEmitter } from 'node:events';\nimport {\n KeepAliveConfig,\n KeepAliveEvents,\n PingResult,\n ResolvedServiceConfig,\n RetryInfo,\n} from './types.js';\nimport { parseDuration, formatDuration } from './utils/duration.js';\nimport { redactHeaders, redactUrl } from './utils/redact.js';\nimport { Logger } from './logger.js';\nimport { executePing } from './http-client.js';\nimport { calculateBackoff, sleep } from './retry.js';\n\nexport class KeepAlive extends EventEmitter {\n private config: ResolvedServiceConfig;\n private running = false;\n private timer: NodeJS.Timeout | null = null;\n private inFlightAbortController: AbortController | null = null;\n private logger: Logger | null = null;\n\n constructor(options: KeepAliveConfig) {\n super();\n this.config = this.resolveConfig(options);\n }\n\n private resolveConfig(options: KeepAliveConfig): ResolvedServiceConfig {\n if (!options || typeof options !== 'object') {\n throw new TypeError('KeepAlive options must be an object.');\n }\n\n if (!options.url || typeof options.url !== 'string') {\n throw new TypeError('url is required and must be a string.');\n }\n\n let parsedUrl: URL;\n try {\n parsedUrl = new URL(options.url);\n if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {\n throw new Error('Protocol must be http or https');\n }\n } catch {\n throw new Error(`Invalid URL: \"${options.url}\". Must be a valid http:// or https:// URL.`);\n }\n\n const name = options.name ?? parsedUrl.hostname;\n const intervalMs = parseDuration(options.interval ?? '10m', 'interval');\n const timeoutMs = parseDuration(options.timeout ?? '30s', 'timeout');\n const method = (options.method?.toUpperCase() ?? 'GET') as ResolvedServiceConfig['method'];\n const retries = Math.max(0, options.retries ?? 3);\n const retryDelayMs = parseDuration(options.retryDelay ?? '5s', 'retryDelay');\n const maxRetryDelayMs = parseDuration(options.maxRetryDelay ?? '60s', 'maxRetryDelay');\n const retryStrategy = options.retryStrategy ?? 'exponential';\n const retryJitter = options.retryJitter ?? true;\n const unrefTimer = options.unrefTimer ?? false;\n const logLevel = options.logLevel ?? 'normal';\n\n let loggerInstance: Logger | null = null;\n if (options.logger !== false) {\n if (options.logger && typeof options.logger === 'object') {\n // Custom logger provided\n loggerInstance = options.logger as Logger;\n } else {\n loggerInstance = new Logger({ logLevel, prefix: name });\n }\n }\n this.logger = loggerInstance;\n\n return {\n name,\n url: options.url,\n intervalMs,\n timeoutMs,\n method,\n headers: options.headers ?? {},\n body: options.body ?? null,\n retries,\n retryDelayMs,\n retryStrategy,\n retryJitter,\n maxRetryDelayMs,\n expectedStatusCodes: options.expectedStatusCodes ?? ((s: number) => s >= 200 && s < 300),\n logger: loggerInstance,\n logLevel,\n unrefTimer,\n };\n }\n\n /**\n * Returns whether the keep-alive scheduler is actively running.\n */\n public isRunning(): boolean {\n return this.running;\n }\n\n /**\n * Returns the resolved service configuration.\n */\n public getConfig(): Readonly<ResolvedServiceConfig> {\n return Object.freeze({ ...this.config });\n }\n\n /**\n * Starts the keep-alive scheduler.\n * Performs an immediate ping, then continues at the configured interval.\n */\n public start(): this {\n if (this.running) {\n this.logger?.debug(`Service [${this.config.name}] is already running.`);\n return this;\n }\n\n this.running = true;\n this.inFlightAbortController = new AbortController();\n\n this.logger?.info(\n `Starting keep-alive for ${redactUrl(this.config.url)} (interval: ${formatDuration(this.config.intervalMs)}, timeout: ${formatDuration(this.config.timeoutMs)})`,\n );\n\n this.emit('start', this.config.name);\n\n // Run first ping asynchronously, then chain subsequent schedules\n void this.runPingLoop();\n\n return this;\n }\n\n /**\n * Stops the keep-alive scheduler and aborts any active requests or wait timers.\n */\n public async stop(): Promise<void> {\n if (!this.running) return;\n\n this.running = false;\n\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n\n if (this.inFlightAbortController) {\n this.inFlightAbortController.abort();\n this.inFlightAbortController = null;\n }\n\n this.logger?.info(`Stopped keep-alive for ${this.config.name}.`);\n this.emit('stop', this.config.name);\n }\n\n /**\n * Executes a single ping cycle with retries without starting the recurring scheduler.\n */\n public async pingOnce(): Promise<PingResult> {\n const abortController = new AbortController();\n return this.executePingWithRetries(abortController.signal);\n }\n\n /**\n * Core scheduling loop. Executes a ping cycle, then schedules the next interval.\n */\n private async runPingLoop(): Promise<void> {\n if (!this.running) return;\n\n try {\n this.inFlightAbortController = new AbortController();\n await this.executePingWithRetries(this.inFlightAbortController.signal);\n } catch (err) {\n if (this.running) {\n this.emit('error', err instanceof Error ? err : new Error(String(err)), this.config.name);\n }\n } finally {\n this.inFlightAbortController = null;\n }\n\n if (!this.running) return;\n\n // Schedule next execution\n this.timer = setTimeout(() => {\n void this.runPingLoop();\n }, this.config.intervalMs);\n\n if (this.config.unrefTimer && this.timer && typeof this.timer.unref === 'function') {\n this.timer.unref();\n }\n }\n\n /**\n * Executes the ping request, retrying on failure up to configured retry attempts.\n */\n private async executePingWithRetries(signal?: AbortSignal): Promise<PingResult> {\n const maxAttempts = 1 + this.config.retries;\n let lastResult: PingResult | null = null;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n if (signal?.aborted) {\n break;\n }\n\n this.logger?.info(`Pinging ${redactUrl(this.config.url)}`);\n this.emit('ping', {\n name: this.config.name,\n url: this.config.url,\n attempt,\n });\n\n const result = await executePing({\n serviceName: this.config.name,\n url: this.config.url,\n method: this.config.method,\n headers: this.config.headers,\n body: this.config.body,\n timeoutMs: this.config.timeoutMs,\n attempt,\n expectedStatusCodes: this.config.expectedStatusCodes,\n externalSignal: signal,\n });\n\n lastResult = result;\n\n if (result.ok) {\n this.logger?.success(`${result.status} ${result.statusText} - ${result.durationMs}ms`);\n if (this.config.logLevel === 'verbose' && result.headers) {\n this.logger?.debug(`Response headers: ${JSON.stringify(redactHeaders(result.headers))}`);\n }\n this.emit('success', result);\n return result;\n }\n\n // If ping failed\n const errorDetail = result.error || `HTTP ${result.status}`;\n this.logger?.error(`Request failed - ${errorDetail}`);\n\n // If attempts remain, calculate backoff delay and wait\n if (attempt < maxAttempts && (!signal || !signal.aborted)) {\n const delayMs = calculateBackoff({\n attempt,\n baseDelayMs: this.config.retryDelayMs,\n strategy: this.config.retryStrategy,\n maxDelayMs: this.config.maxRetryDelayMs,\n jitter: this.config.retryJitter,\n });\n\n const retryInfo: RetryInfo = {\n serviceName: this.config.name,\n url: this.config.url,\n attempt,\n maxRetries: this.config.retries,\n delayMs,\n error: errorDetail,\n };\n\n if (\n this.logger &&\n 'retry' in this.logger &&\n typeof (this.logger as Logger).retry === 'function'\n ) {\n (this.logger as Logger).retry(\n `Retrying ${attempt}/${this.config.retries} in ${formatDuration(delayMs)}...`,\n );\n } else {\n this.logger?.warn(\n `Retrying ${attempt}/${this.config.retries} in ${formatDuration(delayMs)}...`,\n );\n }\n\n this.emit('retry', retryInfo);\n\n try {\n await sleep(delayMs, signal);\n } catch {\n // Aborted during sleep\n break;\n }\n }\n }\n\n // All retries failed\n const finalResult: PingResult = lastResult ?? {\n serviceName: this.config.name,\n url: this.config.url,\n method: this.config.method,\n status: 0,\n statusText: 'Failed',\n ok: false,\n durationMs: 0,\n attempt: maxAttempts,\n timestamp: new Date(),\n error: 'All retry attempts exhausted',\n };\n\n this.emit('failure', finalResult);\n return finalResult;\n }\n\n // Type-safe event emitter methods\n public override on<K extends keyof KeepAliveEvents>(\n event: K,\n listener: KeepAliveEvents[K],\n ): this {\n return super.on(event, listener as (...args: unknown[]) => void);\n }\n\n public override once<K extends keyof KeepAliveEvents>(\n event: K,\n listener: KeepAliveEvents[K],\n ): this {\n return super.once(event, listener as (...args: unknown[]) => void);\n }\n\n public override off<K extends keyof KeepAliveEvents>(\n event: K,\n listener: KeepAliveEvents[K],\n ): this {\n return super.off(event, listener as (...args: unknown[]) => void);\n }\n\n public override emit<K extends keyof KeepAliveEvents>(\n event: K,\n ...args: Parameters<KeepAliveEvents[K]>\n ): boolean {\n return super.emit(event, ...args);\n }\n}\n","import { EventEmitter } from 'node:events';\nimport {\n KeepAliveConfig,\n KeepAliveEvents,\n MultiKeepAliveConfig,\n PingResult,\n RetryInfo,\n} from './types.js';\nimport { KeepAlive } from './keepalive.js';\nimport { Logger } from './logger.js';\n\nexport class MultiKeepAlive extends EventEmitter {\n private services: KeepAlive[] = [];\n private serviceMap: Map<string, KeepAlive> = new Map();\n private logger: Logger | null = null;\n\n constructor(options: MultiKeepAliveConfig) {\n super();\n\n if (!options || !Array.isArray(options.services) || options.services.length === 0) {\n throw new TypeError(\n 'MultiKeepAlive requires a \"services\" array containing at least one service.',\n );\n }\n\n const { defaults = {}, logger, logLevel = 'normal' } = options;\n\n if (logger !== false) {\n if (logger && typeof logger === 'object') {\n this.logger = logger as Logger;\n } else {\n this.logger = new Logger({ logLevel, prefix: 'MultiKeepAlive' });\n }\n }\n\n for (const serviceConfig of options.services) {\n const mergedConfig: KeepAliveConfig = {\n ...defaults,\n ...serviceConfig,\n headers: {\n ...defaults.headers,\n ...serviceConfig.headers,\n },\n logLevel: serviceConfig.logLevel ?? defaults.logLevel ?? logLevel,\n logger: serviceConfig.logger !== undefined ? serviceConfig.logger : logger,\n };\n\n const instance = new KeepAlive(mergedConfig);\n const name = instance.getConfig().name;\n\n if (this.serviceMap.has(name)) {\n throw new Error(\n `Duplicate service name detected: \"${name}\". Each service must have a unique name.`,\n );\n }\n\n this.services.push(instance);\n this.serviceMap.set(name, instance);\n this.forwardEvents(instance);\n }\n }\n\n private forwardEvents(instance: KeepAlive): void {\n instance.on('start', (name: string) => this.emit('start', name));\n instance.on('stop', (name: string) => this.emit('stop', name));\n instance.on('ping', (info: { name: string; url: string; attempt: number }) =>\n this.emit('ping', info),\n );\n instance.on('success', (result: PingResult) => this.emit('success', result));\n instance.on('failure', (result: PingResult) => this.emit('failure', result));\n instance.on('retry', (info: RetryInfo) => this.emit('retry', info));\n instance.on('error', (err: Error, name: string) => this.emit('error', err, name));\n }\n\n /**\n * Starts all configured services.\n */\n public start(): this {\n this.logger?.info(`Starting keep-alive scheduler for ${this.services.length} services...`);\n for (const service of this.services) {\n service.start();\n }\n return this;\n }\n\n /**\n * Stops all running services.\n */\n public async stop(): Promise<void> {\n this.logger?.info(`Stopping all services...`);\n await Promise.all(this.services.map(s => s.stop()));\n this.logger?.info(`All services stopped successfully.`);\n }\n\n /**\n * Pings all services once in parallel and returns their results.\n */\n public async pingOnce(): Promise<PingResult[]> {\n return Promise.all(this.services.map(s => s.pingOnce()));\n }\n\n /**\n * Returns whether any of the services are currently running.\n */\n public isRunning(): boolean {\n return this.services.some(s => s.isRunning());\n }\n\n /**\n * Returns the list of all registered KeepAlive instances.\n */\n public getServices(): KeepAlive[] {\n return [...this.services];\n }\n\n /**\n * Returns a specific KeepAlive instance by service name.\n */\n public getService(name: string): KeepAlive | undefined {\n return this.serviceMap.get(name);\n }\n\n // Type-safe event emitter methods\n public override on<K extends keyof KeepAliveEvents>(\n event: K,\n listener: KeepAliveEvents[K],\n ): this {\n return super.on(event, listener as (...args: unknown[]) => void);\n }\n\n public override once<K extends keyof KeepAliveEvents>(\n event: K,\n listener: KeepAliveEvents[K],\n ): this {\n return super.once(event, listener as (...args: unknown[]) => void);\n }\n\n public override off<K extends keyof KeepAliveEvents>(\n event: K,\n listener: KeepAliveEvents[K],\n ): this {\n return super.off(event, listener as (...args: unknown[]) => void);\n }\n\n public override emit<K extends keyof KeepAliveEvents>(\n event: K,\n ...args: Parameters<KeepAliveEvents[K]>\n ): boolean {\n return super.emit(event, ...args);\n }\n}\n","import { readFileSync, existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport {\n CliOptions,\n HttpMethod,\n KeepAliveConfig,\n LogLevel,\n MultiKeepAliveConfig,\n} from './types.js';\n\nconst CONFIG_CANDIDATES = [\n 'keepalive.config.json',\n '.keepaliverc.json',\n '.keepaliverc',\n 'keepalive.config.js',\n 'keepalive.config.mjs',\n 'keepalive.config.cjs',\n];\n\nexport interface LoadedConfig {\n services: KeepAliveConfig[];\n defaults?: Partial<KeepAliveConfig>;\n logLevel?: LogLevel;\n}\n\n/**\n * Parses header strings in \"Key: Value\" or \"Key=Value\" format.\n */\nexport function parseHeaderPairs(headers: string[] | undefined): Record<string, string> {\n if (!headers || !Array.isArray(headers)) return {};\n\n const result: Record<string, string> = {};\n for (const item of headers) {\n const separatorIdx = item.indexOf(':') !== -1 ? item.indexOf(':') : item.indexOf('=');\n if (separatorIdx === -1) {\n throw new Error(\n `Invalid header format \"${item}\". Expected format \"Header-Name: Value\" or \"Header-Name=Value\".`,\n );\n }\n const key = item.substring(0, separatorIdx).trim();\n const val = item.substring(separatorIdx + 1).trim();\n if (!key) {\n throw new Error(`Header key cannot be empty in \"${item}\".`);\n }\n result[key] = val;\n }\n return result;\n}\n\n/**\n * Loads configuration from a file path.\n */\nexport async function loadConfigFile(customPath?: string): Promise<LoadedConfig | null> {\n let targetPath: string | null = null;\n\n if (customPath) {\n const resolved = resolve(process.cwd(), customPath);\n if (!existsSync(resolved)) {\n throw new Error(`Config file not found at: ${resolved}`);\n }\n targetPath = resolved;\n } else {\n for (const candidate of CONFIG_CANDIDATES) {\n const candidatePath = resolve(process.cwd(), candidate);\n if (existsSync(candidatePath)) {\n targetPath = candidatePath;\n break;\n }\n }\n }\n\n if (!targetPath) return null;\n\n try {\n if (targetPath.endsWith('.json') || targetPath.endsWith('.keepaliverc')) {\n const raw = readFileSync(targetPath, 'utf-8');\n const parsed = JSON.parse(raw);\n return normalizeRawConfig(parsed);\n }\n\n if (targetPath.endsWith('.js') || targetPath.endsWith('.mjs') || targetPath.endsWith('.cjs')) {\n const moduleUrl = pathToFileURL(targetPath).href;\n const imported = await import(moduleUrl);\n const config = imported.default || imported;\n return normalizeRawConfig(config);\n }\n\n throw new Error(`Unsupported configuration file format: ${targetPath}`);\n } catch (err) {\n throw new Error(\n `Failed to parse configuration file \"${targetPath}\": ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n}\n\n/**\n * Normalizes raw config object into LoadedConfig format.\n */\nexport function normalizeRawConfig(raw: unknown): LoadedConfig {\n if (!raw || typeof raw !== 'object') {\n throw new Error('Configuration must be a valid JSON or JS object.');\n }\n\n const obj = raw as Record<string, unknown>;\n\n // Multiple services format: { services: [...] }\n if (Array.isArray(obj['services'])) {\n const services = obj['services'] as KeepAliveConfig[];\n if (services.length === 0) {\n throw new Error('Config \"services\" array cannot be empty.');\n }\n return {\n services,\n defaults: (obj['defaults'] as Partial<KeepAliveConfig>) || undefined,\n logLevel: (obj['logLevel'] as LogLevel) || undefined,\n };\n }\n\n // Single service format: { url: '...' }\n if (typeof obj['url'] === 'string') {\n return {\n services: [obj as unknown as KeepAliveConfig],\n logLevel: (obj['logLevel'] as LogLevel) || undefined,\n };\n }\n\n throw new Error(\n 'Configuration must contain either a \"url\" property or a \"services\" array of target endpoints.',\n );\n}\n\n/**\n * Reads environment variables into a partial KeepAliveConfig.\n */\nexport function loadEnvConfig(): Partial<KeepAliveConfig> {\n const env = process.env;\n const config: Partial<KeepAliveConfig> = {};\n\n if (env['KEEPALIVE_URL']) config.url = env['KEEPALIVE_URL'];\n if (env['KEEPALIVE_INTERVAL']) config.interval = env['KEEPALIVE_INTERVAL'];\n if (env['KEEPALIVE_TIMEOUT']) config.timeout = env['KEEPALIVE_TIMEOUT'];\n if (env['KEEPALIVE_METHOD']) config.method = env['KEEPALIVE_METHOD'].toUpperCase() as HttpMethod;\n if (env['KEEPALIVE_RETRIES']) config.retries = parseInt(env['KEEPALIVE_RETRIES'], 10);\n if (env['KEEPALIVE_RETRY_DELAY']) config.retryDelay = env['KEEPALIVE_RETRY_DELAY'];\n\n if (env['KEEPALIVE_HEADERS']) {\n try {\n config.headers = JSON.parse(env['KEEPALIVE_HEADERS']);\n } catch {\n // If not JSON, try key=value,key=value\n const pairs = env['KEEPALIVE_HEADERS'].split(',').map(s => s.trim());\n config.headers = parseHeaderPairs(pairs);\n }\n }\n\n if (env['KEEPALIVE_QUIET'] === 'true' || env['KEEPALIVE_QUIET'] === '1') {\n config.logLevel = 'quiet';\n } else if (env['KEEPALIVE_VERBOSE'] === 'true' || env['KEEPALIVE_VERBOSE'] === '1') {\n config.logLevel = 'verbose';\n }\n\n return config;\n}\n\n/**\n * Resolves complete runtime configuration from CLI flags, config file, and env variables.\n */\nexport async function resolveRuntimeConfig(\n cliOptions: CliOptions,\n): Promise<MultiKeepAliveConfig | KeepAliveConfig> {\n const fileConfig = await loadConfigFile(cliOptions.config || process.env['KEEPALIVE_CONFIG']);\n const envConfig = loadEnvConfig();\n\n // Determine active log level\n let logLevel: LogLevel = 'normal';\n if (cliOptions.quiet) {\n logLevel = 'quiet';\n } else if (cliOptions.verbose) {\n logLevel = 'verbose';\n } else if (fileConfig?.logLevel) {\n logLevel = fileConfig.logLevel;\n } else if (envConfig.logLevel) {\n logLevel = envConfig.logLevel;\n }\n\n // Parse CLI headers\n const cliHeaders = parseHeaderPairs(cliOptions.headers);\n\n // If a multi-service config file was found and no single CLI --url was specified\n if (fileConfig && fileConfig.services.length > 1 && !cliOptions.url) {\n return {\n services: fileConfig.services,\n defaults: {\n ...fileConfig.defaults,\n logLevel,\n },\n logLevel,\n };\n }\n\n // Single target resolution: CLI > File (first service) > Env > Default\n const primaryServiceFromFile = fileConfig?.services[0];\n\n const targetUrl = cliOptions.url || primaryServiceFromFile?.url || envConfig.url;\n\n if (!targetUrl) {\n throw new Error(\n 'Missing target URL. Provide --url <url>, set KEEPALIVE_URL, or define a config file.',\n );\n }\n\n const interval =\n cliOptions.interval || primaryServiceFromFile?.interval || envConfig.interval || '10m';\n\n const timeout =\n cliOptions.timeout || primaryServiceFromFile?.timeout || envConfig.timeout || '30s';\n\n const method = (\n cliOptions.method ||\n primaryServiceFromFile?.method ||\n envConfig.method ||\n 'GET'\n ).toUpperCase() as HttpMethod;\n\n const retries =\n cliOptions.retries !== undefined\n ? typeof cliOptions.retries === 'string'\n ? parseInt(cliOptions.retries, 10)\n : cliOptions.retries\n : primaryServiceFromFile?.retries !== undefined\n ? primaryServiceFromFile.retries\n : envConfig.retries !== undefined\n ? envConfig.retries\n : 3;\n\n const retryDelay =\n cliOptions.retryDelay || primaryServiceFromFile?.retryDelay || envConfig.retryDelay || '5s';\n\n const headers: Record<string, string> = {\n ...(envConfig.headers ?? {}),\n ...(fileConfig?.defaults?.headers ?? {}),\n ...(primaryServiceFromFile?.headers ?? {}),\n ...cliHeaders,\n };\n\n const name = primaryServiceFromFile?.name;\n\n return {\n url: targetUrl,\n name,\n interval,\n timeout,\n method,\n headers,\n retries,\n retryDelay,\n logLevel,\n };\n}\n","import { CliOptions } from './types.js';\nimport { resolveRuntimeConfig } from './config.js';\nimport { KeepAlive } from './keepalive.js';\nimport { MultiKeepAlive } from './multi-keepalive.js';\n\nconst VERSION = '1.0.0';\n\nexport function parseArgs(argv: string[]): CliOptions {\n const options: CliOptions = {\n headers: [],\n };\n\n const args = argv.slice(2);\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (!arg) continue;\n\n if (arg === '-h' || arg === '--help') {\n options.help = true;\n } else if (arg === '-V' || arg === '--version') {\n options.version = true;\n } else if (arg === '-q' || arg === '--quiet') {\n options.quiet = true;\n } else if (arg === '-v' || arg === '--verbose') {\n options.verbose = true;\n } else if (arg === '--once') {\n options.once = true;\n } else if (arg === '-u' || arg === '--url') {\n options.url = args[++i];\n } else if (arg.startsWith('--url=')) {\n options.url = arg.split('=')[1];\n } else if (arg === '-i' || arg === '--interval') {\n options.interval = args[++i];\n } else if (arg.startsWith('--interval=')) {\n options.interval = arg.split('=')[1];\n } else if (arg === '-t' || arg === '--timeout') {\n options.timeout = args[++i];\n } else if (arg.startsWith('--timeout=')) {\n options.timeout = arg.split('=')[1];\n } else if (arg === '-m' || arg === '--method') {\n options.method = args[++i];\n } else if (arg.startsWith('--method=')) {\n options.method = arg.split('=')[1];\n } else if (arg === '-r' || arg === '--retries') {\n options.retries = args[++i];\n } else if (arg.startsWith('--retries=')) {\n options.retries = arg.split('=')[1];\n } else if (arg === '--retry-delay') {\n options.retryDelay = args[++i];\n } else if (arg.startsWith('--retry-delay=')) {\n options.retryDelay = arg.split('=')[1];\n } else if (arg === '-H' || arg === '--header') {\n const headerVal = args[++i];\n if (headerVal) options.headers?.push(headerVal);\n } else if (arg.startsWith('--header=')) {\n const headerVal = arg.split('=')[1];\n if (headerVal) options.headers?.push(headerVal);\n } else if (arg === '-c' || arg === '--config') {\n options.config = args[++i];\n } else if (arg.startsWith('--config=')) {\n options.config = arg.split('=')[1];\n } else if (!arg.startsWith('-') && !options.url) {\n // Positional URL support: service-keepalive https://example.com/health\n options.url = arg;\n }\n }\n\n return options;\n}\n\nexport function printHelp(): void {\n console.log(`\n\\x1b[1m\\x1b[36mservice-keepalive\\x1b[0m v${VERSION}\nLightweight HTTP keep-alive utility to prevent idle spin-down on services with inbound traffic wakeups.\n\n\\x1b[1mUSAGE:\\x1b[0m\n $ npx service-keepalive [options]\n $ npx service-keepalive <url> [options]\n\n\\x1b[1mOPTIONS:\\x1b[0m\n -u, --url <url> Target service URL (e.g. https://example.onrender.com/health)\n -i, --interval <duration> Interval between pings (e.g. 10s, 1m, 5m, 10m, 1h) [default: 10m]\n -t, --timeout <duration> Request timeout duration (e.g. 10s, 30s, 1m) [default: 30s]\n -m, --method <method> HTTP method (GET, POST, HEAD, etc.) [default: GET]\n -r, --retries <number> Number of retry attempts on failure [default: 3]\n --retry-delay <duration> Base delay between retries [default: 5s]\n -H, --header <key:value> Custom request header (can be used multiple times)\n -c, --config <path> Path to JSON or JS config file [default: keepalive.config.json]\n --once Execute a single ping and exit (useful for cron jobs / CI)\n -q, --quiet Suppress standard output; only log failures\n -v, --verbose Enable verbose debug logging\n -V, --version Output version number\n -h, --help Display this help message\n\n\\x1b[1mEXAMPLES:\\x1b[0m\n $ npx service-keepalive --url https://api.example.com/health --interval 10m\n $ npx service-keepalive -u https://api.example.com/health -H \"Authorization: Bearer mytoken\"\n $ npx service-keepalive --config keepalive.config.json\n $ npx service-keepalive --url https://api.example.com/health --once\n\n\\x1b[1mENVIRONMENT VARIABLES:\\x1b[0m\n KEEPALIVE_URL, KEEPALIVE_INTERVAL, KEEPALIVE_TIMEOUT, KEEPALIVE_METHOD,\n KEEPALIVE_RETRIES, KEEPALIVE_HEADERS, KEEPALIVE_CONFIG, KEEPALIVE_QUIET, KEEPALIVE_VERBOSE\n\n\\x1b[1mNOTE:\\x1b[0m\n This tool runs externally (on your machine, VPS, Docker container, or CI runner).\n Always ensure compliance with your hosting provider's Terms of Service.\n`);\n}\n\nexport async function runCli(argv = process.argv): Promise<number> {\n const options = parseArgs(argv);\n\n if (options.help) {\n printHelp();\n return 0;\n }\n\n if (options.version) {\n console.log(`service-keepalive v${VERSION}`);\n return 0;\n }\n\n try {\n const config = await resolveRuntimeConfig(options);\n\n let runner: KeepAlive | MultiKeepAlive;\n\n if ('services' in config) {\n runner = new MultiKeepAlive(config);\n } else {\n runner = new KeepAlive(config);\n }\n\n // Graceful termination handling\n let isShuttingDown = false;\n const shutdown = async (signal: string) => {\n if (isShuttingDown) return;\n isShuttingDown = true;\n console.log(`\\nReceived ${signal}. Stopping keep-alive...`);\n await runner.stop();\n console.log('Stopped successfully.');\n process.exit(0);\n };\n\n process.once('SIGINT', () => void shutdown('SIGINT'));\n process.once('SIGTERM', () => void shutdown('SIGTERM'));\n\n // Handle single-ping execution mode\n if (options.once) {\n if (runner instanceof MultiKeepAlive) {\n const results = await runner.pingOnce();\n const allOk = results.every(r => r.ok);\n return allOk ? 0 : 1;\n } else {\n const result = await runner.pingOnce();\n return result.ok ? 0 : 1;\n }\n }\n\n // Continuous running mode\n runner.start();\n\n // Return a promise that stays active until process receives a termination signal\n return new Promise<number>(() => {\n // Keep running\n });\n } catch (err) {\n console.error(`\\x1b[31mError:\\x1b[0m ${err instanceof Error ? err.message : String(err)}`);\n return 1;\n }\n}\n"]}
@@ -0,0 +1,375 @@
1
+ import { EventEmitter } from 'node:events';
2
+
3
+ /**
4
+ * Supported HTTP methods for keep-alive pings.
5
+ */
6
+ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
7
+ /**
8
+ * Strategy for calculating delays between retry attempts.
9
+ */
10
+ type RetryStrategy = 'exponential' | 'linear' | 'fixed';
11
+ /**
12
+ * Logging verbosity levels.
13
+ */
14
+ type LogLevel = 'quiet' | 'normal' | 'verbose';
15
+ /**
16
+ * Custom logger interface.
17
+ */
18
+ interface LoggerInterface {
19
+ info(message: string, ...args: unknown[]): void;
20
+ success(message: string, ...args: unknown[]): void;
21
+ warn(message: string, ...args: unknown[]): void;
22
+ error(message: string, ...args: unknown[]): void;
23
+ debug(message: string, ...args: unknown[]): void;
24
+ }
25
+ /**
26
+ * Result of an individual HTTP ping execution.
27
+ */
28
+ interface PingResult {
29
+ /** Identifier of the service pinged */
30
+ serviceName: string;
31
+ /** Target URL */
32
+ url: string;
33
+ /** HTTP method used */
34
+ method: HttpMethod;
35
+ /** HTTP response status code (0 if network error / timeout) */
36
+ status: number;
37
+ /** HTTP response status text */
38
+ statusText: string;
39
+ /** Whether the ping was deemed successful */
40
+ ok: boolean;
41
+ /** Round-trip duration in milliseconds */
42
+ durationMs: number;
43
+ /** Which attempt number succeeded or failed (1-indexed) */
44
+ attempt: number;
45
+ /** ISO timestamp when the ping was executed */
46
+ timestamp: Date;
47
+ /** Error message if request failed */
48
+ error?: string;
49
+ /** Sanitized response headers if available and requested */
50
+ headers?: Record<string, string>;
51
+ }
52
+ /**
53
+ * Information passed during a retry event.
54
+ */
55
+ interface RetryInfo {
56
+ serviceName: string;
57
+ url: string;
58
+ attempt: number;
59
+ maxRetries: number;
60
+ delayMs: number;
61
+ error: string;
62
+ }
63
+ /**
64
+ * Configuration options for an individual KeepAlive target.
65
+ */
66
+ interface KeepAliveConfig {
67
+ /** Target service URL to ping (must be a valid http or https URL) */
68
+ url: string;
69
+ /** Optional friendly name for the service (defaults to URL hostname) */
70
+ name?: string;
71
+ /** Interval between consecutive pings (e.g. '10m', '30s', '1h', or number in ms). Default: '10m' */
72
+ interval?: string | number;
73
+ /** Request timeout duration (e.g. '30s', '10s', or number in ms). Default: '30s' */
74
+ timeout?: string | number;
75
+ /** HTTP method to use. Default: 'GET' */
76
+ method?: HttpMethod;
77
+ /** Custom request headers */
78
+ headers?: Record<string, string>;
79
+ /** Optional request body payload (for POST/PUT requests) */
80
+ body?: string | null;
81
+ /** Number of retry attempts on failure. Default: 3 */
82
+ retries?: number;
83
+ /** Base delay between retries (e.g. '5s', '1000ms'). Default: '5s' */
84
+ retryDelay?: string | number;
85
+ /** Backoff strategy for retries. Default: 'exponential' */
86
+ retryStrategy?: RetryStrategy;
87
+ /** Whether to add random jitter to retry delays. Default: true */
88
+ retryJitter?: boolean;
89
+ /** Maximum upper bound for retry delay. Default: '60s' */
90
+ maxRetryDelay?: string | number;
91
+ /**
92
+ * Status code(s) considered successful.
93
+ * Can be an array of status codes or a predicate function.
94
+ * Default: any 2xx status (200-299)
95
+ */
96
+ expectedStatusCodes?: number[] | ((status: number) => boolean);
97
+ /** Custom logger or false to disable logging. Default: built-in console logger */
98
+ logger?: LoggerInterface | false;
99
+ /** Output verbosity level. Default: 'normal' */
100
+ logLevel?: LogLevel;
101
+ /** Whether the underlying timer should not prevent the Node process from exiting. Default: false */
102
+ unrefTimer?: boolean;
103
+ }
104
+ /**
105
+ * Configuration options for managing multiple services.
106
+ */
107
+ interface MultiKeepAliveConfig {
108
+ /** List of service configurations to keep alive */
109
+ services: KeepAliveConfig[];
110
+ /** Default options applied to all services unless explicitly overridden */
111
+ defaults?: Partial<KeepAliveConfig>;
112
+ /** Global logger or false */
113
+ logger?: LoggerInterface | false;
114
+ /** Global log level */
115
+ logLevel?: LogLevel;
116
+ }
117
+ /**
118
+ * Resolved internal configuration with guaranteed types and parsed milliseconds.
119
+ */
120
+ interface ResolvedServiceConfig {
121
+ name: string;
122
+ url: string;
123
+ intervalMs: number;
124
+ timeoutMs: number;
125
+ method: HttpMethod;
126
+ headers: Record<string, string>;
127
+ body: string | null;
128
+ retries: number;
129
+ retryDelayMs: number;
130
+ retryStrategy: RetryStrategy;
131
+ retryJitter: boolean;
132
+ maxRetryDelayMs: number;
133
+ expectedStatusCodes: number[] | ((status: number) => boolean);
134
+ logger: LoggerInterface | null;
135
+ logLevel: LogLevel;
136
+ unrefTimer: boolean;
137
+ }
138
+ /**
139
+ * CLI Options parsed from command line flags.
140
+ */
141
+ interface CliOptions {
142
+ url?: string;
143
+ interval?: string;
144
+ timeout?: string;
145
+ method?: string;
146
+ retries?: string | number;
147
+ retryDelay?: string;
148
+ headers?: string[];
149
+ config?: string;
150
+ quiet?: boolean;
151
+ verbose?: boolean;
152
+ once?: boolean;
153
+ help?: boolean;
154
+ version?: boolean;
155
+ }
156
+ /**
157
+ * Events emitted by the KeepAlive instance.
158
+ */
159
+ interface KeepAliveEvents {
160
+ start: (serviceName: string) => void;
161
+ stop: (serviceName: string) => void;
162
+ ping: (info: {
163
+ name: string;
164
+ url: string;
165
+ attempt: number;
166
+ }) => void;
167
+ success: (result: PingResult) => void;
168
+ failure: (result: PingResult) => void;
169
+ retry: (info: RetryInfo) => void;
170
+ error: (error: Error, serviceName: string) => void;
171
+ }
172
+
173
+ declare class KeepAlive extends EventEmitter {
174
+ private config;
175
+ private running;
176
+ private timer;
177
+ private inFlightAbortController;
178
+ private logger;
179
+ constructor(options: KeepAliveConfig);
180
+ private resolveConfig;
181
+ /**
182
+ * Returns whether the keep-alive scheduler is actively running.
183
+ */
184
+ isRunning(): boolean;
185
+ /**
186
+ * Returns the resolved service configuration.
187
+ */
188
+ getConfig(): Readonly<ResolvedServiceConfig>;
189
+ /**
190
+ * Starts the keep-alive scheduler.
191
+ * Performs an immediate ping, then continues at the configured interval.
192
+ */
193
+ start(): this;
194
+ /**
195
+ * Stops the keep-alive scheduler and aborts any active requests or wait timers.
196
+ */
197
+ stop(): Promise<void>;
198
+ /**
199
+ * Executes a single ping cycle with retries without starting the recurring scheduler.
200
+ */
201
+ pingOnce(): Promise<PingResult>;
202
+ /**
203
+ * Core scheduling loop. Executes a ping cycle, then schedules the next interval.
204
+ */
205
+ private runPingLoop;
206
+ /**
207
+ * Executes the ping request, retrying on failure up to configured retry attempts.
208
+ */
209
+ private executePingWithRetries;
210
+ on<K extends keyof KeepAliveEvents>(event: K, listener: KeepAliveEvents[K]): this;
211
+ once<K extends keyof KeepAliveEvents>(event: K, listener: KeepAliveEvents[K]): this;
212
+ off<K extends keyof KeepAliveEvents>(event: K, listener: KeepAliveEvents[K]): this;
213
+ emit<K extends keyof KeepAliveEvents>(event: K, ...args: Parameters<KeepAliveEvents[K]>): boolean;
214
+ }
215
+
216
+ declare class MultiKeepAlive extends EventEmitter {
217
+ private services;
218
+ private serviceMap;
219
+ private logger;
220
+ constructor(options: MultiKeepAliveConfig);
221
+ private forwardEvents;
222
+ /**
223
+ * Starts all configured services.
224
+ */
225
+ start(): this;
226
+ /**
227
+ * Stops all running services.
228
+ */
229
+ stop(): Promise<void>;
230
+ /**
231
+ * Pings all services once in parallel and returns their results.
232
+ */
233
+ pingOnce(): Promise<PingResult[]>;
234
+ /**
235
+ * Returns whether any of the services are currently running.
236
+ */
237
+ isRunning(): boolean;
238
+ /**
239
+ * Returns the list of all registered KeepAlive instances.
240
+ */
241
+ getServices(): KeepAlive[];
242
+ /**
243
+ * Returns a specific KeepAlive instance by service name.
244
+ */
245
+ getService(name: string): KeepAlive | undefined;
246
+ on<K extends keyof KeepAliveEvents>(event: K, listener: KeepAliveEvents[K]): this;
247
+ once<K extends keyof KeepAliveEvents>(event: K, listener: KeepAliveEvents[K]): this;
248
+ off<K extends keyof KeepAliveEvents>(event: K, listener: KeepAliveEvents[K]): this;
249
+ emit<K extends keyof KeepAliveEvents>(event: K, ...args: Parameters<KeepAliveEvents[K]>): boolean;
250
+ }
251
+
252
+ interface ExecutePingOptions {
253
+ serviceName: string;
254
+ url: string;
255
+ method: HttpMethod;
256
+ headers?: Record<string, string>;
257
+ body?: string | null;
258
+ timeoutMs: number;
259
+ attempt?: number;
260
+ expectedStatusCodes?: number[] | ((status: number) => boolean);
261
+ externalSignal?: AbortSignal;
262
+ }
263
+ /**
264
+ * Checks whether an HTTP status code is considered successful.
265
+ */
266
+ declare function isStatusSuccessful(status: number, expected?: number[] | ((status: number) => boolean)): boolean;
267
+ /**
268
+ * Executes a single HTTP ping request with timeout and cancellation protection.
269
+ */
270
+ declare function executePing(options: ExecutePingOptions): Promise<PingResult>;
271
+
272
+ /**
273
+ * Parses a human-readable duration string or millisecond number into milliseconds.
274
+ *
275
+ * Supported formats:
276
+ * - Number: `5000` (treated as 5000ms)
277
+ * - String: `'10s'`, `'30s'`, `'1m'`, `'5m'`, `'10m'`, `'1h'`, `'500ms'`, `'1m30s'`
278
+ *
279
+ * @throws {TypeError | RangeError} If the duration is invalid, zero, or negative.
280
+ */
281
+ declare function parseDuration(value: string | number, fieldName?: string): number;
282
+ /**
283
+ * Formats a duration in milliseconds into a concise human-readable string.
284
+ *
285
+ * Examples:
286
+ * - `142` -> `'142ms'`
287
+ * - `5000` -> `'5s'`
288
+ * - `60000` -> `'1m'`
289
+ * - `90000` -> `'1m 30s'`
290
+ * - `3600000` -> `'1h'`
291
+ */
292
+ declare function formatDuration(ms: number): string;
293
+
294
+ interface BackoffOptions {
295
+ attempt: number;
296
+ baseDelayMs: number;
297
+ strategy?: RetryStrategy;
298
+ maxDelayMs?: number;
299
+ jitter?: boolean;
300
+ }
301
+ /**
302
+ * Calculates the backoff delay in milliseconds for a given attempt.
303
+ *
304
+ * @param options Calculation parameters
305
+ * @returns Delay in milliseconds
306
+ */
307
+ declare function calculateBackoff(options: BackoffOptions): number;
308
+ /**
309
+ * Asynchronously sleeps for the given duration, cancellable via AbortSignal.
310
+ *
311
+ * @param ms Duration in milliseconds
312
+ * @param signal Optional AbortSignal to cancel waiting
313
+ */
314
+ declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
315
+
316
+ /**
317
+ * Returns a shallow copy of headers with sensitive values masked.
318
+ */
319
+ declare function redactHeaders(headers?: Record<string, string> | null): Record<string, string>;
320
+ /**
321
+ * Masks sensitive query parameters in a URL string for safe logging.
322
+ */
323
+ declare function redactUrl(urlStr: string): string;
324
+
325
+ declare function formatTimestamp(date?: Date): string;
326
+ declare class Logger implements LoggerInterface {
327
+ private logLevel;
328
+ private prefix?;
329
+ constructor(options?: {
330
+ logLevel?: LogLevel;
331
+ prefix?: string;
332
+ });
333
+ setLevel(level: LogLevel): void;
334
+ setPrefix(prefix: string | undefined): void;
335
+ private shouldLog;
336
+ private formatLine;
337
+ info(message: string, ...args: unknown[]): void;
338
+ success(message: string, ...args: unknown[]): void;
339
+ warn(message: string, ...args: unknown[]): void;
340
+ error(message: string, ...args: unknown[]): void;
341
+ retry(message: string, ...args: unknown[]): void;
342
+ debug(message: string, ...args: unknown[]): void;
343
+ }
344
+
345
+ interface LoadedConfig {
346
+ services: KeepAliveConfig[];
347
+ defaults?: Partial<KeepAliveConfig>;
348
+ logLevel?: LogLevel;
349
+ }
350
+ /**
351
+ * Parses header strings in "Key: Value" or "Key=Value" format.
352
+ */
353
+ declare function parseHeaderPairs(headers: string[] | undefined): Record<string, string>;
354
+ /**
355
+ * Loads configuration from a file path.
356
+ */
357
+ declare function loadConfigFile(customPath?: string): Promise<LoadedConfig | null>;
358
+ /**
359
+ * Normalizes raw config object into LoadedConfig format.
360
+ */
361
+ declare function normalizeRawConfig(raw: unknown): LoadedConfig;
362
+ /**
363
+ * Reads environment variables into a partial KeepAliveConfig.
364
+ */
365
+ declare function loadEnvConfig(): Partial<KeepAliveConfig>;
366
+ /**
367
+ * Resolves complete runtime configuration from CLI flags, config file, and env variables.
368
+ */
369
+ declare function resolveRuntimeConfig(cliOptions: CliOptions): Promise<MultiKeepAliveConfig | KeepAliveConfig>;
370
+
371
+ declare function parseArgs(argv: string[]): CliOptions;
372
+ declare function printHelp(): void;
373
+ declare function runCli(argv?: string[]): Promise<number>;
374
+
375
+ export { type BackoffOptions, type CliOptions, type ExecutePingOptions, type HttpMethod, KeepAlive, type KeepAliveConfig, type KeepAliveEvents, type LoadedConfig, type LogLevel, Logger, type LoggerInterface, MultiKeepAlive, type MultiKeepAliveConfig, type PingResult, type ResolvedServiceConfig, type RetryInfo, type RetryStrategy, calculateBackoff, executePing, formatDuration, formatTimestamp, isStatusSuccessful, loadConfigFile, loadEnvConfig, normalizeRawConfig, parseArgs, parseDuration, parseHeaderPairs, printHelp, redactHeaders, redactUrl, resolveRuntimeConfig, runCli, sleep };