chore: standardize
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 4s
Build & Deploy / 🧪 QA (push) Failing after 42s
Build & Deploy / 🏗️ Build (push) Failing after 2m14s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s

This commit is contained in:
2026-02-11 11:05:37 +01:00
parent 8ff4503270
commit 8d547c559e
7 changed files with 209 additions and 460 deletions

70
lib/env.test.ts Normal file
View File

@@ -0,0 +1,70 @@
import { describe, it, expect } from "vitest";
import { envSchema } from "./env";
describe("envSchema", () => {
it("should allow missing MAIL_HOST in development", () => {
const result = envSchema.safeParse({
NEXT_PUBLIC_BASE_URL: "http://localhost:3000",
TARGET: "development",
});
expect(result.success).toBe(true);
});
it("should require MAIL_HOST in production", () => {
const result = envSchema.safeParse({
NEXT_PUBLIC_BASE_URL: "https://example.com",
TARGET: "production",
});
expect(result.success).toBe(false);
if (!result.success) {
expect(result.error.issues[0].message).toBe(
"MAIL_HOST is required in non-development environments",
);
}
});
it("should require MAIL_HOST in testing", () => {
const result = envSchema.safeParse({
NEXT_PUBLIC_BASE_URL: "https://testing.example.com",
TARGET: "testing",
});
expect(result.success).toBe(false);
if (!result.success) {
expect(result.error.issues[0].message).toBe(
"MAIL_HOST is required in non-development environments",
);
}
});
it("should require MAIL_HOST in staging", () => {
const result = envSchema.safeParse({
NEXT_PUBLIC_BASE_URL: "https://staging.example.com",
TARGET: "staging",
});
expect(result.success).toBe(false);
if (!result.success) {
expect(result.error.issues[0].message).toBe(
"MAIL_HOST is required in non-development environments",
);
}
});
it("should pass if MAIL_HOST is provided in production", () => {
const result = envSchema.safeParse({
NEXT_PUBLIC_BASE_URL: "https://example.com",
TARGET: "production",
MAIL_HOST: "smtp.example.com",
});
expect(result.success).toBe(true);
});
it("should skip MAIL_HOST requirement if SKIP_RUNTIME_ENV_VALIDATION is true", () => {
process.env.SKIP_RUNTIME_ENV_VALIDATION = "true";
const result = envSchema.safeParse({
NEXT_PUBLIC_BASE_URL: "https://example.com",
TARGET: "production",
});
expect(result.success).toBe(true);
delete process.env.SKIP_RUNTIME_ENV_VALIDATION;
});
});

View File

@@ -1,5 +1,9 @@
import { z } from "zod";
import { validateMintelEnv, mintelEnvSchema } from "@mintel/next-utils";
import {
validateMintelEnv,
mintelEnvSchema,
withMintelRefinements,
} from "@mintel/next-utils";
/**
* Environment variable schema.
@@ -10,20 +14,25 @@ import { validateMintelEnv, mintelEnvSchema } from "@mintel/next-utils";
* - Logging
* - Analytics
*/
export const envSchema = z.object({
...mintelEnvSchema,
const envExtension = {
// Project specific overrides or additions
AUTH_COOKIE_NAME: z.string().default("mb_gatekeeper_session"),
INFRA_DIRECTUS_URL: z.string().url().optional(),
INFRA_DIRECTUS_TOKEN: z.string().optional(),
});
};
/**
* Full schema including Mintel base and refinements
*/
export const envSchema = withMintelRefinements(
z.object(mintelEnvSchema).extend(envExtension),
);
/**
* Validated environment object.
*/
export const env = validateMintelEnv(envSchema.shape);
export const env = validateMintelEnv(envExtension);
/**
* For legacy compatibility with existing code.