
























@@ -0,0 +1,112 @@
1+#!/usr/bin/env node
2+3+import fs from "node:fs";
4+import path from "node:path";
5+import { pathToFileURL } from "node:url";
6+import {
7+buildPluginNpmRuntime,
8+resolvePluginNpmRuntimeBuildPlan,
9+} from "./lib/plugin-npm-runtime-build.mjs";
10+11+function readJsonFile(filePath) {
12+return JSON.parse(fs.readFileSync(filePath, "utf8"));
13+}
14+15+function isPublishablePluginPackage(packageJson) {
16+return packageJson.openclaw?.release?.publishToNpm === true;
17+}
18+19+function listPublishablePluginPackageDirs(repoRoot) {
20+const extensionsRoot = path.join(repoRoot, "extensions");
21+return fs
22+.readdirSync(extensionsRoot, { withFileTypes: true })
23+.filter((entry) => entry.isDirectory())
24+.map((entry) => path.join("extensions", entry.name))
25+.filter((packageDir) => {
26+const packageJsonPath = path.join(repoRoot, packageDir, "package.json");
27+return (
28+fs.existsSync(packageJsonPath) && isPublishablePluginPackage(readJsonFile(packageJsonPath))
29+);
30+})
31+.toSorted((left, right) => left.localeCompare(right));
32+}
33+34+function parseArgs(argv) {
35+const packageDirs = [];
36+for (let index = 0; index < argv.length; index += 1) {
37+const arg = argv[index];
38+if (arg === "--package") {
39+const packageDir = argv[index + 1];
40+if (!packageDir) {
41+throw new Error("missing value for --package");
42+}
43+packageDirs.push(packageDir);
44+index += 1;
45+continue;
46+}
47+throw new Error(
48+"usage: node scripts/check-plugin-npm-runtime-builds.mjs [--package extensions/<id> ...]",
49+);
50+}
51+return { packageDirs };
52+}
53+54+function listMissingRuntimeOutputs(plan) {
55+return Object.keys(plan.entry)
56+.map((entryKey) => path.join(plan.outDir, `${entryKey}.js`))
57+.filter((filePath) => !fs.existsSync(filePath));
58+}
59+60+export async function checkPluginNpmRuntimeBuilds(params = {}) {
61+const repoRoot = path.resolve(params.repoRoot ?? ".");
62+const packageDirs =
63+params.packageDirs?.length > 0
64+ ? params.packageDirs
65+ : listPublishablePluginPackageDirs(repoRoot);
66+const rows = [];
67+for (const packageDir of packageDirs) {
68+const plan = resolvePluginNpmRuntimeBuildPlan({ repoRoot, packageDir });
69+if (!plan) {
70+throw new Error(`${packageDir} did not produce a package-local runtime build plan`);
71+}
72+const result = await buildPluginNpmRuntime({
73+ repoRoot,
74+ packageDir,
75+logLevel: params.logLevel ?? "warn",
76+});
77+const missing = listMissingRuntimeOutputs(result);
78+if (missing.length > 0) {
79+throw new Error(
80+`${packageDir} missing built runtime outputs: ${missing
81+ .map((filePath) => path.relative(repoRoot, filePath))
82+ .join(", ")}`,
83+);
84+}
85+rows.push({
86+pluginDir: result.pluginDir,
87+entryCount: Object.keys(result.entry).length,
88+copiedStaticAssets: result.copiedStaticAssets,
89+});
90+}
91+return rows;
92+}
93+94+if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) {
95+try {
96+const args = parseArgs(process.argv.slice(2));
97+const rows = await checkPluginNpmRuntimeBuilds(args);
98+console.log(`built ${rows.length} publishable plugin runtimes`);
99+for (const row of rows) {
100+console.log(
101+[
102+row.pluginDir,
103+row.entryCount,
104+row.copiedStaticAssets.length > 0 ? row.copiedStaticAssets.join(",") : "-",
105+].join("\t"),
106+);
107+}
108+} catch (error) {
109+console.error(error instanceof Error ? error.message : String(error));
110+process.exitCode = 1;
111+}
112+}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。