env vars
This commit is contained in:
96
apps/website/lib/config/env.ts
Normal file
96
apps/website/lib/config/env.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
const urlOptional = z.string().url().optional();
|
||||
const stringOptional = z.string().optional();
|
||||
|
||||
const publicEnvSchema = z.object({
|
||||
NEXT_PUBLIC_GRIDPILOT_MODE: z.enum(['pre-launch', 'alpha']).optional(),
|
||||
NEXT_PUBLIC_SITE_URL: urlOptional,
|
||||
NEXT_PUBLIC_API_BASE_URL: urlOptional,
|
||||
|
||||
NEXT_PUBLIC_SITE_NAME: stringOptional,
|
||||
NEXT_PUBLIC_SUPPORT_EMAIL: stringOptional,
|
||||
NEXT_PUBLIC_SPONSOR_EMAIL: stringOptional,
|
||||
|
||||
NEXT_PUBLIC_LEGAL_COMPANY_NAME: stringOptional,
|
||||
NEXT_PUBLIC_LEGAL_VAT_ID: stringOptional,
|
||||
NEXT_PUBLIC_LEGAL_REGISTERED_COUNTRY: stringOptional,
|
||||
NEXT_PUBLIC_LEGAL_REGISTERED_ADDRESS: stringOptional,
|
||||
|
||||
NEXT_PUBLIC_DISCORD_URL: stringOptional,
|
||||
NEXT_PUBLIC_X_URL: stringOptional,
|
||||
});
|
||||
|
||||
const serverEnvSchema = z.object({
|
||||
API_BASE_URL: urlOptional,
|
||||
KV_REST_API_URL: urlOptional,
|
||||
KV_REST_API_TOKEN: stringOptional,
|
||||
|
||||
CI: stringOptional,
|
||||
DOCKER: stringOptional,
|
||||
NODE_ENV: z.enum(['development', 'production', 'test']).optional(),
|
||||
});
|
||||
|
||||
export type WebsitePublicEnv = z.infer<typeof publicEnvSchema>;
|
||||
export type WebsiteServerEnv = z.infer<typeof serverEnvSchema>;
|
||||
|
||||
function formatZodIssues(issues: z.ZodIssue[]): string {
|
||||
return issues
|
||||
.map((issue) => {
|
||||
const path = issue.path.join('.') || '(root)';
|
||||
return `${path}: ${issue.message}`;
|
||||
})
|
||||
.join('; ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Website env vars (server-side safe).
|
||||
* Only validates the variables we explicitly support.
|
||||
*/
|
||||
export function getWebsiteServerEnv(): WebsiteServerEnv {
|
||||
const result = serverEnvSchema.safeParse(process.env);
|
||||
if (!result.success) {
|
||||
throw new Error(`Invalid website server env: ${formatZodIssues(result.error.issues)}`);
|
||||
}
|
||||
return result.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Website public env vars (safe on both server + client).
|
||||
* Note: on the client, only `NEXT_PUBLIC_*` vars are actually present.
|
||||
*/
|
||||
export function getWebsitePublicEnv(): WebsitePublicEnv {
|
||||
const result = publicEnvSchema.safeParse(process.env);
|
||||
if (!result.success) {
|
||||
throw new Error(`Invalid website public env: ${formatZodIssues(result.error.issues)}`);
|
||||
}
|
||||
return result.data;
|
||||
}
|
||||
|
||||
export function isTruthyEnv(value: string | undefined): boolean {
|
||||
if (!value) return false;
|
||||
return value !== '0' && value.toLowerCase() !== 'false';
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the semantics used in [`getWebsiteApiBaseUrl()`](apps/website/lib/config/apiBaseUrl.ts:6).
|
||||
*/
|
||||
export function isTestLikeEnvironment(): boolean {
|
||||
const { NODE_ENV, CI, DOCKER } = getWebsiteServerEnv();
|
||||
return NODE_ENV === 'test' || CI === 'true' || DOCKER === 'true';
|
||||
}
|
||||
|
||||
export function isProductionEnvironment(): boolean {
|
||||
return getWebsiteServerEnv().NODE_ENV === 'production';
|
||||
}
|
||||
|
||||
export function isKvConfigured(): boolean {
|
||||
const { KV_REST_API_URL, KV_REST_API_TOKEN } = getWebsiteServerEnv();
|
||||
return Boolean(KV_REST_API_URL && KV_REST_API_TOKEN);
|
||||
}
|
||||
|
||||
export function assertKvConfiguredInProduction(): void {
|
||||
if (isProductionEnvironment() && !isKvConfigured()) {
|
||||
throw new Error('Missing KV_REST_API_URL/KV_REST_API_TOKEN in production environment');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user