mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:50:43 +00:00
116 lines
3.9 KiB
JavaScript
116 lines
3.9 KiB
JavaScript
// Thin ESM wrapper so native dynamic import() resolves in source-checkout mode
|
|
// while packaged dist builds resolve a distinct runtime entry that cannot loop
|
|
// back into this wrapper through the stable root runtime alias.
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
|
|
const PLUGIN_ID = "matrix";
|
|
const PLUGIN_ENTRY_RUNTIME_BASENAME = "plugin-entry.handlers.runtime";
|
|
const NATIVE_RUNTIME_EXTENSIONS = [".js", ".mjs", ".cjs"];
|
|
|
|
function readPackageJson(packageRoot) {
|
|
try {
|
|
return JSON.parse(fs.readFileSync(path.join(packageRoot, "package.json"), "utf8"));
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function normalizeLowercaseStringOrEmpty(value) {
|
|
return typeof value === "string" ? value.toLowerCase() : "";
|
|
}
|
|
|
|
function hasTrustedOpenClawRootIndicator(packageRoot, packageJson) {
|
|
const packageExports = packageJson?.exports ?? {};
|
|
if (!Object.prototype.hasOwnProperty.call(packageExports, "./plugin-sdk")) {
|
|
return false;
|
|
}
|
|
const hasCliEntryExport = Object.prototype.hasOwnProperty.call(packageExports, "./cli-entry");
|
|
const hasOpenClawBin =
|
|
(typeof packageJson?.bin === "string" &&
|
|
normalizeLowercaseStringOrEmpty(packageJson.bin).includes("openclaw")) ||
|
|
(typeof packageJson?.bin === "object" &&
|
|
packageJson.bin !== null &&
|
|
typeof packageJson.bin.openclaw === "string");
|
|
const hasOpenClawEntrypoint = fs.existsSync(path.join(packageRoot, "openclaw.mjs"));
|
|
return hasCliEntryExport || hasOpenClawBin || hasOpenClawEntrypoint;
|
|
}
|
|
|
|
function findOpenClawPackageRoot(startDir) {
|
|
let cursor = path.resolve(startDir);
|
|
for (let i = 0; i < 12; i += 1) {
|
|
const pkg = readPackageJson(cursor);
|
|
if (pkg?.name === "openclaw" && hasTrustedOpenClawRootIndicator(cursor, pkg)) {
|
|
return { packageRoot: cursor, packageJson: pkg };
|
|
}
|
|
const parent = path.dirname(cursor);
|
|
if (parent === cursor) {
|
|
break;
|
|
}
|
|
cursor = parent;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function resolveExistingFile(basePath, extensions) {
|
|
for (const ext of extensions) {
|
|
const candidate = `${basePath}${ext}`;
|
|
if (fs.existsSync(candidate)) {
|
|
return candidate;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function resolveBundledPluginRuntimeModulePath(moduleUrl, params) {
|
|
const modulePath = fileURLToPath(moduleUrl);
|
|
const moduleDir = path.dirname(modulePath);
|
|
const localCandidates = [
|
|
path.join(moduleDir, "..", params.runtimeBasename),
|
|
path.join(moduleDir, "extensions", params.pluginId, params.runtimeBasename),
|
|
];
|
|
|
|
for (const candidate of localCandidates) {
|
|
const resolved = resolveExistingFile(candidate, NATIVE_RUNTIME_EXTENSIONS);
|
|
if (resolved) {
|
|
return resolved;
|
|
}
|
|
}
|
|
|
|
const location = findOpenClawPackageRoot(moduleDir);
|
|
if (location) {
|
|
const { packageRoot } = location;
|
|
const packageCandidates = [
|
|
path.join(packageRoot, "extensions", params.pluginId, params.runtimeBasename),
|
|
path.join(packageRoot, "dist", "extensions", params.pluginId, params.runtimeBasename),
|
|
];
|
|
|
|
for (const candidate of packageCandidates) {
|
|
const resolved = resolveExistingFile(candidate, NATIVE_RUNTIME_EXTENSIONS);
|
|
if (resolved) {
|
|
return resolved;
|
|
}
|
|
}
|
|
}
|
|
|
|
throw new Error(
|
|
`Cannot resolve ${params.pluginId} plugin runtime module ${params.runtimeBasename} from ${modulePath}`,
|
|
);
|
|
}
|
|
|
|
async function loadRuntimeModule(modulePath) {
|
|
return import(pathToFileURL(modulePath).href);
|
|
}
|
|
|
|
const mod = await loadRuntimeModule(
|
|
resolveBundledPluginRuntimeModulePath(import.meta.url, {
|
|
pluginId: PLUGIN_ID,
|
|
runtimeBasename: PLUGIN_ENTRY_RUNTIME_BASENAME,
|
|
}),
|
|
);
|
|
export const ensureMatrixCryptoRuntime = mod.ensureMatrixCryptoRuntime;
|
|
export const handleVerifyRecoveryKey = mod.handleVerifyRecoveryKey;
|
|
export const handleVerificationBootstrap = mod.handleVerificationBootstrap;
|
|
export const handleVerificationStatus = mod.handleVerificationStatus;
|