import { z } from "zod"; const LogLevel = z.enum(["fatal", "error", "warn", "info", "debug", "trace", "silent"]); export const ConfigSchema = z.object({ NODE_ENV: z.enum(["development", "test", "production"]).default("development"), PORT: z.coerce.number().int().min(1).max(65535).default(4380), DATABASE_URL: z.string().regex(/^postgres(ql)?:\/\//, "必须是 postgres:// 连接串"), SECRET_MASTER_KEY: z.string().min(16, "SECRET_MASTER_KEY 至少 16 个字符"), LOG_LEVEL: LogLevel.default("info"), /** 仅开发模式生效的管理员 Key */ DEV_ADMIN_KEY: z.string().min(8).optional(), /** worker 心跳间隔 */ WORKER_HEARTBEAT_MS: z.coerce.number().int().min(1000).default(30_000), }); export type Config = z.infer; /** 从环境变量加载并校验配置;失败时抛出可读错误(不含变量值) */ export function loadConfig(env: NodeJS.ProcessEnv = process.env): Config { const parsed = ConfigSchema.safeParse(env); if (!parsed.success) { const lines = parsed.error.issues.map((i) => ` ${i.path.join(".")}: ${i.message}`); throw new Error(`配置无效:\n${lines.join("\n")}`); } return parsed.data; } export const isDev = (c: Pick) => c.NODE_ENV !== "production";