build: avoid ambiguous runtime aliases

(cherry picked from commit c96e62d5ab)
This commit is contained in:
Peter Steinberger
2026-05-02 21:26:27 +01:00
parent 422f1fe9bb
commit 82dd68d299
2 changed files with 250 additions and 3 deletions

View File

@@ -5,7 +5,9 @@ import { discoverStaticExtensionAssets } from "../../scripts/lib/static-extensio
import {
copyStaticExtensionAssets,
listStaticExtensionAssetOutputs,
rewriteRootRuntimeImportsToStableAliases,
writeLegacyCliExitCompatChunks,
writeLegacyRootRuntimeCompatAliases,
writeStableRootRuntimeAliases,
} from "../../scripts/runtime-postbuild.mjs";
import { createScriptTestHarness } from "./test-helpers.js";
@@ -118,6 +120,138 @@ describe("runtime postbuild static assets", () => {
await expect(fs.stat(path.join(distDir, "library.js"))).rejects.toThrow();
});
it("does not write ambiguous stable aliases for colliding root runtime chunks", async () => {
const rootDir = createTempDir("openclaw-runtime-postbuild-");
const distDir = path.join(rootDir, "dist");
await fs.mkdir(distDir, { recursive: true });
await fs.writeFile(
path.join(distDir, "install.runtime-Aaa111.js"),
"export const pluginInstall = true;\n",
"utf8",
);
await fs.writeFile(
path.join(distDir, "install.runtime-Bbb222.js"),
"export const daemonInstall = true;\n",
"utf8",
);
await fs.writeFile(
path.join(distDir, "install.runtime.js"),
'export * from "./install.runtime-Stale.js";\n',
"utf8",
);
writeStableRootRuntimeAliases({ rootDir });
await expect(fs.stat(path.join(distDir, "install.runtime.js"))).rejects.toThrow();
});
it("rewrites root runtime imports to stable aliases", async () => {
const rootDir = createTempDir("openclaw-runtime-postbuild-");
const distDir = path.join(rootDir, "dist");
await fs.mkdir(distDir, { recursive: true });
await fs.writeFile(
path.join(distDir, "runtime-plugins.runtime-AbCd1234.js"),
"export const ready = true;\n",
"utf8",
);
await fs.writeFile(
path.join(distDir, "dispatch-OldHash.js"),
[
'const lazy = () => import("./runtime-plugins.runtime-AbCd1234.js");',
'import "./missing.runtime-Nope.js";',
"",
].join("\n"),
"utf8",
);
rewriteRootRuntimeImportsToStableAliases({ rootDir });
expect(await fs.readFile(path.join(distDir, "dispatch-OldHash.js"), "utf8")).toBe(
[
'const lazy = () => import("./runtime-plugins.runtime.js");',
'import "./missing.runtime-Nope.js";',
"",
].join("\n"),
);
});
it("keeps hashed imports when a stable runtime alias would collide", async () => {
const rootDir = createTempDir("openclaw-runtime-postbuild-");
const distDir = path.join(rootDir, "dist");
await fs.mkdir(distDir, { recursive: true });
await fs.writeFile(
path.join(distDir, "install.runtime-Aaa111.js"),
"export const pluginInstall = true;\n",
"utf8",
);
await fs.writeFile(
path.join(distDir, "install.runtime-Bbb222.js"),
"export const daemonInstall = true;\n",
"utf8",
);
await fs.writeFile(
path.join(distDir, "install-OldHash.js"),
[
'const pluginRuntime = () => import("./install.runtime-Aaa111.js");',
'const daemonRuntime = () => import("./install.runtime-Bbb222.js");',
"",
].join("\n"),
"utf8",
);
rewriteRootRuntimeImportsToStableAliases({ rootDir });
expect(await fs.readFile(path.join(distDir, "install-OldHash.js"), "utf8")).toBe(
[
'const pluginRuntime = () => import("./install.runtime-Aaa111.js");',
'const daemonRuntime = () => import("./install.runtime-Bbb222.js");',
"",
].join("\n"),
);
});
it("leaves stable alias files pointing at their hashed runtime chunks", async () => {
const rootDir = createTempDir("openclaw-runtime-postbuild-");
const distDir = path.join(rootDir, "dist");
await fs.mkdir(distDir, { recursive: true });
await fs.writeFile(
path.join(distDir, "runtime-plugins.runtime-AbCd1234.js"),
"export const ready = true;\n",
"utf8",
);
await fs.writeFile(
path.join(distDir, "runtime-plugins.runtime.js"),
'export * from "./runtime-plugins.runtime-AbCd1234.js";\n',
"utf8",
);
rewriteRootRuntimeImportsToStableAliases({ rootDir });
expect(await fs.readFile(path.join(distDir, "runtime-plugins.runtime.js"), "utf8")).toBe(
'export * from "./runtime-plugins.runtime-AbCd1234.js";\n',
);
});
it("writes compatibility aliases for previous release runtime chunk names", async () => {
const rootDir = createTempDir("openclaw-runtime-postbuild-");
const distDir = path.join(rootDir, "dist");
await fs.mkdir(distDir, { recursive: true });
await fs.writeFile(
path.join(distDir, "runtime-plugins.runtime.js"),
'export * from "./runtime-plugins.runtime-NewHash.js";\n',
"utf8",
);
writeLegacyRootRuntimeCompatAliases({ rootDir });
expect(
await fs.readFile(path.join(distDir, "runtime-plugins.runtime-fLHuT7Vs.js"), "utf8"),
).toBe('export * from "./runtime-plugins.runtime.js";\n');
expect(
await fs.readFile(path.join(distDir, "runtime-plugins.runtime-CNAfmQRG.js"), "utf8"),
).toBe('export * from "./runtime-plugins.runtime.js";\n');
});
it("writes legacy CLI exit compatibility chunks", async () => {
const rootDir = createTempDir("openclaw-runtime-postbuild-");