Files
runners-calendar/backend/src/config.ts
2026-05-21 00:01:35 +03:00

95 lines
3.0 KiB
TypeScript

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 <no-reply@example.com>",
},
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;
}