fix(build): include webdav-handler.mjs in dist/ bundle (#3687)

server-ws.mjs imports ./webdav-handler.mjs but the assembleStandalone
pipeline did not copy it from scripts/dev/, causing a startup crash on
any fresh install of v3.8.22 (ERR_MODULE_NOT_FOUND).

Fix: add the copy entry to assembleStandalone.mjs, add it to
APP_STAGING_ALLOWED_EXACT_PATHS and PACK_ARTIFACT_REQUIRED_PATHS in
pack-artifact-policy.ts, and add a regression test.

Hotfix validated live on VPS (192.168.0.15): server-ws.mjs resolves the
module and the process starts healthy after the file was deployed.
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-06-11 22:07:32 -03:00
committed by GitHub
parent 9350a5d6c6
commit b6c65efd28
3 changed files with 81 additions and 13 deletions

View File

@@ -73,19 +73,43 @@ async function exists(targetPath) {
* for either path/platform. @type {{label:string, src:string[], dest:string[]}[]}
*/
const NATIVE_ASSET_ENTRIES = [
{ label: "wreq-js native runtime", src: ["node_modules", "wreq-js", "rust"], dest: ["node_modules", "wreq-js", "rust"] },
{ label: "better-sqlite3 native binary", src: ["node_modules", "better-sqlite3", "build"], dest: ["node_modules", "better-sqlite3", "build"] },
{
label: "wreq-js native runtime",
src: ["node_modules", "wreq-js", "rust"],
dest: ["node_modules", "wreq-js", "rust"],
},
{
label: "better-sqlite3 native binary",
src: ["node_modules", "better-sqlite3", "build"],
dest: ["node_modules", "better-sqlite3", "build"],
},
];
/** @type {{label:string, src:string[], dest:string[]}[]} */
const EXTRA_MODULE_ENTRIES = [
{ label: "@swc/helpers", src: ["node_modules", "@swc", "helpers"], dest: ["node_modules", "@swc", "helpers"] },
{ label: "pino-abstract-transport", src: ["node_modules", "pino-abstract-transport"], dest: ["node_modules", "pino-abstract-transport"] },
{ label: "pino-pretty", src: ["node_modules", "pino-pretty"], dest: ["node_modules", "pino-pretty"] },
{
label: "@swc/helpers",
src: ["node_modules", "@swc", "helpers"],
dest: ["node_modules", "@swc", "helpers"],
},
{
label: "pino-abstract-transport",
src: ["node_modules", "pino-abstract-transport"],
dest: ["node_modules", "pino-abstract-transport"],
},
{
label: "pino-pretty",
src: ["node_modules", "pino-pretty"],
dest: ["node_modules", "pino-pretty"],
},
{ label: "split2", src: ["node_modules", "split2"], dest: ["node_modules", "split2"] },
{ label: "migrations", src: ["src", "lib", "db", "migrations"], dest: ["migrations"] },
{ label: "MITM server", src: ["src", "mitm", "server.cjs"], dest: ["src", "mitm", "server.cjs"] },
{ label: "run-standalone script", src: ["scripts", "dev", "run-standalone.mjs"], dest: ["dev", "run-standalone.mjs"] },
{
label: "run-standalone script",
src: ["scripts", "dev", "run-standalone.mjs"],
dest: ["dev", "run-standalone.mjs"],
},
{
// WS-aware wrapper that run-standalone.mjs prefers over bare server.js.
// It installs the trusted peer-IP stamp the authz middleware needs to allow
@@ -96,14 +120,47 @@ const EXTRA_MODULE_ENTRIES = [
src: ["scripts", "dev", "standalone-server-ws.mjs"],
dest: ["server-ws.mjs"],
},
{ label: "peer-stamp helper (server-ws.mjs dependency)", src: ["scripts", "dev", "peer-stamp.mjs"], dest: ["peer-stamp.mjs"] },
{ label: "responses-ws-proxy (server-ws.mjs dependency)", src: ["scripts", "dev", "responses-ws-proxy.mjs"], dest: ["responses-ws-proxy.mjs"] },
{ label: "runtime-env script", src: ["scripts", "build", "runtime-env.mjs"], dest: ["build", "runtime-env.mjs"] },
{ label: "bootstrap-env script", src: ["scripts", "build", "bootstrap-env.mjs"], dest: ["build", "bootstrap-env.mjs"] },
{ label: "healthcheck script", src: ["scripts", "dev", "healthcheck.mjs"], dest: ["healthcheck.mjs"] },
{
label: "peer-stamp helper (server-ws.mjs dependency)",
src: ["scripts", "dev", "peer-stamp.mjs"],
dest: ["peer-stamp.mjs"],
},
{
label: "responses-ws-proxy (server-ws.mjs dependency)",
src: ["scripts", "dev", "responses-ws-proxy.mjs"],
dest: ["responses-ws-proxy.mjs"],
},
{
label: "webdav-handler (server-ws.mjs dependency)",
src: ["scripts", "dev", "webdav-handler.mjs"],
dest: ["webdav-handler.mjs"],
},
{
label: "runtime-env script",
src: ["scripts", "build", "runtime-env.mjs"],
dest: ["build", "runtime-env.mjs"],
},
{
label: "bootstrap-env script",
src: ["scripts", "build", "bootstrap-env.mjs"],
dest: ["build", "bootstrap-env.mjs"],
},
{
label: "healthcheck script",
src: ["scripts", "dev", "healthcheck.mjs"],
dest: ["healthcheck.mjs"],
},
{ label: "public directory", src: ["public"], dest: ["public"] },
{ label: "playwright-core (dynamic import by gemini-web executor)", src: ["node_modules", "playwright-core"], dest: ["node_modules", "playwright-core"] },
{ label: "sqlite-vec wrapper (vector memory - loaded at runtime via createRequire)", src: ["node_modules", "sqlite-vec"], dest: ["node_modules", "sqlite-vec"] },
{
label: "playwright-core (dynamic import by gemini-web executor)",
src: ["node_modules", "playwright-core"],
dest: ["node_modules", "playwright-core"],
},
{
label: "sqlite-vec wrapper (vector memory - loaded at runtime via createRequire)",
src: ["node_modules", "sqlite-vec"],
dest: ["node_modules", "sqlite-vec"],
},
// sqlite-vec's native vec0.so lives in a platform-specific package resolved at
// runtime via require.resolve(). Next.js does NOT trace it into the standalone
// (the externalized wrapper is copied, but its optional platform dep is missed -

View File

@@ -42,6 +42,7 @@ export const APP_STAGING_ALLOWED_EXACT_PATHS: string[] = [
"scripts/dev/sync-env.mjs",
"server.js",
"server-ws.mjs",
"webdav-handler.mjs",
];
export const APP_STAGING_ALLOWED_PATH_PREFIXES: string[] = [
@@ -120,6 +121,7 @@ export const PACK_ARTIFACT_REQUIRED_PATHS: string[] = [
"dist/server-ws.mjs",
"dist/responses-ws-proxy.mjs",
"dist/peer-stamp.mjs",
"dist/webdav-handler.mjs",
"bin/cli/program.mjs",
"bin/mcp-server.mjs",
"bin/nodeRuntimeSupport.mjs",

View File

@@ -56,6 +56,14 @@ test("findUnexpectedArtifactPaths flags app pack files outside the allowlist", (
assert.deepEqual(unexpectedPaths, ["dist/scripts/build/prepublish.mjs", "docs/extra.md"]);
});
test("webdav-handler.mjs is allowed in staging dist/ (server-ws.mjs dependency, missed in 3.8.22 build)", () => {
const unexpectedPaths = findUnexpectedArtifactPaths(["webdav-handler.mjs"], {
exactPaths: APP_STAGING_ALLOWED_EXACT_PATHS,
prefixPaths: APP_STAGING_ALLOWED_PATH_PREFIXES,
});
assert.deepEqual(unexpectedPaths, []);
});
test("setupPolyfill.ts is allowed in the tarball (bin/omniroute.mjs imports it at startup)", () => {
const unexpectedPaths = findUnexpectedArtifactPaths(["open-sse/utils/setupPolyfill.ts"], {
exactPaths: PACK_ARTIFACT_ALLOWED_EXACT_PATHS,
@@ -89,6 +97,7 @@ test("findMissingArtifactPaths flags missing root runtime files in the tarball",
"dist/peer-stamp.mjs",
"dist/responses-ws-proxy.mjs",
"dist/server-ws.mjs",
"dist/webdav-handler.mjs",
"scripts/build/native-binary-compat.mjs",
"src/shared/utils/nodeRuntimeSupport.ts",
]);