UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

142 lines (141 loc) 5.4 kB
import { i as openRootFileSync } from "./root-file-jRMCpJW4.js"; import "./boundary-file-read-CBe_wA_B.js"; import { n as resolveBundledPluginsDir } from "./bundled-dir-CG-NYRXR.js"; import { n as getCachedPluginModuleLoader } from "./plugin-module-loader-cache-lz0qhu-X.js"; import { u as resolveLoaderPackageRoot } from "./sdk-alias-ZgondhPg.js"; import { n as resolveBundledFacadeModuleLocation } from "./facade-resolution-shared-CLzcjb4a.js"; import { fileURLToPath } from "node:url"; import fs from "node:fs"; import path from "node:path"; //#region src/plugin-sdk/facade-loader.ts const CURRENT_MODULE_PATH = fileURLToPath(import.meta.url); const moduleLoaders = /* @__PURE__ */ new Map(); const loadedFacadeModules = /* @__PURE__ */ new Map(); const loadedFacadePluginIds = /* @__PURE__ */ new Set(); let cachedOpenClawPackageRoot; function getOpenClawPackageRoot() { if (cachedOpenClawPackageRoot) return cachedOpenClawPackageRoot; cachedOpenClawPackageRoot = resolveLoaderPackageRoot({ modulePath: fileURLToPath(import.meta.url), moduleUrl: import.meta.url }) ?? fileURLToPath(new URL("../..", import.meta.url)); return cachedOpenClawPackageRoot; } function resolveFacadeModuleLocation(params) { const bundledPluginsDir = resolveBundledPluginsDir(params.env ?? process.env); return resolveBundledFacadeModuleLocation({ ...params, currentModulePath: CURRENT_MODULE_PATH, packageRoot: getOpenClawPackageRoot(), bundledPluginsDir }); } function getModuleLoader(modulePath) { return getCachedPluginModuleLoader({ cache: moduleLoaders, modulePath, importerUrl: import.meta.url, preferBuiltDist: true, loaderFilename: import.meta.url }); } function createLazyFacadeValueLoader(load) { let loaded = false; let value; return () => { if (!loaded) { value = load(); loaded = true; } return value; }; } function createLazyFacadeProxyValue(params) { const resolve = createLazyFacadeValueLoader(params.load); return new Proxy(params.target, { defineProperty(_target, property, descriptor) { return Reflect.defineProperty(resolve(), property, descriptor); }, deleteProperty(_target, property) { return Reflect.deleteProperty(resolve(), property); }, get(_target, property, receiver) { return Reflect.get(resolve(), property, receiver); }, getOwnPropertyDescriptor(_target, property) { return Reflect.getOwnPropertyDescriptor(resolve(), property); }, getPrototypeOf() { return Reflect.getPrototypeOf(resolve()); }, has(_target, property) { return Reflect.has(resolve(), property); }, isExtensible() { return Reflect.isExtensible(resolve()); }, ownKeys() { return Reflect.ownKeys(resolve()); }, preventExtensions() { return Reflect.preventExtensions(resolve()); }, set(_target, property, value, receiver) { return Reflect.set(resolve(), property, value, receiver); }, setPrototypeOf(_target, prototype) { return Reflect.setPrototypeOf(resolve(), prototype); } }); } /** Create an object proxy that loads the underlying facade only on first property access. */ function createLazyFacadeObjectValue(load) { return createLazyFacadeProxyValue({ load, target: {} }); } /** Load and cache a facade module after verifying it is inside its declared boundary root. */ function loadFacadeModuleAtLocationSync(params) { const location = params.location; const cached = loadedFacadeModules.get(location.modulePath); if (cached) return cached; const opened = openRootFileSync({ absolutePath: location.modulePath, rootPath: location.boundaryRoot, boundaryLabel: location.boundaryRoot === getOpenClawPackageRoot() ? "OpenClaw package root" : (() => { const bundledDir = resolveBundledPluginsDir(); return bundledDir && path.resolve(location.boundaryRoot) === path.resolve(bundledDir) ? "bundled plugin directory" : "plugin root"; })(), rejectHardlinks: false }); if (!opened.ok) throw new Error(`Unable to open bundled plugin public surface ${location.modulePath}`, { cause: opened.error }); fs.closeSync(opened.fd); const sentinel = {}; loadedFacadeModules.set(location.modulePath, sentinel); let loaded; try { loaded = params.loadModule?.(location.modulePath) ?? getModuleLoader(location.modulePath)(location.modulePath); Object.assign(sentinel, loaded); loadedFacadePluginIds.add(typeof params.trackedPluginId === "function" ? params.trackedPluginId() : params.trackedPluginId); } catch (err) { loadedFacadeModules.delete(location.modulePath); throw err; } return sentinel; } /** Resolve and synchronously load a bundled plugin public surface by plugin dir and artifact name. */ function loadBundledPluginPublicSurfaceModuleSync(params) { const location = resolveFacadeModuleLocation(params); if (!location) throw new Error(`Unable to resolve bundled plugin public surface ${params.dirName}/${params.artifactBasename}`); return loadFacadeModuleAtLocationSync({ location, trackedPluginId: params.trackedPluginId ?? params.dirName }); } /** List plugin ids whose public facades have been loaded in this process. */ function listImportedBundledPluginFacadeIds() { return [...loadedFacadePluginIds].toSorted((left, right) => left.localeCompare(right)); } //#endregion export { loadFacadeModuleAtLocationSync as i, listImportedBundledPluginFacadeIds as n, loadBundledPluginPublicSurfaceModuleSync as r, createLazyFacadeObjectValue as t };