


























@@ -1,7 +1,7 @@
11import fs from "node:fs";
22import path from "node:path";
33import { fileURLToPath, pathToFileURL } from "node:url";
4-import { afterEach, describe, expect, it, vi } from "vitest";
4+import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
55import {
66clearBundledRuntimeDependencyNodePaths,
77resolveBundledRuntimeDependencyInstallRoot,
@@ -15,19 +15,17 @@ import {
1515setFacadeLoaderJitiFactoryForTest,
1616} from "./facade-loader.js";
1717import { listImportedBundledPluginFacadeIds as listImportedFacadeRuntimeIds } from "./facade-runtime.js";
18-import {
19-createBundledPluginPublicSurfaceFixture,
20-createPluginSdkTestHarness,
21-createThrowingBundledPluginPublicSurfaceFixture,
22-} from "./test-helpers.js";
18+import { createPluginSdkTestHarness } from "./test-helpers.js";
23192420const { createTempDirSync } = createPluginSdkTestHarness();
2521const originalBundledPluginsDir = process.env.OPENCLAW_BUNDLED_PLUGINS_DIR;
2622const originalDisableBundledPlugins = process.env.OPENCLAW_DISABLE_BUNDLED_PLUGINS;
2723const originalPluginStageDir = process.env.OPENCLAW_PLUGIN_STAGE_DIR;
24+const trustedBundledFixturesRoot = path.resolve("dist-runtime", "extensions");
2825const FACADE_LOADER_GLOBAL = "__openclawTestLoadBundledPluginPublicSurfaceModuleSync";
2926const STAGED_RUNTIME_DEP_NAME = "openclaw-facade-loader-runtime-dep";
3027type FacadeLoaderJitiFactory = NonNullable<Parameters<typeof setFacadeLoaderJitiFactoryForTest>[0]>;
28+const trustedBundledFixtureDirs: string[] = [];
31293230function forceNodeRuntimeVersionsForTest(): () => void {
3331const originalVersions = process.versions;
@@ -47,17 +45,52 @@ function forceNodeRuntimeVersionsForTest(): () => void {
4745};
4846}
494748+function createTrustedBundledFixtureRoot(prefix: string): string {
49+fs.mkdirSync(trustedBundledFixturesRoot, { recursive: true });
50+const rootDir = fs.mkdtempSync(path.join(trustedBundledFixturesRoot, `.${prefix}`));
51+trustedBundledFixtureDirs.push(rootDir);
52+return rootDir;
53+}
54+55+function writePluginPackageJson(pluginDir: string, name = "demo"): void {
56+writeJsonFile(path.join(pluginDir, "package.json"), {
57+name: `@openclaw/plugin-${name}`,
58+version: "0.0.0",
59+type: "module",
60+});
61+}
62+5063function createBundledPluginDir(prefix: string, marker: string): string {
51-return createBundledPluginPublicSurfaceFixture({ createTempDirSync, marker, prefix });
64+const rootDir = createTrustedBundledFixtureRoot(prefix);
65+const pluginDir = path.join(rootDir, "demo");
66+fs.mkdirSync(pluginDir, { recursive: true });
67+writePluginPackageJson(pluginDir);
68+fs.writeFileSync(
69+path.join(pluginDir, "api.js"),
70+`export const marker = ${JSON.stringify(marker)};\n`,
71+"utf8",
72+);
73+return rootDir;
5274}
53755476function createThrowingPluginDir(prefix: string): string {
55-return createThrowingBundledPluginPublicSurfaceFixture({ createTempDirSync, prefix });
77+const rootDir = createTrustedBundledFixtureRoot(prefix);
78+const pluginDir = path.join(rootDir, "bad");
79+fs.mkdirSync(pluginDir, { recursive: true });
80+writePluginPackageJson(pluginDir, "bad");
81+fs.writeFileSync(
82+path.join(pluginDir, "api.js"),
83+`throw new Error("plugin load failure");\n`,
84+"utf8",
85+);
86+return rootDir;
5687}
57885889function createCircularPluginDir(prefix: string): string {
59-const rootDir = createTempDirSync(prefix);
60-fs.mkdirSync(path.join(rootDir, "demo"), { recursive: true });
90+const rootDir = createTrustedBundledFixtureRoot(prefix);
91+const pluginDir = path.join(rootDir, "demo");
92+fs.mkdirSync(pluginDir, { recursive: true });
93+writePluginPackageJson(pluginDir);
6194fs.writeFileSync(
6295path.join(rootDir, "facade.mjs"),
6396[
@@ -71,14 +104,14 @@ function createCircularPluginDir(prefix: string): string {
71104"utf8",
72105);
73106fs.writeFileSync(
74-path.join(rootDir, "demo", "helper.js"),
107+path.join(pluginDir, "helper.js"),
75108['import { marker } from "../facade.mjs";', "export const circularMarker = marker;", ""].join(
76109"\n",
77110),
78111"utf8",
79112);
80113fs.writeFileSync(
81-path.join(rootDir, "demo", "api.js"),
114+path.join(pluginDir, "api.js"),
82115['import "./helper.js";', 'export const marker = "circular-ok";', ""].join("\n"),
83116"utf8",
84117);
@@ -102,21 +135,17 @@ function createPackagedBundledPluginDirWithStagedRuntimeDep(params: {
102135pluginRoot: string;
103136stageRoot: string;
104137} {
105-const packageRoot = createTempDirSync(params.prefix);
106-const pluginRoot = path.join(packageRoot, "dist", "extensions", "demo");
107-const stageRoot = path.join(packageRoot, "stage");
138+const packageRoot = path.resolve(".");
139+const pluginRoot = path.join(trustedBundledFixturesRoot, "demo");
140+const stageRoot = createTempDirSync(`${params.prefix}stage-`);
108141const env = {
109142 ...process.env,
110-OPENCLAW_BUNDLED_PLUGINS_DIR: path.join(packageRoot, "dist", "extensions"),
143+OPENCLAW_BUNDLED_PLUGINS_DIR: trustedBundledFixturesRoot,
111144OPENCLAW_PLUGIN_STAGE_DIR: stageRoot,
112145};
146+trustedBundledFixtureDirs.push(pluginRoot);
113147fs.mkdirSync(pluginRoot, { recursive: true });
114148115-writeJsonFile(path.join(packageRoot, "package.json"), {
116-name: "openclaw",
117-version: "0.0.0",
118-type: "module",
119-});
120149writeJsonFile(path.join(pluginRoot, "package.json"), {
121150name: "@openclaw/plugin-demo",
122151version: "0.0.0",
@@ -154,7 +183,7 @@ function createPackagedBundledPluginDirWithStagedRuntimeDep(params: {
154183);
155184156185return {
157-bundledPluginsDir: path.join(packageRoot, "dist", "extensions"),
186+bundledPluginsDir: trustedBundledFixturesRoot,
158187 env,
159188 installRoot,
160189 modulePath,
@@ -163,8 +192,18 @@ function createPackagedBundledPluginDirWithStagedRuntimeDep(params: {
163192 stageRoot,
164193};
165194}
195+196+beforeEach(() => {
197+delete process.env.OPENCLAW_BUNDLED_PLUGINS_DIR;
198+delete process.env.OPENCLAW_DISABLE_BUNDLED_PLUGINS;
199+delete process.env.OPENCLAW_PLUGIN_STAGE_DIR;
200+});
201+166202afterEach(() => {
167203vi.restoreAllMocks();
204+for (const dir of trustedBundledFixtureDirs.splice(0)) {
205+fs.rmSync(dir, { recursive: true, force: true });
206+}
168207resetFacadeLoaderStateForTest();
169208setFacadeLoaderJitiFactoryForTest(undefined);
170209clearBundledRuntimeDependencyNodePaths();
@@ -187,7 +226,7 @@ afterEach(() => {
187226});
188227189228describe("plugin-sdk facade loader", () => {
190-it("honors bundled plugin dir overrides outside the package root", () => {
229+it("honors trusted bundled plugin dir overrides", () => {
191230const overrideA = createBundledPluginDir("openclaw-facade-loader-a-", "override-a");
192231const overrideB = createBundledPluginDir("openclaw-facade-loader-b-", "override-b");
193232@@ -251,11 +290,14 @@ describe("plugin-sdk facade loader", () => {
251290});
252291253292it("uses the runtime-supported Jiti boundary for Windows dist facade loads", () => {
254-const dir = createTempDirSync("openclaw-facade-loader-windows-dist-");
255-const bundledPluginsDir = path.join(dir, "dist");
256-fs.mkdirSync(path.join(bundledPluginsDir, "demo"), { recursive: true });
293+const bundledPluginsDir = createTrustedBundledFixtureRoot(
294+"openclaw-facade-loader-windows-dist-",
295+);
296+const pluginDir = path.join(bundledPluginsDir, "demo");
297+fs.mkdirSync(pluginDir, { recursive: true });
298+writePluginPackageJson(pluginDir);
257299fs.writeFileSync(
258-path.join(bundledPluginsDir, "demo", "api.js"),
300+path.join(pluginDir, "api.js"),
259301'export const marker = "windows-dist-ok";\n',
260302"utf8",
261303);
@@ -314,13 +356,15 @@ describe("plugin-sdk facade loader", () => {
314356expect(loaded.marker).toBe("facade:staged");
315357expect(fs.existsSync(path.join(fixture.pluginRoot, "node_modules"))).toBe(false);
316358expect(fs.realpathSync(fileURLToPath(loaded.moduleUrl))).toBe(
317-fs.realpathSync(path.join(fixture.installRoot, "dist", "extensions", "demo", "api.js")),
359+fs.realpathSync(
360+path.join(fixture.installRoot, "dist-runtime", "extensions", "demo", "api.js"),
361+),
318362);
319363});
320364321365it("loads built bundled async public surfaces through staged runtime deps", async () => {
322366const fixture = createPackagedBundledPluginDirWithStagedRuntimeDep({
323-marker: "async-staged",
367+marker: "staged",
324368prefix: "openclaw-facade-loader-built-async-",
325369});
326370@@ -333,9 +377,11 @@ describe("plugin-sdk facade loader", () => {
333377env: fixture.env,
334378});
335379336-expect(loaded.marker).toBe("facade:async-staged");
380+expect(loaded.marker).toBe("facade:staged");
337381expect(fs.realpathSync(fileURLToPath(loaded.moduleUrl))).toBe(
338-fs.realpathSync(path.join(fixture.installRoot, "dist", "extensions", "demo", "api.js")),
382+fs.realpathSync(
383+path.join(fixture.installRoot, "dist-runtime", "extensions", "demo", "api.js"),
384+),
339385);
340386});
341387此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。