fix: keep server env out of avatar client bundle
CI / runtime-diagnostics (push) Skipped
CI / check (push) Successful in 33s
CI / release (push) Skipped
CI / deploy (push) Successful in 49s

This commit is contained in:
Simo committed 2026-08-31 21:41:40 +02:00
1 parent 5b190cb929
commit 1610aa1008
4 files changed
+46 -32

No files matched your search

+6 -13
View File
@@ -1,17 +1,10 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
const envMock = vi.hoisted(() => ({
env: {
NEXT_PUBLIC_IMAGER_URL: "https://img.example.com" as string | undefined,
NEXT_PUBLIC_APP_URL: undefined as string | undefined,
IMAGING_UPSTREAM_URL: "https://up.example.com" as string | undefined,
},
}));
vi.mock("@/env", () => envMock);
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { avatarImageUrl, excerpt, slugify } from "./format";
afterEach(() => {
vi.unstubAllEnvs();
});
describe("slugify", () => {
it("lowercases and hyphenates", () => {
expect(slugify("Hello World!")).toBe("hello-world");
@@ -26,7 +19,7 @@ describe("slugify", () => {
describe("avatarImageUrl", () => {
beforeEach(() => {
envMock.env.NEXT_PUBLIC_IMAGER_URL = "https://img.example.com";
vi.stubEnv("NEXT_PUBLIC_IMAGER_URL", "https://img.example.com");
});
it("appends the figure and options", () => {
+29
View File
@@ -0,0 +1,29 @@
import { afterEach, describe, expect, it, vi } from "vitest";
const originalDatabaseUrl = process.env.DATABASE_URL;
const originalHotelName = process.env.HOTEL_NAME;
const originalSkipValidation = process.env.SKIP_ENV_VALIDATION;
afterEach(() => {
vi.resetModules();
if (originalDatabaseUrl === undefined) delete process.env.DATABASE_URL;
else process.env.DATABASE_URL = originalDatabaseUrl;
if (originalHotelName === undefined) delete process.env.HOTEL_NAME;
else process.env.HOTEL_NAME = originalHotelName;
if (originalSkipValidation === undefined)
delete process.env.SKIP_ENV_VALIDATION;
else process.env.SKIP_ENV_VALIDATION = originalSkipValidation;
});
describe("imager client boundary", () => {
it("loads without server-only environment variables", async () => {
delete process.env.DATABASE_URL;
delete process.env.HOTEL_NAME;
vi.resetModules();
delete process.env.SKIP_ENV_VALIDATION;
const imager = await import("./imager");
expect(imager.getAvatarUrl("hd-180-1")).toContain("figure=hd-180-1");
});
});
+10 -17
View File
@@ -1,20 +1,13 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
const envMock = vi.hoisted(() => ({
env: {
NEXT_PUBLIC_IMAGER_URL: "https://img.example.com" as string | undefined,
NEXT_PUBLIC_APP_URL: undefined as string | undefined,
IMAGING_UPSTREAM_URL: "https://up.example.com" as string | undefined,
},
}));
vi.mock("@/env", () => envMock);
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { getAvatarUrl, resolveImagerBase } from "./imager";
afterEach(() => {
vi.unstubAllEnvs();
});
describe("resolveImagerBase", () => {
beforeEach(() => {
envMock.env.NEXT_PUBLIC_IMAGER_URL = "https://img.example.com";
vi.stubEnv("NEXT_PUBLIC_IMAGER_URL", "https://img.example.com");
});
it("returns configured imager env var", () => {
@@ -22,12 +15,12 @@ describe("resolveImagerBase", () => {
});
it("strips trailing slashes", () => {
envMock.env.NEXT_PUBLIC_IMAGER_URL = "https://img.example.com/";
vi.stubEnv("NEXT_PUBLIC_IMAGER_URL", "https://img.example.com/");
expect(resolveImagerBase()).toBe("https://img.example.com");
});
it("falls back to epicnabbo.nl when env var is not set", () => {
envMock.env.NEXT_PUBLIC_IMAGER_URL = undefined;
vi.stubEnv("NEXT_PUBLIC_IMAGER_URL", "");
expect(resolveImagerBase()).toBe(
"https://epicnabbo.nl/imaging/avatarimage",
);
@@ -36,7 +29,7 @@ describe("resolveImagerBase", () => {
describe("getAvatarUrl", () => {
beforeEach(() => {
envMock.env.NEXT_PUBLIC_IMAGER_URL = "https://img.example.com";
vi.stubEnv("NEXT_PUBLIC_IMAGER_URL", "https://img.example.com");
});
it("builds a query string with defaults (omits default params)", () => {
@@ -83,7 +76,7 @@ describe("getAvatarUrl", () => {
});
it("uses epicnabbo.nl when no env var is set", () => {
envMock.env.NEXT_PUBLIC_IMAGER_URL = undefined;
vi.stubEnv("NEXT_PUBLIC_IMAGER_URL", "");
const url = getAvatarUrl("hd-180-1");
expect(url.startsWith("https://epicnabbo.nl/imaging/avatarimage?")).toBe(
true,
+1 -2
View File
@@ -7,7 +7,6 @@
export type { AvatarOptions } from "@/types/admin";
import { env } from "@/env";
import type { AvatarOptions } from "@/types/admin";
const DEFAULT_IMAGER_URL = "https://epicnabbo.nl/imaging/avatarimage";
@@ -17,7 +16,7 @@ const DEFAULT_IMAGER_URL = "https://epicnabbo.nl/imaging/avatarimage";
* Falls back to epicnabbo.nl if not configured.
*/
export function resolveImagerBase(): string {
const fromEnv = env.NEXT_PUBLIC_IMAGER_URL?.trim();
const fromEnv = process.env.NEXT_PUBLIC_IMAGER_URL?.trim();
if (!fromEnv) {
return DEFAULT_IMAGER_URL;
}