import 'dotenv/config'; import type { ProxyConfig } from './types.js'; /** * Reads a required environment variable or aborts the process. */ function requireEnv(name: string): string { const value = process.env[name]?.trim(); if (!value) { console.error(`[FATAL] Missing required environment variable: ${name}`); process.exit(1); } return value; } /** * Reads an optional environment variable with a fallback default. */ function optionalEnv(name: string, fallback: string): string { return process.env[name]?.trim() || fallback; } /** * Parses and validates all environment variables into a typed, frozen config object. * Aborts the process immediately if required variables are missing. */ export function loadConfig(): ProxyConfig { const config: ProxyConfig = { anthropicApiKey: process.env['ANTHROPIC_API_KEY']?.trim() || undefined, proxyAuthToken: requireEnv('PROXY_AUTH_TOKEN'), port: parseInt(optionalEnv('PORT', '7860'), 10), host: optionalEnv('HOST', '0.0.0.0'), logLevel: optionalEnv('LOG_LEVEL', 'info'), rateLimitMax: parseInt(optionalEnv('RATE_LIMIT_MAX', '100'), 10), rateLimitWindowMs: parseInt(optionalEnv('RATE_LIMIT_WINDOW_MS', '60000'), 10), bodyLimit: parseInt(optionalEnv('BODY_LIMIT', '5242880'), 10), corsOrigin: optionalEnv('CORS_ORIGIN', ''), anthropicBaseUrl: optionalEnv('ANTHROPIC_BASE_URL', 'https://api.anthropic.com'), upstreamTimeoutMs: parseInt(optionalEnv('UPSTREAM_TIMEOUT_MS', '300000'), 10), geminiApiKey: process.env['GEMINI_API_KEY']?.trim() || undefined, geminiBaseUrl: optionalEnv('GEMINI_BASE_URL', 'https://generativelanguage.googleapis.com'), }; // At least one provider must be configured if (!config.anthropicApiKey && !config.geminiApiKey) { console.error('[FATAL] At least one provider API key must be set (ANTHROPIC_API_KEY and/or GEMINI_API_KEY)'); process.exit(1); } // Validate numeric values if (isNaN(config.port) || config.port < 1 || config.port > 65535) { console.error(`[FATAL] Invalid PORT value: ${process.env['PORT']}`); process.exit(1); } return Object.freeze(config); }