Files
openclaw/scripts/lib/plugin-package-dependencies.mjs
2026-05-01 21:37:08 +01:00

63 lines
1.9 KiB
JavaScript

import fs from "node:fs";
import path from "node:path";
export function collectRuntimeDependencySpecs(packageJson = {}) {
return new Map(
[
...Object.entries(packageJson.dependencies ?? {}),
...Object.entries(packageJson.optionalDependencies ?? {}),
].filter((entry) => typeof entry[1] === "string" && entry[1].length > 0),
);
}
export function packageNameFromSpecifier(specifier) {
if (
typeof specifier !== "string" ||
specifier.startsWith(".") ||
specifier.startsWith("/") ||
specifier.startsWith("node:") ||
specifier.startsWith("#")
) {
return null;
}
const [first, second] = specifier.split("/");
if (!first) {
return null;
}
return first.startsWith("@") && second ? `${first}/${second}` : first;
}
export function collectBundledPluginPackageDependencySpecs(bundledPluginsDir) {
const specs = new Map();
if (!fs.existsSync(bundledPluginsDir)) {
return specs;
}
const packageJsonPaths = fs
.readdirSync(bundledPluginsDir, { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map((entry) => path.join(bundledPluginsDir, entry.name, "package.json"))
.filter((packageJsonPath) => fs.existsSync(packageJsonPath))
.toSorted((left, right) => left.localeCompare(right));
for (const packageJsonPath of packageJsonPaths) {
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
const pluginId = path.basename(path.dirname(packageJsonPath));
for (const [name, spec] of collectRuntimeDependencySpecs(packageJson)) {
const existing = specs.get(name);
if (existing) {
if (existing.spec !== spec) {
existing.conflicts.push({ pluginId, spec });
} else if (!existing.pluginIds.includes(pluginId)) {
existing.pluginIds.push(pluginId);
}
continue;
}
specs.set(name, { conflicts: [], pluginIds: [pluginId], spec });
}
}
return specs;
}