diff --git a/scripts/load-channel-config-surface.ts b/scripts/load-channel-config-surface.ts index 28a7985430d..f392331f9ce 100644 --- a/scripts/load-channel-config-surface.ts +++ b/scripts/load-channel-config-surface.ts @@ -12,10 +12,19 @@ import { type CreateJiti = typeof createJiti; +const jitiFactoryOverrideKey = Symbol.for("openclaw.channelConfigSurfaceJitiFactoryOverride"); const requireForJiti = createRequire(import.meta.url); let createJitiLoaderFactory: CreateJiti | undefined; function loadCreateJitiLoaderFactory(): CreateJiti { + const override = ( + globalThis as typeof globalThis & { + [jitiFactoryOverrideKey]?: CreateJiti; + } + )[jitiFactoryOverrideKey]; + if (override) { + return override; + } if (createJitiLoaderFactory) { return createJitiLoaderFactory; } diff --git a/src/config/load-channel-config-surface.test.ts b/src/config/load-channel-config-surface.test.ts index 39e4376b339..f4be5a8a146 100644 --- a/src/config/load-channel-config-surface.test.ts +++ b/src/config/load-channel-config-surface.test.ts @@ -1,9 +1,28 @@ import fs from "node:fs"; import path from "node:path"; +import type { createJiti as createJitiType } from "jiti"; import { importFreshModule } from "openclaw/plugin-sdk/test-fixtures"; -import { describe, expect, it, vi } from "vitest"; +import { afterEach, describe, expect, it, vi } from "vitest"; import { withTempDir } from "../test-helpers/temp-dir.js"; +const jitiFactoryOverrideKey = Symbol.for("openclaw.channelConfigSurfaceJitiFactoryOverride"); + +function stubChannelConfigSurfaceJitiFactory(createJiti: typeof createJitiType): void { + ( + globalThis as typeof globalThis & { + [jitiFactoryOverrideKey]?: typeof createJitiType; + } + )[jitiFactoryOverrideKey] = createJiti; +} + +afterEach(() => { + delete ( + globalThis as typeof globalThis & { + [jitiFactoryOverrideKey]?: typeof createJitiType; + } + )[jitiFactoryOverrideKey]; +}); + async function importLoaderWithMissingBun() { const spawnSync = vi.fn(() => ({ error: Object.assign(new Error("bun not found"), { code: "ENOENT" }), @@ -41,7 +60,7 @@ async function importLoaderWithFailingJitiAndWorkingBun() { throw new Error("jiti failed"); }); vi.doMock("node:child_process", () => ({ spawnSync })); - vi.doMock("jiti", () => ({ createJiti })); + stubChannelConfigSurfaceJitiFactory(createJiti as typeof createJitiType); try { const imported = await importFreshModule< @@ -54,7 +73,6 @@ async function importLoaderWithFailingJitiAndWorkingBun() { }; } finally { vi.doUnmock("node:child_process"); - vi.doUnmock("jiti"); } } diff --git a/src/plugin-sdk/channel-entry-contract.test.ts b/src/plugin-sdk/channel-entry-contract.test.ts index 154460da047..dee47a35e71 100644 --- a/src/plugin-sdk/channel-entry-contract.test.ts +++ b/src/plugin-sdk/channel-entry-contract.test.ts @@ -4,11 +4,15 @@ import path from "node:path"; import { pathToFileURL } from "node:url"; import { importFreshModule } from "openclaw/plugin-sdk/test-fixtures"; import { afterEach, describe, expect, it, vi } from "vitest"; +import type { PluginModuleLoaderFactory } from "../plugins/plugin-module-loader-cache.js"; import type { PluginRuntime } from "../plugins/runtime/types.js"; import type { OpenClawPluginApi, PluginRegistrationMode } from "../plugins/types.js"; import { defineBundledChannelEntry, loadBundledEntryExportSync } from "./channel-entry-contract.js"; const tempDirs: string[] = []; +const pluginModuleLoaderJitiFactoryOverrideKey = Symbol.for( + "openclaw.pluginModuleLoaderJitiFactoryOverride", +); afterEach(() => { for (const dir of tempDirs.splice(0)) { @@ -17,8 +21,21 @@ afterEach(() => { vi.resetModules(); vi.doUnmock("jiti"); vi.unstubAllEnvs(); + delete ( + globalThis as typeof globalThis & { + [pluginModuleLoaderJitiFactoryOverrideKey]?: PluginModuleLoaderFactory; + } + )[pluginModuleLoaderJitiFactoryOverrideKey]; }); +function stubPluginModuleLoaderJitiFactory(createJiti: PluginModuleLoaderFactory): void { + ( + globalThis as typeof globalThis & { + [pluginModuleLoaderJitiFactoryOverrideKey]?: PluginModuleLoaderFactory; + } + )[pluginModuleLoaderJitiFactoryOverrideKey] = createJiti; +} + function createApi(registrationMode: PluginRegistrationMode): OpenClawPluginApi { return { registrationMode, @@ -269,9 +286,7 @@ describe("loadBundledEntryExportSync", () => { it("keeps Windows dist sidecar loads off source-transform loading", async () => { const createJiti = vi.fn(() => vi.fn(() => ({ load: 42 }))); - vi.doMock("jiti", () => ({ - createJiti, - })); + stubPluginModuleLoaderJitiFactory(createJiti as PluginModuleLoaderFactory); const platformSpy = vi.spyOn(process, "platform", "get").mockReturnValue("win32"); try { @@ -313,9 +328,7 @@ describe("loadBundledEntryExportSync", () => { fs.writeFileSync(openedFdPath, "opened\n", "utf8"); const jitiLoad = vi.fn(() => ({ load: 42 })); const createJiti = vi.fn(() => jitiLoad); - vi.doMock("jiti", () => ({ - createJiti, - })); + stubPluginModuleLoaderJitiFactory(createJiti as PluginModuleLoaderFactory); vi.doMock("../infra/boundary-file-read.js", () => ({ openBoundaryFileSync: () => ({ ok: true,