From 9a11185c2ddcac78e85251188a620981fa9780a6 Mon Sep 17 00:00:00 2001 From: Mike Tuev R9FT Date: Sat, 11 Jul 2026 05:35:40 +0500 Subject: [PATCH] fix(docker): copy head-response-guard.cjs into the standalone bundle #6608 added `import headResponseGuard from './head-response-guard.cjs'` to scripts/dev/standalone-server-ws.mjs but never added the copy entry to assembleStandalone.mjs. The standalone Docker image crashed at boot with ERR_MODULE_NOT_FOUND /app/head-response-guard.cjs. The new test derives ALL relative imports of standalone-server-ws.mjs and asserts each has a copy entry, so a future sibling module cannot silently break the container again. --- scripts/build/assembleStandalone.mjs | 7 +++ .../standalone-server-ws-deps-copied.test.ts | 48 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 tests/unit/standalone-server-ws-deps-copied.test.ts diff --git a/scripts/build/assembleStandalone.mjs b/scripts/build/assembleStandalone.mjs index 6ee88d58a7f7..887570a39413 100644 --- a/scripts/build/assembleStandalone.mjs +++ b/scripts/build/assembleStandalone.mjs @@ -139,6 +139,13 @@ const EXTRA_MODULE_ENTRIES = [ src: ["scripts", "dev", "http-method-guard.cjs"], dest: ["http-method-guard.cjs"], }, + { + // #6608 added this import to standalone-server-ws.mjs; without the copy + // the Docker image crashes at boot with ERR_MODULE_NOT_FOUND. + label: "HEAD response guard (server-ws.mjs dependency)", + src: ["scripts", "dev", "head-response-guard.cjs"], + dest: ["head-response-guard.cjs"], + }, { label: "responses-ws-proxy (server-ws.mjs dependency)", src: ["scripts", "dev", "responses-ws-proxy.mjs"], diff --git a/tests/unit/standalone-server-ws-deps-copied.test.ts b/tests/unit/standalone-server-ws-deps-copied.test.ts new file mode 100644 index 000000000000..3abc622a77bb --- /dev/null +++ b/tests/unit/standalone-server-ws-deps-copied.test.ts @@ -0,0 +1,48 @@ +/** + * tests/unit/standalone-server-ws-deps-copied.test.ts + * + * Bug: #6608 added `import headResponseGuard from "./head-response-guard.cjs"` + * to scripts/dev/standalone-server-ws.mjs but did NOT add a copy entry to + * scripts/build/assembleStandalone.mjs. The standalone Docker image then + * crashed at boot: ERR_MODULE_NOT_FOUND /app/head-response-guard.cjs. + * + * Guard: every RELATIVE import in standalone-server-ws.mjs must have a + * matching copy entry in assembleStandalone.mjs, so a future sibling module + * cannot silently break the container again. + */ + +import test from "node:test"; +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { join } from "node:path"; + +const ROOT = join(import.meta.dirname, "../.."); +const serverWsSrc = readFileSync(join(ROOT, "scripts/dev/standalone-server-ws.mjs"), "utf8"); +const assembleSrc = readFileSync(join(ROOT, "scripts/build/assembleStandalone.mjs"), "utf8"); + +/** All relative same-dir imports of standalone-server-ws.mjs (./foo.mjs|cjs). */ +function relativeImports(src: string): string[] { + const out: string[] = []; + const re = /from\s+["']\.\/([\w./-]+\.(?:mjs|cjs))["']/g; + let m: RegExpExecArray | null; + while ((m = re.exec(src)) !== null) out.push(m[1]); + return [...new Set(out)]; +} + +test("standalone-server-ws.mjs has relative imports to verify", () => { + const imports = relativeImports(serverWsSrc); + assert.ok(imports.length > 0, "expected at least one relative import (sanity)"); + assert.ok( + imports.includes("head-response-guard.cjs"), + "expected the #6608 head-response-guard.cjs import (sanity)" + ); +}); + +test("every relative import of standalone-server-ws.mjs is copied by assembleStandalone", () => { + const missing = relativeImports(serverWsSrc).filter((f) => !assembleSrc.includes(f)); + assert.deepEqual( + missing, + [], + `assembleStandalone.mjs must copy these server-ws.mjs dependencies: ${missing.join(", ")}` + ); +});