import { z } from "zod"; /** Server settings from environment variables (see `.env.example`). */ const envSchema = z.object({ NODE_ENV: z.enum(["development", "test", "production"]).default("development"), PORT: z.coerce.number().int().min(0).max(65535).default(3000), LOG_LEVEL: z.enum(["fatal", "error", "warn", "info", "debug", "trace", "silent"]).default("info"), DATABASE_URL: z.url(), TEST_DATABASE_URL: z.url().optional(), BETTER_AUTH_SECRET: z.string().min(32), BETTER_AUTH_URL: z.url(), /** Run background job workers in this process (Step 7.1). */ WORKERS_ENABLED: z.enum(["true", "false"]).default("true"), }); export interface ServerConfig { env: "development" | "test" | "production"; port: number; logLevel: z.infer["LOG_LEVEL"]; databaseUrl: string; testDatabaseUrl: string | undefined; authSecret: string; authUrl: string; workersEnabled: boolean; } /** Validates the environment, throwing one error that lists every problem. */ export function loadConfig(env: Record): ServerConfig { const result = envSchema.safeParse(env); if (!result.success) { const problems = result.error.issues.map((i) => ` ${i.path.join(".")}: ${i.message}`); throw new Error(`Invalid server environment:\n${problems.join("\n")}`); } const e = result.data; return { env: e.NODE_ENV, port: e.PORT, logLevel: e.LOG_LEVEL, databaseUrl: e.DATABASE_URL, testDatabaseUrl: e.TEST_DATABASE_URL, authSecret: e.BETTER_AUTH_SECRET, authUrl: e.BETTER_AUTH_URL, workersEnabled: e.WORKERS_ENABLED === "true", }; }