Files
moltbot/scripts/check-plugin-sdk-exports.mjs

87 lines
2.8 KiB
JavaScript
Executable File

#!/usr/bin/env node
/**
* Verifies that critical plugin-sdk exports are present in the compiled dist output.
* Regression guard for #27569 where isDangerousNameMatchingEnabled was missing
* from the compiled output, breaking channel extension plugins at runtime.
*
* Run after `pnpm build` to catch missing exports before release.
*/
import { readFileSync, existsSync } from "node:fs";
import { resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
const distFile = resolve(__dirname, "..", "dist", "plugin-sdk", "index.js");
if (!existsSync(distFile)) {
console.error("ERROR: dist/plugin-sdk/index.js not found. Run `pnpm build` first.");
process.exit(1);
}
const content = readFileSync(distFile, "utf-8");
// Extract the final export statement from the compiled output.
// tsdown/rolldown emits a single `export { ... }` at the end of the file.
const exportMatch = content.match(/export\s*\{([^}]+)\}\s*;?\s*$/);
if (!exportMatch) {
console.error("ERROR: Could not find export statement in dist/plugin-sdk/index.js");
process.exit(1);
}
const exportedNames = exportMatch[1]
.split(",")
.map((s) => {
// Handle `foo as bar` aliases — the exported name is the `bar` part
const parts = s.trim().split(/\s+as\s+/);
return (parts[parts.length - 1] || "").trim();
})
.filter(Boolean);
const exportSet = new Set(exportedNames);
// Critical functions that channel extension plugins import from openclaw/plugin-sdk.
// If any of these are missing, plugins will fail at runtime with:
// TypeError: (0 , _pluginSdk.<name>) is not a function
const requiredExports = [
"isDangerousNameMatchingEnabled",
"createAccountListHelpers",
"buildAgentMediaPayload",
"createReplyPrefixOptions",
"createTypingCallbacks",
"logInboundDrop",
"logTypingFailure",
"buildPendingHistoryContextFromMap",
"clearHistoryEntriesIfEnabled",
"recordPendingHistoryEntryIfEnabled",
"resolveControlCommandGate",
"resolveDmGroupAccessWithLists",
"resolveAllowlistProviderRuntimeGroupPolicy",
"resolveDefaultGroupPolicy",
"resolveChannelMediaMaxBytes",
"warnMissingProviderGroupPolicyFallbackOnce",
"emptyPluginConfigSchema",
"normalizePluginHttpPath",
"registerPluginHttpRoute",
"DEFAULT_ACCOUNT_ID",
"DEFAULT_GROUP_HISTORY_LIMIT",
];
let missing = 0;
for (const name of requiredExports) {
if (!exportSet.has(name)) {
console.error(`MISSING EXPORT: ${name}`);
missing += 1;
}
}
if (missing > 0) {
console.error(`\nERROR: ${missing} required export(s) missing from dist/plugin-sdk/index.js.`);
console.error("This will break channel extension plugins at runtime.");
console.error("Check src/plugin-sdk/index.ts and rebuild.");
process.exit(1);
}
console.log(`OK: All ${requiredExports.length} required plugin-sdk exports verified.`);