import { z } from "zod"; export const envSchema = z.object({ NODE_ENV: z.enum(["development", "production", "test"]).default("development"), PORT: z.coerce.number().default(3000), // Database POSTGRES_HOST: z.string(), POSTGRES_PORT: z.coerce.number().default(5432), POSTGRES_DB: z.string(), POSTGRES_USER: z.string(), POSTGRES_PASSWORD: z.string(), // S3 S3_ENDPOINT: z.string().default("localhost"), S3_PORT: z.coerce.number().default(9000), S3_USE_SSL: z.preprocess((val) => val === "true", z.boolean()).default(false), S3_ACCESS_KEY: z.string().default("minioadmin"), S3_SECRET_KEY: z.string().default("minioadmin"), S3_BUCKET_NAME: z.string().default("memegoat"), // Security JWT_SECRET: z.string().min(32), ENCRYPTION_KEY: z.string().length(32), PGP_ENCRYPTION_KEY: z.string().min(16), // Mail MAIL_HOST: z.string(), MAIL_PORT: z.coerce.number(), MAIL_SECURE: z.preprocess((val) => val === "true", z.boolean()).default(false), MAIL_USER: z.string(), MAIL_PASS: z.string(), MAIL_FROM: z.string().email(), DOMAIN_NAME: z.string(), API_URL: z.string().url().optional(), // Sentry SENTRY_DSN: z.string().optional(), // Redis REDIS_HOST: z.string().default("localhost"), REDIS_PORT: z.coerce.number().default(6379), // Session SESSION_PASSWORD: z.string().min(32), // Media Limits MAX_IMAGE_SIZE_KB: z.coerce.number().default(512), MAX_GIF_SIZE_KB: z.coerce.number().default(1024), MAX_VIDEO_SIZE_KB: z.coerce.number().default(10240), }); export type Env = z.infer; export function validateEnv(config: Record) { const result = envSchema.safeParse(config); if (!result.success) { console.error("❌ Invalid environment variables:", result.error.format()); throw new Error("Invalid environment variables"); } return result.data; }