import path from "path"; import dotenv from "dotenv"; dotenv.config({ path: path.resolve(__dirname, "../../.env") }); function requireEnv(name: string): string { const value = process.env[name]; if (!value) { throw new Error(`Missing required environment variable: ${name}`); } return value; } function optionalEnv(name: string): string | null { const value = process.env[name]?.trim(); return value ? value : null; } function requireEnvUnlessMock(name: string, fallback: string): string { if (useMockDb) { return process.env[name]?.trim() || fallback; } return requireEnv(name); } function parseBoolean(value: string | undefined, fallback: boolean): boolean { if (value == null || value.trim() === "") { return fallback; } return value === "1" || value.toLowerCase() === "true"; } const useMockDb = process.env.CALENDAR_RUN_MOCK_DB === "1" || process.env.CALENDAR_RUN_MOCK_DB?.toLowerCase() === "true"; export const config = { useMockDb, db: useMockDb ? { host: "mock", port: 5432, database: "mock", user: "mock", password: "mock", } : { host: requireEnv("DB_HOST"), port: parseInt(requireEnv("DB_PORT"), 10), database: requireEnv("DB_NAME"), user: requireEnv("DB_USER"), password: requireEnv("DB_PASSWORD"), }, apiPort: parseInt(process.env.PORT || process.env.API_PORT || "3001", 10), /** Одно значение или несколько через запятую (прод: https://домен) */ corsOrigin: parseCorsOrigins(), appBaseUrl: process.env.APP_BASE_URL?.trim() || "http://localhost:5173", session: { secret: requireEnvUnlessMock("SESSION_SECRET", "mock-session-secret-change-me"), cookieName: process.env.SESSION_COOKIE_NAME?.trim() || (process.env.NODE_ENV === "production" ? "__Host-sid" : "sid"), secure: parseBoolean(process.env.SESSION_COOKIE_SECURE, process.env.NODE_ENV === "production"), ttlDays: parseInt(process.env.SESSION_TTL_DAYS || "30", 10), }, smtp: { host: optionalEnv("SMTP_HOST"), port: parseInt(process.env.SMTP_PORT || "587", 10), secure: parseBoolean(process.env.SMTP_SECURE, false), user: optionalEnv("SMTP_USER"), password: optionalEnv("SMTP_PASSWORD"), from: process.env.SMTP_FROM?.trim() || "Calendar Run ", }, turnstile: { secretKey: process.env.TURNSTILE_SECRET_KEY?.trim() || (useMockDb ? "mock-turnstile-secret" : ""), bypassToken: process.env.TURNSTILE_BYPASS_TOKEN?.trim() || (useMockDb ? "mock-turnstile-token" : ""), }, securityProfile: process.env.SECURITY_PROFILE?.trim() || process.env.NODE_ENV || "development", }; function parseCorsOrigins(): string | string[] { const raw = process.env.CORS_ORIGIN?.trim(); if (!raw) { return "http://localhost:5173"; } const parts = raw.split(",").map((s) => s.trim()).filter(Boolean); if (parts.length === 0) { return "http://localhost:5173"; } if (parts.length === 1) { return parts[0]!; } return parts; }