fix: keep server env out of avatar client bundle
This commit is contained in:
1 parent
5b190cb929
commit
1610aa1008
4 files changed
+46
-32
No files matched your search
+6
-13
@@ -1,17 +1,10 @@
|
|||||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, 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 { avatarImageUrl, excerpt, slugify } from "./format";
|
import { avatarImageUrl, excerpt, slugify } from "./format";
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vi.unstubAllEnvs();
|
||||||
|
});
|
||||||
|
|
||||||
describe("slugify", () => {
|
describe("slugify", () => {
|
||||||
it("lowercases and hyphenates", () => {
|
it("lowercases and hyphenates", () => {
|
||||||
expect(slugify("Hello World!")).toBe("hello-world");
|
expect(slugify("Hello World!")).toBe("hello-world");
|
||||||
@@ -26,7 +19,7 @@ describe("slugify", () => {
|
|||||||
|
|
||||||
describe("avatarImageUrl", () => {
|
describe("avatarImageUrl", () => {
|
||||||
beforeEach(() => {
|
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", () => {
|
it("appends the figure and options", () => {
|
||||||
|
|||||||
@@ -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
@@ -1,20 +1,13 @@
|
|||||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, 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 { getAvatarUrl, resolveImagerBase } from "./imager";
|
import { getAvatarUrl, resolveImagerBase } from "./imager";
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vi.unstubAllEnvs();
|
||||||
|
});
|
||||||
|
|
||||||
describe("resolveImagerBase", () => {
|
describe("resolveImagerBase", () => {
|
||||||
beforeEach(() => {
|
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", () => {
|
it("returns configured imager env var", () => {
|
||||||
@@ -22,12 +15,12 @@ describe("resolveImagerBase", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("strips trailing slashes", () => {
|
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");
|
expect(resolveImagerBase()).toBe("https://img.example.com");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("falls back to epicnabbo.nl when env var is not set", () => {
|
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(
|
expect(resolveImagerBase()).toBe(
|
||||||
"https://epicnabbo.nl/imaging/avatarimage",
|
"https://epicnabbo.nl/imaging/avatarimage",
|
||||||
);
|
);
|
||||||
@@ -36,7 +29,7 @@ describe("resolveImagerBase", () => {
|
|||||||
|
|
||||||
describe("getAvatarUrl", () => {
|
describe("getAvatarUrl", () => {
|
||||||
beforeEach(() => {
|
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)", () => {
|
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", () => {
|
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");
|
const url = getAvatarUrl("hd-180-1");
|
||||||
expect(url.startsWith("https://epicnabbo.nl/imaging/avatarimage?")).toBe(
|
expect(url.startsWith("https://epicnabbo.nl/imaging/avatarimage?")).toBe(
|
||||||
true,
|
true,
|
||||||
|
|||||||
+1
-2
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
export type { AvatarOptions } from "@/types/admin";
|
export type { AvatarOptions } from "@/types/admin";
|
||||||
|
|
||||||
import { env } from "@/env";
|
|
||||||
import type { AvatarOptions } from "@/types/admin";
|
import type { AvatarOptions } from "@/types/admin";
|
||||||
|
|
||||||
const DEFAULT_IMAGER_URL = "https://epicnabbo.nl/imaging/avatarimage";
|
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.
|
* Falls back to epicnabbo.nl if not configured.
|
||||||
*/
|
*/
|
||||||
export function resolveImagerBase(): string {
|
export function resolveImagerBase(): string {
|
||||||
const fromEnv = env.NEXT_PUBLIC_IMAGER_URL?.trim();
|
const fromEnv = process.env.NEXT_PUBLIC_IMAGER_URL?.trim();
|
||||||
if (!fromEnv) {
|
if (!fromEnv) {
|
||||||
return DEFAULT_IMAGER_URL;
|
return DEFAULT_IMAGER_URL;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user