UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

131 lines (130 loc) • 6.71 kB
import { l as normalizeOptionalString } from "./string-coerce-1VuiLaaR.mjs"; import { p as normalizeTrimmedStringList, y as uniqueStrings } from "./string-normalization-CECOqf64.mjs"; import { r as isPathInside } from "./path-guards-CH7noY0Z.mjs"; import { t as PUBLIC_SURFACE_SOURCE_EXTENSIONS } from "./package-entrypoints-DCjwjOnD.mjs"; import fs from "node:fs"; import path from "node:path"; //#region src/plugins/bundled-plugin-scan.ts /** Scans bundled plugin source/build roots and derives public/runtime artifacts from manifests. */ const RUNTIME_SIDECAR_ARTIFACTS = /* @__PURE__ */ new Set([ "helper-api.js", "light-runtime-api.js", "qa-runner-api.js", "runtime-api.js", "runtime-setter-api.js", "thread-bindings-runtime.js" ]); /** Converts a source entry path to its built JavaScript artifact path. */ function rewriteBundledPluginEntryToBuiltPath(entry) { if (!entry) return; return entry.replace(/^\.\//u, "").replace(/\.[^.]+$/u, ".js"); } function isTopLevelPublicSurfaceSource(name) { if (!PUBLIC_SURFACE_SOURCE_EXTENSIONS.includes(path.extname(name))) return false; if (name.startsWith(".") || name.startsWith("test-") || name.includes(".test-")) return false; if (name.endsWith(".d.ts")) return false; if (/^config-api(\.[cm]?[jt]s)$/u.test(name)) return false; return !/(\.test|\.spec)(\.[cm]?[jt]s)$/u.test(name); } /** Derives a stable id hint for bundled plugins with one or more extension entrypoints. */ function deriveBundledPluginIdHint(params) { const base = path.basename(params.entryPath, path.extname(params.entryPath)); if (!params.hasMultipleExtensions) return params.manifestId; const packageName = normalizeOptionalString(params.packageName); if (!packageName) return `${params.manifestId}/${base}`; return `${packageName.includes("/") ? packageName.split("/").pop() ?? packageName : packageName}/${base}`; } /** Lists top-level public surface artifacts that should be copied with bundled plugin runtime. */ function collectBundledPluginPublicSurfaceArtifacts(params) { const excluded = new Set(normalizeTrimmedStringList([params.sourceEntry, params.setupEntry]).map((entry) => path.basename(entry))); const artifacts = fs.readdirSync(params.pluginDir, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name).filter(isTopLevelPublicSurfaceSource).filter((entry) => !excluded.has(entry)).map((entry) => rewriteBundledPluginEntryToBuiltPath(entry)).filter((entry) => typeof entry === "string" && entry.length > 0).toSorted((left, right) => left.localeCompare(right)); return artifacts.length > 0 ? artifacts : void 0; } /** Filters public artifacts down to runtime sidecars needed by bundled plugin execution. */ function collectBundledPluginRuntimeSidecarArtifacts(publicSurfaceArtifacts) { if (!publicSurfaceArtifacts) return; const artifacts = publicSurfaceArtifacts.filter((artifact) => RUNTIME_SIDECAR_ARTIFACTS.has(artifact)); return artifacts.length > 0 ? artifacts : void 0; } /** Chooses the source or built extension directory appropriate for the current package layout. */ function resolveBundledPluginScanDir(params) { const sourceDir = path.join(params.packageRoot, "extensions"); const runtimeDir = path.join(params.packageRoot, "dist-runtime", "extensions"); const builtDir = path.join(params.packageRoot, "dist", "extensions"); if (params.runningFromBuiltArtifact) return [ builtDir, runtimeDir, sourceDir ].find((candidate) => fs.existsSync(candidate)); if (fs.existsSync(sourceDir)) return sourceDir; return fs.existsSync(builtDir) ? fs.existsSync(runtimeDir) ? runtimeDir : builtDir : void 0; } function listBundledPluginEntryBaseDirs(params) { const scanPluginRoot = params.scanDir ? path.resolve(params.scanDir, params.pluginDirName ?? "") : void 0; const baseDirs = [ ...scanPluginRoot ? [path.resolve(scanPluginRoot, "dist")] : [], ...scanPluginRoot ? [scanPluginRoot] : [], path.resolve(params.rootDir, "dist", "extensions", params.pluginDirName ?? ""), path.resolve(params.rootDir, "dist-runtime", "extensions", params.pluginDirName ?? ""), path.resolve(params.rootDir, "extensions", params.pluginDirName ?? "", "dist"), path.resolve(params.rootDir, "extensions", params.pluginDirName ?? "") ]; return uniqueStrings(baseDirs); } function listBundledPluginEntryRoots(params) { const roots = [ ...params.scanDir ? [path.resolve(params.scanDir, params.pluginDirName ?? "")] : [], path.resolve(params.rootDir, "extensions", params.pluginDirName ?? ""), path.resolve(params.rootDir, "dist", "extensions", params.pluginDirName ?? ""), path.resolve(params.rootDir, "dist-runtime", "extensions", params.pluginDirName ?? "") ]; return uniqueStrings(roots); } function listBundledPluginEntrySearchPaths(entry, params) { const paths = []; const roots = listBundledPluginEntryRoots(params); for (const rawEntry of [entry.built, entry.source]) { if (typeof rawEntry !== "string" || rawEntry.length === 0) continue; if (!path.isAbsolute(rawEntry)) { paths.push(rawEntry); continue; } const normalizedEntry = path.normalize(rawEntry); for (const root of roots) { if (!isPathInside(root, normalizedEntry)) continue; const relativeEntry = path.relative(root, normalizedEntry); const builtEntry = rewriteBundledPluginEntryToBuiltPath(relativeEntry); if (builtEntry) paths.push(builtEntry); paths.push(relativeEntry); } } return uniqueStrings(paths); } /** Resolves a generated runtime path for a bundled plugin entry. */ function resolveBundledPluginGeneratedPath(rootDir, entry, pluginDirName, scanDir) { if (!entry) return null; const entryOrder = listBundledPluginEntrySearchPaths(entry, { rootDir, pluginDirName, ...scanDir ? { scanDir } : {} }); const baseDirs = listBundledPluginEntryBaseDirs({ rootDir, pluginDirName, ...scanDir ? { scanDir } : {} }); for (const baseDir of baseDirs) for (const entryPath of entryOrder) { const candidate = resolveBundledPluginEntryCandidate(baseDir, entryPath); if (!candidate) continue; if (fs.existsSync(candidate)) return candidate; } return null; } function resolveBundledPluginEntryCandidate(baseDir, entryPath) { const normalizedEntryPath = entryPath.replace(/^\.\//u, ""); const candidate = path.isAbsolute(normalizedEntryPath) ? path.normalize(normalizedEntryPath) : path.resolve(baseDir, normalizedEntryPath); if (!isPathInside(baseDir, candidate)) return null; return candidate; } //#endregion export { resolveBundledPluginScanDir as a, resolveBundledPluginGeneratedPath as i, collectBundledPluginRuntimeSidecarArtifacts as n, rewriteBundledPluginEntryToBuiltPath as o, deriveBundledPluginIdHint as r, collectBundledPluginPublicSurfaceArtifacts as t };