All checks were successful
Monorepo Pipeline / ⚡ Prioritize Release (push) Successful in 2s
Monorepo Pipeline / 🧹 Lint (push) Successful in 46s
Monorepo Pipeline / 🧪 Test (push) Successful in 55s
Monorepo Pipeline / 🏗️ Build (push) Successful in 1m48s
Monorepo Pipeline / 🚀 Release (push) Has been skipped
Monorepo Pipeline / 🐳 Build Directus (Base) (push) Has been skipped
Monorepo Pipeline / 🐳 Build Gatekeeper (Product) (push) Has been skipped
Monorepo Pipeline / 🐳 Build Build-Base (push) Has been skipped
Monorepo Pipeline / 🐳 Build Production Runtime (push) Has been skipped
119 lines
3.5 KiB
TypeScript
119 lines
3.5 KiB
TypeScript
import { z } from "zod";
|
|
|
|
export const mintelEnvSchema = {
|
|
NODE_ENV: z
|
|
.enum(["development", "production", "test"])
|
|
.default("development"),
|
|
NEXT_PUBLIC_BASE_URL: z.string().url().optional(),
|
|
NEXT_PUBLIC_TARGET: z
|
|
.enum(["development", "testing", "staging", "production"])
|
|
.optional(),
|
|
TARGET: z
|
|
.enum(["development", "testing", "staging", "production"])
|
|
.optional(),
|
|
|
|
// Analytics (Proxy Pattern)
|
|
UMAMI_WEBSITE_ID: z.string().optional(),
|
|
NEXT_PUBLIC_UMAMI_WEBSITE_ID: z.string().optional(),
|
|
UMAMI_API_ENDPOINT: z
|
|
.string()
|
|
.url()
|
|
.default("https://analytics.infra.mintel.me"),
|
|
|
|
// Error Tracking
|
|
SENTRY_DSN: z.string().optional(),
|
|
|
|
// Notifications
|
|
GOTIFY_URL: z.string().url().optional(),
|
|
GOTIFY_TOKEN: z.string().optional(),
|
|
|
|
LOG_LEVEL: z
|
|
.enum(["trace", "debug", "info", "warn", "error", "fatal"])
|
|
.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.preprocess(
|
|
(val) => (typeof val === "string" ? val.split(",").filter(Boolean) : val),
|
|
z.array(z.string()).default([]),
|
|
),
|
|
|
|
// Directus
|
|
DIRECTUS_URL: z.string().url().default("http://localhost:8055"),
|
|
DIRECTUS_ADMIN_EMAIL: z.string().optional(),
|
|
DIRECTUS_ADMIN_PASSWORD: z.string().optional(),
|
|
DIRECTUS_API_TOKEN: z.string().optional(),
|
|
INTERNAL_DIRECTUS_URL: z.string().url().optional(),
|
|
};
|
|
|
|
/**
|
|
* Standard Mintel refinements for environment variables.
|
|
* Enforces mandatory requirements for non-development environments.
|
|
*/
|
|
export const withMintelRefinements = <T extends z.ZodTypeAny>(schema: T) => {
|
|
return schema.superRefine((data: any, ctx) => {
|
|
const skipValidation =
|
|
process.env.SKIP_ENV_VALIDATION === "true" ||
|
|
process.env.SKIP_RUNTIME_ENV_VALIDATION === "true";
|
|
|
|
if (skipValidation) return;
|
|
|
|
const target = data.TARGET || data.NEXT_PUBLIC_TARGET || "development";
|
|
|
|
// Strict validation for non-development environments
|
|
if (target !== "development") {
|
|
if (!data.MAIL_HOST) {
|
|
ctx.addIssue({
|
|
code: z.ZodIssueCode.custom,
|
|
message: "MAIL_HOST is required in non-development environments",
|
|
path: ["MAIL_HOST"],
|
|
});
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
export type MintelEnv<T extends z.ZodRawShape = Record<string, never>> =
|
|
z.infer<
|
|
ReturnType<
|
|
typeof withMintelRefinements<z.ZodObject<typeof mintelEnvSchema & T>>
|
|
>
|
|
>;
|
|
|
|
export function validateMintelEnv<
|
|
T extends z.ZodRawShape = Record<string, never>,
|
|
>(schemaExtension: T = {} as T): MintelEnv<T> {
|
|
const fullSchema = withMintelRefinements(
|
|
z.object(mintelEnvSchema).extend(schemaExtension),
|
|
);
|
|
|
|
const isBuildTime =
|
|
process.env.NEXT_PHASE === "phase-production-build" ||
|
|
process.env.SKIP_ENV_VALIDATION === "true" ||
|
|
process.env.SKIP_RUNTIME_ENV_VALIDATION === "true";
|
|
|
|
const result = fullSchema.safeParse(process.env);
|
|
|
|
if (!result.success) {
|
|
if (isBuildTime) {
|
|
console.warn(
|
|
"⚠️ Some environment variables are missing during build, but skipping strict validation.",
|
|
);
|
|
// Return process.env casted to the full schema type to unblock builds
|
|
return process.env as unknown as z.infer<typeof fullSchema>;
|
|
}
|
|
|
|
console.error(
|
|
"❌ Invalid environment variables:",
|
|
result.error.flatten().fieldErrors,
|
|
);
|
|
throw new Error("Invalid environment variables");
|
|
}
|
|
|
|
return result.data as MintelEnv<T>;
|
|
}
|