mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-22 22:52:03 +00:00
build(plugin-sdk): verify dist facade exports
This commit is contained in:
@@ -1006,10 +1006,10 @@
|
||||
"android:test:integration": "OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_ANDROID_NODE=1 vitest run --config vitest.live.config.ts src/gateway/android-node.capabilities.live.test.ts",
|
||||
"android:test:third-party": "cd apps/android && ./gradlew :app:testThirdPartyDebugUnitTest",
|
||||
"audit:seams": "node scripts/audit-seams.mjs",
|
||||
"build": "pnpm canvas:a2ui:bundle && node scripts/tsdown-build.mjs && node scripts/runtime-postbuild.mjs && node scripts/build-stamp.mjs && pnpm build:plugin-sdk:dts && node --import tsx scripts/write-plugin-sdk-entry-dts.ts && node --import tsx scripts/canvas-a2ui-copy.ts && node --import tsx scripts/copy-hook-metadata.ts && node --import tsx scripts/copy-export-html-templates.ts && node --import tsx scripts/write-build-info.ts && node --import tsx scripts/write-cli-startup-metadata.ts && node --import tsx scripts/write-cli-compat.ts",
|
||||
"build": "pnpm canvas:a2ui:bundle && node scripts/tsdown-build.mjs && node scripts/runtime-postbuild.mjs && node scripts/build-stamp.mjs && pnpm build:plugin-sdk:dts && node --import tsx scripts/write-plugin-sdk-entry-dts.ts && node scripts/check-plugin-sdk-exports.mjs && node --import tsx scripts/canvas-a2ui-copy.ts && node --import tsx scripts/copy-hook-metadata.ts && node --import tsx scripts/copy-export-html-templates.ts && node --import tsx scripts/write-build-info.ts && node --import tsx scripts/write-cli-startup-metadata.ts && node --import tsx scripts/write-cli-compat.ts",
|
||||
"build:docker": "node scripts/tsdown-build.mjs && node scripts/runtime-postbuild.mjs && node scripts/build-stamp.mjs && node --import tsx scripts/canvas-a2ui-copy.ts && node --import tsx scripts/copy-hook-metadata.ts && node --import tsx scripts/copy-export-html-templates.ts && node --import tsx scripts/write-build-info.ts && node --import tsx scripts/write-cli-startup-metadata.ts && node --import tsx scripts/write-cli-compat.ts",
|
||||
"build:plugin-sdk:dts": "tsc -p tsconfig.plugin-sdk.dts.json",
|
||||
"build:strict-smoke": "pnpm canvas:a2ui:bundle && node scripts/tsdown-build.mjs && node scripts/runtime-postbuild.mjs && node scripts/build-stamp.mjs && pnpm build:plugin-sdk:dts",
|
||||
"build:strict-smoke": "pnpm canvas:a2ui:bundle && node scripts/tsdown-build.mjs && node scripts/runtime-postbuild.mjs && node scripts/build-stamp.mjs && pnpm build:plugin-sdk:dts && node --import tsx scripts/write-plugin-sdk-entry-dts.ts && node scripts/check-plugin-sdk-exports.mjs",
|
||||
"canon:check": "node scripts/canon.mjs check",
|
||||
"canon:check:json": "node scripts/canon.mjs check --json",
|
||||
"canon:enforce": "node scripts/canon.mjs enforce --json",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#!/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.
|
||||
* Verifies that the root plugin-sdk runtime surface and generated facade types
|
||||
* are present in the compiled dist output.
|
||||
*
|
||||
* Run after `pnpm build` to catch missing exports before release.
|
||||
* Run after `pnpm build` to catch missing root exports or leaked repo-only type
|
||||
* aliases before release.
|
||||
*/
|
||||
|
||||
import { readFileSync, existsSync } from "node:fs";
|
||||
@@ -15,6 +15,15 @@ import { pluginSdkSubpaths } from "./lib/plugin-sdk-entries.mjs";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const distFile = resolve(__dirname, "..", "dist", "plugin-sdk", "index.js");
|
||||
const generatedFacadeTypeMapDts = resolve(
|
||||
__dirname,
|
||||
"..",
|
||||
"dist",
|
||||
"plugin-sdk",
|
||||
"src",
|
||||
"generated",
|
||||
"plugin-sdk-facade-type-map.generated.d.ts",
|
||||
);
|
||||
|
||||
if (!existsSync(distFile)) {
|
||||
console.error("ERROR: dist/plugin-sdk/index.js not found. Run `pnpm build` first.");
|
||||
@@ -44,32 +53,13 @@ const exportSet = new Set(exportedNames);
|
||||
|
||||
const requiredRuntimeShimEntries = ["compat.js", "root-alias.cjs"];
|
||||
|
||||
// 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
|
||||
// The root plugin-sdk entry intentionally stays tiny. Keep this list aligned
|
||||
// with src/plugin-sdk/index.ts runtime exports.
|
||||
const requiredExports = [
|
||||
"isDangerousNameMatchingEnabled",
|
||||
"createAccountListHelpers",
|
||||
"buildAgentMediaPayload",
|
||||
"createReplyPrefixOptions",
|
||||
"createTypingCallbacks",
|
||||
"logInboundDrop",
|
||||
"logTypingFailure",
|
||||
"buildPendingHistoryContextFromMap",
|
||||
"clearHistoryEntriesIfEnabled",
|
||||
"recordPendingHistoryEntryIfEnabled",
|
||||
"resolveControlCommandGate",
|
||||
"resolveDmGroupAccessWithLists",
|
||||
"resolveAllowlistProviderRuntimeGroupPolicy",
|
||||
"resolveDefaultGroupPolicy",
|
||||
"resolveChannelMediaMaxBytes",
|
||||
"warnMissingProviderGroupPolicyFallbackOnce",
|
||||
"emptyPluginConfigSchema",
|
||||
"onDiagnosticEvent",
|
||||
"normalizePluginHttpPath",
|
||||
"registerPluginHttpRoute",
|
||||
"DEFAULT_ACCOUNT_ID",
|
||||
"DEFAULT_GROUP_HISTORY_LIMIT",
|
||||
"registerContextEngine",
|
||||
"delegateCompactionToRuntime",
|
||||
];
|
||||
|
||||
let missing = 0;
|
||||
@@ -101,12 +91,29 @@ for (const entry of requiredRuntimeShimEntries) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!existsSync(generatedFacadeTypeMapDts)) {
|
||||
console.error(
|
||||
"MISSING GENERATED FACADE TYPE MAP DTS: dist/plugin-sdk/src/generated/plugin-sdk-facade-type-map.generated.d.ts",
|
||||
);
|
||||
missing += 1;
|
||||
} else {
|
||||
const facadeTypeMapContent = readFileSync(generatedFacadeTypeMapDts, "utf-8");
|
||||
if (facadeTypeMapContent.includes("@openclaw/")) {
|
||||
console.error(
|
||||
"INVALID GENERATED FACADE TYPE MAP DTS: dist/plugin-sdk/src/generated/plugin-sdk-facade-type-map.generated.d.ts leaks @openclaw/* imports",
|
||||
);
|
||||
missing += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (missing > 0) {
|
||||
console.error(
|
||||
`\nERROR: ${missing} required plugin-sdk artifact(s) missing (named exports or subpath files).`,
|
||||
);
|
||||
console.error("This will break channel extension plugins at runtime.");
|
||||
console.error("Check src/plugin-sdk/index.ts, subpath entries, and rebuild.");
|
||||
console.error("This will break published plugin-sdk artifacts.");
|
||||
console.error(
|
||||
"Check src/plugin-sdk/index.ts, generated d.ts rewrites, subpath entries, and rebuild.",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,32 @@ const TYPE_SHIMS: Partial<Record<string, string>> = {
|
||||
].join("\n"),
|
||||
};
|
||||
|
||||
const GENERATED_FACADE_TYPE_MAP_SOURCE = path.join(
|
||||
process.cwd(),
|
||||
"dist/plugin-sdk/src/generated/plugin-sdk-facade-type-map.generated.d.ts",
|
||||
);
|
||||
const GENERATED_FACADE_TYPE_MAP_DIST_PREFIX = "../../../extensions/";
|
||||
|
||||
function rewriteFacadeTypeMapSpecifier(specifier: string): string {
|
||||
if (!specifier.startsWith("@openclaw/")) {
|
||||
return specifier;
|
||||
}
|
||||
return `${GENERATED_FACADE_TYPE_MAP_DIST_PREFIX}${specifier.slice("@openclaw/".length)}`;
|
||||
}
|
||||
|
||||
function rewriteGeneratedFacadeTypeMapDts(): void {
|
||||
if (!fs.existsSync(GENERATED_FACADE_TYPE_MAP_SOURCE)) {
|
||||
return;
|
||||
}
|
||||
const source = fs.readFileSync(GENERATED_FACADE_TYPE_MAP_SOURCE, "utf8");
|
||||
const rewritten = source.replace(/@openclaw\/([a-z0-9-]+\/[^")\s]+)/g, (_match, suffix: string) =>
|
||||
rewriteFacadeTypeMapSpecifier(`@openclaw/${suffix}`),
|
||||
);
|
||||
if (rewritten !== source) {
|
||||
fs.writeFileSync(GENERATED_FACADE_TYPE_MAP_SOURCE, rewritten, "utf8");
|
||||
}
|
||||
}
|
||||
|
||||
// `tsc` emits declarations under `dist/plugin-sdk/src/plugin-sdk/*` because the source lives
|
||||
// at `src/plugin-sdk/*` and `rootDir` is `.` (repo root, to support cross-src/extensions refs).
|
||||
//
|
||||
@@ -78,3 +104,5 @@ for (const entry of pluginSdkEntrypoints) {
|
||||
fs.mkdirSync(path.dirname(runtimeOut), { recursive: true });
|
||||
fs.writeFileSync(runtimeOut, runtimeShim, "utf8");
|
||||
}
|
||||
|
||||
rewriteGeneratedFacadeTypeMapDts();
|
||||
|
||||
Reference in New Issue
Block a user