mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-17 10:21:37 +00:00
104 lines
4.5 KiB
TypeScript
104 lines
4.5 KiB
TypeScript
import fs from "node:fs";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { afterEach, describe, expect, it } from "vitest";
|
|
import { fingerprintPluginRuntimeArtifact } from "./plugin-runtime-artifact-identity.js";
|
|
|
|
const tempDirs: string[] = [];
|
|
|
|
function createPluginFixture(): { rootDir: string; source: string } {
|
|
const rootDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-plugin-artifact-"));
|
|
tempDirs.push(rootDir);
|
|
const source = path.join(rootDir, "dist", "index.js");
|
|
fs.mkdirSync(path.dirname(source), { recursive: true });
|
|
fs.writeFileSync(source, 'export { run } from "./runtime.js";\n', "utf8");
|
|
fs.writeFileSync(path.join(rootDir, "dist", "runtime.js"), "export const run = () => 1;\n");
|
|
fs.writeFileSync(path.join(rootDir, "package.json"), '{"name":"fixture"}\n');
|
|
return { rootDir, source };
|
|
}
|
|
|
|
afterEach(() => {
|
|
for (const dir of tempDirs.splice(0)) {
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
describe("fingerprintPluginRuntimeArtifact", () => {
|
|
it("is stable for unchanged files and changes with plugin-owned imported code", () => {
|
|
const fixture = createPluginFixture();
|
|
const record = { pluginId: "fixture", origin: "global" as const, ...fixture };
|
|
const first = fingerprintPluginRuntimeArtifact(record);
|
|
|
|
expect(fingerprintPluginRuntimeArtifact(record)).toBe(first);
|
|
|
|
fs.writeFileSync(
|
|
path.join(fixture.rootDir, "dist", "runtime.js"),
|
|
"export const run = () => 2;\n",
|
|
);
|
|
expect(fingerprintPluginRuntimeArtifact(record)).not.toBe(first);
|
|
});
|
|
|
|
it("keeps dependency stores outside the plugin-owned artifact identity", () => {
|
|
const fixture = createPluginFixture();
|
|
const dependency = path.join(fixture.rootDir, "node_modules", "dependency", "index.js");
|
|
fs.mkdirSync(path.dirname(dependency), { recursive: true });
|
|
fs.writeFileSync(dependency, "export const value = 1;\n");
|
|
const record = { pluginId: "fixture", origin: "global" as const, ...fixture };
|
|
const first = fingerprintPluginRuntimeArtifact(record);
|
|
|
|
fs.writeFileSync(dependency, "export const value = 2;\n");
|
|
expect(fingerprintPluginRuntimeArtifact(record)).toBe(first);
|
|
});
|
|
|
|
it("hashes canonical dist content when the registry points at dist-runtime", () => {
|
|
const packageRoot = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-plugin-artifact-"));
|
|
tempDirs.push(packageRoot);
|
|
const stagingRoot = path.join(packageRoot, "dist-runtime", "extensions", "fixture");
|
|
const canonicalRoot = path.join(packageRoot, "dist", "extensions", "fixture");
|
|
const stagingSource = path.join(stagingRoot, "index.js");
|
|
const canonicalSource = path.join(canonicalRoot, "index.js");
|
|
fs.mkdirSync(stagingRoot, { recursive: true });
|
|
fs.mkdirSync(canonicalRoot, { recursive: true });
|
|
fs.writeFileSync(stagingSource, "export const revision = 'staging-1';\n");
|
|
fs.writeFileSync(canonicalSource, "export const revision = 'canonical-1';\n");
|
|
const record = {
|
|
pluginId: "fixture",
|
|
origin: "bundled" as const,
|
|
rootDir: stagingRoot,
|
|
source: stagingSource,
|
|
};
|
|
const first = fingerprintPluginRuntimeArtifact(record);
|
|
|
|
fs.writeFileSync(stagingSource, "export const revision = 'staging-2';\n");
|
|
expect(fingerprintPluginRuntimeArtifact(record)).toBe(first);
|
|
|
|
fs.writeFileSync(canonicalSource, "export const revision = 'canonical-2';\n");
|
|
expect(fingerprintPluginRuntimeArtifact(record)).not.toBe(first);
|
|
});
|
|
|
|
it("hashes source when a bundled plugin opts out of core dist", () => {
|
|
const rootDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-plugin-artifact-"));
|
|
tempDirs.push(rootDir);
|
|
const source = path.join(rootDir, "index.ts");
|
|
const staleDistSource = path.join(rootDir, "dist", "index.js");
|
|
fs.mkdirSync(path.dirname(staleDistSource), { recursive: true });
|
|
fs.writeFileSync(source, "export const revision = 'source-1';\n");
|
|
fs.writeFileSync(staleDistSource, "export const revision = 'stale-1';\n");
|
|
const record = {
|
|
pluginId: "fixture",
|
|
origin: "bundled" as const,
|
|
rootDir,
|
|
source,
|
|
packageBuild: { bundledDist: false },
|
|
};
|
|
const first = fingerprintPluginRuntimeArtifact(record);
|
|
|
|
fs.writeFileSync(staleDistSource, "export const revision = 'stale-2';\n");
|
|
expect(fingerprintPluginRuntimeArtifact(record)).not.toBe(first);
|
|
|
|
const afterStaleChange = fingerprintPluginRuntimeArtifact(record);
|
|
fs.writeFileSync(source, "export const revision = 'source-2';\n");
|
|
expect(fingerprintPluginRuntimeArtifact(record)).not.toBe(afterStaleChange);
|
|
});
|
|
});
|