This commit is contained in:
75
lib/env.ts
Normal file
75
lib/env.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import './load-env';
|
||||
import { z } from 'zod';
|
||||
|
||||
/**
|
||||
* Environment variable schema.
|
||||
* This ensures the application has all required configuration at startup.
|
||||
*/
|
||||
const envSchema = z.object({
|
||||
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
|
||||
NEXT_PUBLIC_BASE_URL: z.string().url().default('http://localhost:3000'),
|
||||
|
||||
// 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'),
|
||||
|
||||
// Error Tracking
|
||||
SENTRY_DSN: z.string().optional(),
|
||||
|
||||
// Cache
|
||||
REDIS_URL: z.string().optional(),
|
||||
REDIS_KEY_PREFIX: 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) || []),
|
||||
});
|
||||
|
||||
export type Env = z.infer<typeof envSchema>;
|
||||
|
||||
/**
|
||||
* Helper to get environment variables.
|
||||
* On the client, only NEXT_PUBLIC_ variables are available.
|
||||
* On the server, all variables are available.
|
||||
*/
|
||||
function getRawEnv() {
|
||||
if (typeof window !== 'undefined') {
|
||||
// Client-side: only return NEXT_PUBLIC_ variables
|
||||
// We must explicitly reference them for Next.js inlining to work
|
||||
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 from process.env
|
||||
return {
|
||||
NODE_ENV: process.env.NODE_ENV,
|
||||
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,
|
||||
SENTRY_DSN: process.env.SENTRY_DSN,
|
||||
REDIS_URL: process.env.REDIS_URL,
|
||||
REDIS_KEY_PREFIX: process.env.REDIS_KEY_PREFIX,
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Validated environment variables.
|
||||
*/
|
||||
export const env = envSchema.parse(getRawEnv());
|
||||
Reference in New Issue
Block a user