import { z } from "zod"; const envSchema = z.object({ DATABASE_URL: z.string().url(), DATA_DIR: z.string().min(1).default("/data"), MEDIA_DIR: z.string().min(1).default("/data/media"), WEB_PORT: z.string().regex(/^\d+$/).transform((s) => Number(s)).default("3000"), }); export type Env = z.infer; // Lazy parse via Proxy. Next.js's `next build` does a // "Collecting page data" pass that imports every route module — // including api/events/route.ts which depends on this env. With a // top-level `envSchema.parse(process.env)` the parse ran during // the build container, where DATABASE_URL isn't (and shouldn't be) // set, and Zod aborted the build with: // ZodError: DATABASE_URL: Required // Deferring the parse until first property access lets the build // finish (no consumer accesses env during page-data collection) // while still failing loudly at runtime if the var is missing. let cached: Env | null = null; function read(): Env { if (cached) return cached; cached = envSchema.parse(process.env); return cached; } export const env: Env = new Proxy({} as Env, { get(_t, prop) { return read()[prop as keyof Env]; }, }) as Env;