import type { OpenClawConfig } from "../../../src/config/config.js"; import { createPluginRegistry, type PluginRecord } from "../../../src/plugins/registry.js"; import type { PluginRuntime } from "../../../src/plugins/runtime/types.js"; import { createPluginRecord } from "../../../src/plugins/status.test-helpers.js"; import type { OpenClawPluginApi } from "../../../src/plugins/types.js"; export { registerProviderPlugins as registerProviders, requireRegisteredProvider as requireProvider, } from "../../../src/test-utils/plugin-registration.js"; export function uniqueSortedStrings(values: readonly string[]) { return [...new Set(values)].toSorted((left, right) => left.localeCompare(right)); } function formatImportSideEffectCall(args: readonly unknown[]): string { if (args.length === 0) { return "(no args)"; } return args .map((arg) => { try { return JSON.stringify(arg); } catch { return String(arg); } }) .join(", "); } export function assertNoImportTimeSideEffects(params: { moduleId: string; forbiddenSeam: string; calls: readonly (readonly unknown[])[]; why: string; fixHint: string; }) { if (params.calls.length === 0) { return; } const observedCalls = params.calls .slice(0, 3) .map((call, index) => ` ${index + 1}. ${formatImportSideEffectCall(call)}`) .join("\n"); throw new Error( [ `[runtime contract] ${params.moduleId} touched ${params.forbiddenSeam} during module import.`, `why this is banned: ${params.why}`, `expected fix: ${params.fixHint}`, `observed calls (${params.calls.length}):`, observedCalls, ].join("\n"), ); } export function createPluginRegistryFixture(config = {} as OpenClawConfig) { return { config, registry: createPluginRegistry({ logger: { info() {}, warn() {}, error() {}, debug() {}, }, runtime: {} as PluginRuntime, }), }; } export function registerTestPlugin(params: { registry: ReturnType; config: OpenClawConfig; record: PluginRecord; register(api: OpenClawPluginApi): void; }) { params.registry.registry.plugins.push(params.record); params.register( params.registry.createApi(params.record, { config: params.config, }), ); } export function registerVirtualTestPlugin(params: { registry: ReturnType; config: OpenClawConfig; id: string; name: string; source?: string; kind?: PluginRecord["kind"]; contracts?: PluginRecord["contracts"]; register(this: void, api: OpenClawPluginApi): void; }) { registerTestPlugin({ registry: params.registry, config: params.config, record: createPluginRecord({ id: params.id, name: params.name, source: params.source ?? `/virtual/${params.id}/index.ts`, ...(params.kind ? { kind: params.kind } : {}), ...(params.contracts ? { contracts: params.contracts } : {}), }), register: params.register, }); }