item-34 - Serve every /public/ asset under a content-versioned URL with an immutable Cache-Control

This commit is contained in:
2026-10-31 10:00:03 +01:00
parent 910ac18798
commit 3d757d4726
18 changed files with 340 additions and 88 deletions
+8 -2
View File
@@ -6,10 +6,10 @@ import ejs from "ejs";
import { ENGLISH_LOCALS } from "../i18n/view-locals.ts";
// A localeHref that marks what it touches, so a raw href in the chrome is visible to a test.
const CARRYING = { ...ENGLISH_LOCALS, localeHref: (href: string) => `${href}?locale=sv-SE` };
const CARRYING = { ...ENGLISH_LOCALS, assetHref: (href: string) => href, localeHref: (href: string) => `${href}?locale=sv-SE` };
const shell = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "views", "partials", "shell.ejs");
const render = (data: Record<string, unknown> = {}): Promise<string> => ejs.renderFile(shell, { ...ENGLISH_LOCALS, ...data });
const render = (data: Record<string, unknown> = {}): Promise<string> => ejs.renderFile(shell, { ...ENGLISH_LOCALS, assetHref: (href: string) => href, ...data });
test("app shell renders sidebar, topbar and the content slot", async () => {
const html = await render({
@@ -90,6 +90,12 @@ test("app shell links extra per-page stylesheets via the styles slot (e.g. a plu
assert.equal((none.match(/rel="stylesheet"/g) ?? []).length, 1);
});
test("app shell passes every /public/ reference through the host's assetHref, the plugin's styles included", async () => {
const html = await render({ assetHref: (href: string) => `${href}?v=1`, brand: { logo: "/public/brand/logo.svg", name: "Acme" }, styles: ["/public/scheduling/scheduling.css"] });
const refs = [...html.matchAll(/(?:href|src)="(\/public\/[^"]*)"/g)].map((m) => m[1]);
assert.deepEqual(refs, ["/public/css/styles.css?v=1", "/public/scheduling/scheduling.css?v=1", "/public/favicon.svg?v=1", "/public/brand/logo.svg?v=1"]);
});
test("app shell can disable the menu: no sidebar, focused single-column layout", async () => {
const bare = await render({ menu: false, title: "Focus", body: '<section id="b">x</section>', nav: '<a href="/x">Overview</a>' });
assert.doesNotMatch(bare, /<aside class="sidebar"/); // sidebar dropped