env
Some checks failed
Build & Deploy KLZ Cables / build-and-deploy (push) Failing after 1m17s

This commit is contained in:
2026-01-28 15:26:36 +01:00
parent 91ebc54571
commit 859d034ed7
7 changed files with 153 additions and 117 deletions

View File

@@ -1,51 +1,50 @@
import { z } from 'zod';
/**
* Helper to treat empty strings as undefined.
*/
const preprocessEmptyString = (val: unknown) => (val === '' ? undefined : val);
/**
* Environment variable schema.
*/
const envSchema = z.object({
export const envSchema = z.object({
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
NEXT_PUBLIC_BASE_URL: z.string().url().default('http://localhost:3000'),
NEXT_PUBLIC_BASE_URL: z.preprocess(preprocessEmptyString, z.string().url()),
// Analytics
NEXT_PUBLIC_UMAMI_WEBSITE_ID: z.string().optional(),
NEXT_PUBLIC_UMAMI_SCRIPT_URL: z.string().url().default('https://analytics.infra.mintel.me/script.js'),
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.string().optional(),
SENTRY_DSN: z.preprocess(preprocessEmptyString, z.string().optional()),
// Cache
REDIS_URL: z.string().optional(),
REDIS_KEY_PREFIX: z.string().default('klz:'),
REDIS_URL: z.preprocess(preprocessEmptyString, z.string().optional()),
REDIS_KEY_PREFIX: z.preprocess(preprocessEmptyString, z.string().default('klz:')),
// Logging
LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
// Mail
MAIL_HOST: z.string().optional(),
MAIL_PORT: z.coerce.number().default(587),
MAIL_USERNAME: z.string().optional(),
MAIL_PASSWORD: z.string().optional(),
MAIL_FROM: z.string().optional(),
MAIL_RECIPIENTS: z.string().optional().transform(val => val?.split(',').filter(Boolean) || []),
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([])
),
});
export type Env = z.infer<typeof envSchema>;
/**
* Helper to get environment variables.
* Collects all environment variables from the process.
* Explicitly references NEXT_PUBLIC_ variables for Next.js inlining.
*/
function getRawEnv() {
const isServer = typeof window === 'undefined';
if (!isServer) {
// Client-side: only return NEXT_PUBLIC_ variables
return {
NEXT_PUBLIC_BASE_URL: process.env.NEXT_PUBLIC_BASE_URL,
NEXT_PUBLIC_UMAMI_WEBSITE_ID: process.env.NEXT_PUBLIC_UMAMI_WEBSITE_ID,
NEXT_PUBLIC_UMAMI_SCRIPT_URL: process.env.NEXT_PUBLIC_UMAMI_SCRIPT_URL,
};
}
// Server-side: return all variables
export function getRawEnv() {
return {
NODE_ENV: process.env.NODE_ENV,
NEXT_PUBLIC_BASE_URL: process.env.NEXT_PUBLIC_BASE_URL,
@@ -63,14 +62,3 @@ function getRawEnv() {
MAIL_RECIPIENTS: process.env.MAIL_RECIPIENTS,
};
}
/**
* Validated environment variables.
* We use safeParse during build to avoid crashing the build process.
*/
const isBuildTime = process.env.NEXT_PHASE === 'phase-production-build';
const parsed = isBuildTime
? envSchema.safeParse(getRawEnv())
: { success: true, data: envSchema.parse(getRawEnv()) };
export const env = parsed.success ? parsed.data : envSchema.parse({});