mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:10:44 +00:00
refactor: trim channel plugin loader helpers
This commit is contained in:
@@ -3,7 +3,6 @@ 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";
|
||||
import { loadPluginManifestRegistry } from "../../plugins/manifest-registry.js";
|
||||
|
||||
vi.mock("../../plugins/bundled-dir.js", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("../../plugins/bundled-dir.js")>();
|
||||
@@ -92,6 +91,19 @@ function collectBundledChannelEntrypointOffenders(
|
||||
return offenders;
|
||||
}
|
||||
|
||||
function listSourceBundledPluginRoots(): string[] {
|
||||
const extensionsDir = path.resolve("extensions");
|
||||
return fs
|
||||
.readdirSync(extensionsDir, { withFileTypes: true })
|
||||
.filter((entry) => entry.isDirectory())
|
||||
.map((entry) => path.join(extensionsDir, entry.name))
|
||||
.filter(
|
||||
(entryPath) =>
|
||||
fs.existsSync(path.join(entryPath, "package.json")) ||
|
||||
fs.existsSync(path.join(entryPath, "openclaw.plugin.json")),
|
||||
);
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
vi.resetModules();
|
||||
vi.doUnmock("../../plugins/bundled-channel-runtime.js");
|
||||
@@ -104,9 +116,7 @@ afterEach(() => {
|
||||
});
|
||||
|
||||
describe("bundled channel entry shape guards", () => {
|
||||
const bundledPluginRoots = loadPluginManifestRegistry({ config: {} })
|
||||
.plugins.filter((plugin) => plugin.origin === "bundled")
|
||||
.map((plugin) => plugin.rootDir);
|
||||
const bundledPluginRoots = listSourceBundledPluginRoots();
|
||||
|
||||
it("treats missing bundled discovery results as empty", async () => {
|
||||
vi.doMock("../../plugins/bundled-channel-runtime.js", async (importOriginal) => {
|
||||
|
||||
@@ -15,11 +15,12 @@ import {
|
||||
import { normalizePluginsConfig } from "../../plugins/config-state.js";
|
||||
import { passesManifestOwnerBasePolicy } from "../../plugins/manifest-owner-policy.js";
|
||||
import { unwrapDefaultModuleExport } from "../../plugins/module-export.js";
|
||||
import { isJavaScriptModulePath } from "../../plugins/native-module-require.js";
|
||||
import type { PluginRuntime } from "../../plugins/runtime/types.js";
|
||||
import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js";
|
||||
import { resolveBundledChannelRootScope, type BundledChannelRootScope } from "./bundled-root.js";
|
||||
import { normalizeChannelMeta } from "./meta-normalization.js";
|
||||
import { isJavaScriptModulePath, loadChannelPluginModule } from "./module-loader.js";
|
||||
import { loadChannelPluginModule } from "./module-loader.js";
|
||||
import type { ChannelPlugin } from "./types.plugin.js";
|
||||
import type { ChannelId } from "./types.public.js";
|
||||
|
||||
|
||||
@@ -3,12 +3,8 @@ 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";
|
||||
import {
|
||||
isJavaScriptModulePath,
|
||||
resolveCompiledBundledModulePath,
|
||||
resolveExistingPluginModulePath,
|
||||
resolvePluginModuleCandidates,
|
||||
} from "./module-loader.js";
|
||||
import { isJavaScriptModulePath } from "../../plugins/native-module-require.js";
|
||||
import { resolveExistingPluginModulePath } from "./module-loader.js";
|
||||
|
||||
const tempDirs: string[] = [];
|
||||
|
||||
@@ -27,38 +23,12 @@ function createTempDir(): string {
|
||||
}
|
||||
|
||||
describe("channel plugin module loader helpers", () => {
|
||||
it("prefers compiled bundled dist output when present", () => {
|
||||
const rootDir = createTempDir();
|
||||
const runtimePath = path.join(rootDir, "dist-runtime", "entry.js");
|
||||
const compiledPath = path.join(rootDir, "dist", "entry.js");
|
||||
fs.mkdirSync(path.dirname(compiledPath), { recursive: true });
|
||||
fs.writeFileSync(compiledPath, "export {};\n", "utf8");
|
||||
|
||||
expect(resolveCompiledBundledModulePath(runtimePath)).toBe(compiledPath);
|
||||
});
|
||||
|
||||
it("keeps dist-runtime path when compiled bundled output is absent", () => {
|
||||
const rootDir = createTempDir();
|
||||
const runtimePath = path.join(rootDir, "dist-runtime", "entry.js");
|
||||
|
||||
expect(resolveCompiledBundledModulePath(runtimePath)).toBe(runtimePath);
|
||||
});
|
||||
|
||||
it("resolves plugin module candidates and picks the first existing extension", () => {
|
||||
it("resolves extensionless plugin module specifiers to the first existing extension", () => {
|
||||
const rootDir = createTempDir();
|
||||
const expectedPath = path.join(rootDir, "src", "checker.mts");
|
||||
fs.mkdirSync(path.dirname(expectedPath), { recursive: true });
|
||||
fs.writeFileSync(expectedPath, "export const ok = true;\n", "utf8");
|
||||
|
||||
expect(resolvePluginModuleCandidates(rootDir, "./src/checker")).toEqual([
|
||||
path.join(rootDir, "src", "checker"),
|
||||
path.join(rootDir, "src", "checker.ts"),
|
||||
path.join(rootDir, "src", "checker.mts"),
|
||||
path.join(rootDir, "src", "checker.js"),
|
||||
path.join(rootDir, "src", "checker.mjs"),
|
||||
path.join(rootDir, "src", "checker.cts"),
|
||||
path.join(rootDir, "src", "checker.cjs"),
|
||||
]);
|
||||
expect(resolveExistingPluginModulePath(rootDir, "./src/checker")).toBe(expectedPath);
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
getCachedPluginJitiLoader,
|
||||
type PluginJitiLoaderCache,
|
||||
} from "../../plugins/jiti-loader-cache.js";
|
||||
export { isJavaScriptModulePath } from "../../plugins/native-module-require.js";
|
||||
|
||||
const jitiLoaders: PluginJitiLoaderCache = new Map();
|
||||
|
||||
@@ -21,17 +20,7 @@ function loadModule(modulePath: string, tryNative?: boolean) {
|
||||
});
|
||||
}
|
||||
|
||||
export function resolveCompiledBundledModulePath(modulePath: string): string {
|
||||
const compiledDistModulePath = modulePath.replace(
|
||||
`${path.sep}dist-runtime${path.sep}`,
|
||||
`${path.sep}dist${path.sep}`,
|
||||
);
|
||||
return compiledDistModulePath !== modulePath && fs.existsSync(compiledDistModulePath)
|
||||
? compiledDistModulePath
|
||||
: modulePath;
|
||||
}
|
||||
|
||||
export function resolvePluginModuleCandidates(rootDir: string, specifier: string): string[] {
|
||||
function resolvePluginModuleCandidates(rootDir: string, specifier: string): string[] {
|
||||
const normalizedSpecifier = specifier.replace(/\\/g, "/");
|
||||
const resolvedPath = path.resolve(rootDir, normalizedSpecifier);
|
||||
const ext = path.extname(resolvedPath);
|
||||
|
||||
@@ -5,12 +5,9 @@ import {
|
||||
listChannelCatalogEntries,
|
||||
type PluginChannelCatalogEntry,
|
||||
} from "../../plugins/channel-catalog-registry.js";
|
||||
import { isJavaScriptModulePath } from "../../plugins/native-module-require.js";
|
||||
import { normalizeOptionalString } from "../../shared/string-coerce.js";
|
||||
import {
|
||||
isJavaScriptModulePath,
|
||||
loadChannelPluginModule,
|
||||
resolveExistingPluginModulePath,
|
||||
} from "./module-loader.js";
|
||||
import { loadChannelPluginModule, resolveExistingPluginModulePath } from "./module-loader.js";
|
||||
|
||||
type ChannelPackageStateChecker = (params: {
|
||||
cfg: OpenClawConfig;
|
||||
|
||||
Reference in New Issue
Block a user