46 lines
1.6 KiB
TypeScript
46 lines
1.6 KiB
TypeScript
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<typeof envSchema>["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<string, string | undefined>): 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",
|
|
};
|
|
}
|