feat: add env schema for environment variable validation

Introduced `env.schema.ts` for structured validation of environment variables using Zod. Includes defaults and validations for database, S3, security, mail, Redis, and session configurations.
This commit is contained in:
Mathis HERRIOT
2026-01-08 15:25:16 +01:00
parent 2218768adb
commit e210f1f95f

View File

@@ -0,0 +1,63 @@
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(),
// 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),
});
export type Env = z.infer<typeof envSchema>;
export function validateEnv(config: Record<string, unknown>) {
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;
}