mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-07 08:20:42 +00:00
177 lines
4.3 KiB
TypeScript
177 lines
4.3 KiB
TypeScript
import fs from "node:fs";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { importFreshModule } from "openclaw/plugin-sdk/test-fixtures";
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
|
|
const tempDirs: string[] = [];
|
|
|
|
function makeTempDir() {
|
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-plugin-loader-"));
|
|
tempDirs.push(dir);
|
|
return dir;
|
|
}
|
|
|
|
function writeBundledPluginFixture(id: string) {
|
|
const pluginRoot = makeTempDir();
|
|
fs.writeFileSync(
|
|
path.join(pluginRoot, "openclaw.plugin.json"),
|
|
JSON.stringify(
|
|
{
|
|
id,
|
|
configSchema: {
|
|
type: "object",
|
|
additionalProperties: false,
|
|
properties: {},
|
|
},
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
"utf-8",
|
|
);
|
|
fs.writeFileSync(
|
|
path.join(pluginRoot, "index.cjs"),
|
|
`module.exports = { id: ${JSON.stringify(id)}, register() {} };`,
|
|
"utf-8",
|
|
);
|
|
return pluginRoot;
|
|
}
|
|
|
|
function writePackagedPluginFixture(id: string) {
|
|
const pluginRoot = makeTempDir();
|
|
fs.writeFileSync(
|
|
path.join(pluginRoot, "package.json"),
|
|
JSON.stringify(
|
|
{
|
|
name: id,
|
|
type: "commonjs",
|
|
openclaw: {
|
|
extensions: ["./index.cjs"],
|
|
},
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
"utf-8",
|
|
);
|
|
fs.writeFileSync(
|
|
path.join(pluginRoot, "openclaw.plugin.json"),
|
|
JSON.stringify(
|
|
{
|
|
id,
|
|
configSchema: {
|
|
type: "object",
|
|
additionalProperties: false,
|
|
properties: {},
|
|
},
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
"utf-8",
|
|
);
|
|
fs.writeFileSync(
|
|
path.join(pluginRoot, "index.cjs"),
|
|
`module.exports = { id: ${JSON.stringify(id)}, register() {} };`,
|
|
"utf-8",
|
|
);
|
|
return pluginRoot;
|
|
}
|
|
|
|
afterEach(() => {
|
|
vi.resetModules();
|
|
vi.doUnmock("./plugin-module-loader-cache.js");
|
|
delete process.env.OPENCLAW_BUNDLED_PLUGINS_DIR;
|
|
for (const dir of tempDirs.splice(0)) {
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
function mockSourceLoaderCalls() {
|
|
const sourceLoaderCalls: Array<{ modulePath: string; loaderFilename?: string }> = [];
|
|
vi.doMock("./plugin-module-loader-cache.js", async (importOriginal) => {
|
|
const actual = await importOriginal<typeof import("./plugin-module-loader-cache.js")>();
|
|
return {
|
|
...actual,
|
|
getCachedPluginSourceModuleLoader: vi.fn((params) => {
|
|
sourceLoaderCalls.push({
|
|
modulePath: params.modulePath,
|
|
loaderFilename: params.loaderFilename,
|
|
});
|
|
return vi.fn(() => ({
|
|
default: {
|
|
id: "source-fallback",
|
|
register() {},
|
|
},
|
|
}));
|
|
}),
|
|
};
|
|
});
|
|
return sourceLoaderCalls;
|
|
}
|
|
|
|
describe("createPluginModuleLoader", () => {
|
|
it("loads bundled JavaScript without creating a module loader", async () => {
|
|
const sourceLoaderCalls = mockSourceLoaderCalls();
|
|
|
|
const { loadOpenClawPlugins } = await importFreshModule<typeof import("./loader.js")>(
|
|
import.meta.url,
|
|
"./loader.js?scope=native-module-loader",
|
|
);
|
|
|
|
const pluginRoot = writeBundledPluginFixture("demo");
|
|
process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = pluginRoot;
|
|
|
|
loadOpenClawPlugins({
|
|
cache: false,
|
|
workspaceDir: pluginRoot,
|
|
onlyPluginIds: ["demo"],
|
|
config: {
|
|
plugins: {
|
|
entries: {
|
|
demo: {
|
|
enabled: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
expect(sourceLoaderCalls).toEqual([]);
|
|
});
|
|
|
|
it("loads packaged JavaScript without creating a module loader", async () => {
|
|
const sourceLoaderCalls = mockSourceLoaderCalls();
|
|
|
|
const { loadOpenClawPlugins } = await importFreshModule<typeof import("./loader.js")>(
|
|
import.meta.url,
|
|
"./loader.js?scope=packaged-native-module-loader",
|
|
);
|
|
|
|
const pluginRoot = writePackagedPluginFixture("npm-demo");
|
|
process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = makeTempDir();
|
|
|
|
const registry = loadOpenClawPlugins({
|
|
cache: false,
|
|
config: {
|
|
plugins: {
|
|
enabled: true,
|
|
load: {
|
|
paths: [pluginRoot],
|
|
},
|
|
allow: ["npm-demo"],
|
|
entries: {
|
|
"npm-demo": {
|
|
enabled: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
expect(registry.plugins.find((plugin) => plugin.id === "npm-demo")?.status).toBe("loaded");
|
|
expect(sourceLoaderCalls).toEqual([]);
|
|
});
|
|
});
|