import { z } from 'zod'; /** * Helper to treat empty strings as undefined. */ const preprocessEmptyString = (val: unknown) => (val === '' ? undefined : val); /** * Environment variable schema. */ export const envSchema = z.object({ NODE_ENV: z.enum(['development', 'production', 'test']).default('development'), NEXT_PUBLIC_BASE_URL: z.preprocess(preprocessEmptyString, z.string().url()), NEXT_PUBLIC_TARGET: z .enum(['development', 'testing', 'staging', 'production']) .default('development'), // Analytics NEXT_PUBLIC_UMAMI_WEBSITE_ID: z.preprocess(preprocessEmptyString, z.string().optional()), NEXT_PUBLIC_UMAMI_SCRIPT_URL: z.preprocess( preprocessEmptyString, z.string().url().default('https://analytics.infra.mintel.me/script.js'), ), // Error Tracking SENTRY_DSN: z.preprocess(preprocessEmptyString, z.string().optional()), // Logging LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'), // Mail MAIL_HOST: z.preprocess(preprocessEmptyString, z.string().optional()), MAIL_PORT: z.preprocess(preprocessEmptyString, z.coerce.number().default(587)), MAIL_USERNAME: z.preprocess(preprocessEmptyString, z.string().optional()), MAIL_PASSWORD: z.preprocess(preprocessEmptyString, z.string().optional()), MAIL_FROM: z.preprocess(preprocessEmptyString, z.string().optional()), MAIL_RECIPIENTS: z.preprocess( (val) => (typeof val === 'string' ? val.split(',').filter(Boolean) : val), z.array(z.string()).default([]), ), // Directus DIRECTUS_URL: z.preprocess( preprocessEmptyString, z.string().url().default('http://localhost:8055'), ), DIRECTUS_ADMIN_EMAIL: z.preprocess(preprocessEmptyString, z.string().optional()), DIRECTUS_ADMIN_PASSWORD: z.preprocess(preprocessEmptyString, z.string().optional()), DIRECTUS_API_TOKEN: z.preprocess(preprocessEmptyString, z.string().optional()), INTERNAL_DIRECTUS_URL: z.preprocess(preprocessEmptyString, z.string().url().optional()), // Deploy Target TARGET: z.enum(['development', 'testing', 'staging', 'production']).default('development'), }); export type Env = z.infer; /** * Collects all environment variables from the process. * Explicitly references NEXT_PUBLIC_ variables for Next.js inlining. */ export function getRawEnv() { return { NODE_ENV: process.env.NODE_ENV, NEXT_PUBLIC_BASE_URL: process.env.NEXT_PUBLIC_BASE_URL, NEXT_PUBLIC_TARGET: process.env.NEXT_PUBLIC_TARGET, NEXT_PUBLIC_UMAMI_WEBSITE_ID: process.env.NEXT_PUBLIC_UMAMI_WEBSITE_ID, NEXT_PUBLIC_UMAMI_SCRIPT_URL: process.env.NEXT_PUBLIC_UMAMI_SCRIPT_URL, SENTRY_DSN: process.env.SENTRY_DSN, LOG_LEVEL: process.env.LOG_LEVEL, MAIL_HOST: process.env.MAIL_HOST, MAIL_PORT: process.env.MAIL_PORT, MAIL_USERNAME: process.env.MAIL_USERNAME, MAIL_PASSWORD: process.env.MAIL_PASSWORD, MAIL_FROM: process.env.MAIL_FROM, MAIL_RECIPIENTS: process.env.MAIL_RECIPIENTS, DIRECTUS_URL: process.env.DIRECTUS_URL, DIRECTUS_ADMIN_EMAIL: process.env.DIRECTUS_ADMIN_EMAIL, DIRECTUS_ADMIN_PASSWORD: process.env.DIRECTUS_ADMIN_PASSWORD, DIRECTUS_API_TOKEN: process.env.DIRECTUS_API_TOKEN, INTERNAL_DIRECTUS_URL: process.env.INTERNAL_DIRECTUS_URL, TARGET: process.env.TARGET, }; }