mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 10:30:44 +00:00
fix(plugins): gate package test api aliases
This commit is contained in:
@@ -48,6 +48,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Fixes
|
||||
|
||||
- Plugins/loader: keep bundled plugin package `test-api.js` aliases behind private QA mode, so source transforms do not expose test-only public surfaces during normal plugin loading. Thanks @vincentkoc.
|
||||
- Gateway/startup: start cron and record the post-ready memory trace even when deferred maintenance timers fail after readiness, so a non-fatal timer setup issue does not silently leave scheduled jobs idle. Thanks @vincentkoc.
|
||||
- Agents/session status: keep semantic `session_status({ sessionKey: "current" })` on the live run session even before that run has a persisted session-store entry, instead of falling back to the sandbox policy key. Thanks @vincentkoc.
|
||||
- QA/Slack: resolve bundled official plugin public-surface package aliases during source-mode QA runs, so release Slack live validation can load `@openclaw/slack/api.js` without workspace symlinks. Thanks @vincentkoc.
|
||||
|
||||
@@ -211,12 +211,16 @@ function createBundledPluginPackagePublicSurfaceAliasFixture() {
|
||||
);
|
||||
const sourceApiPath = path.join(extensionRoot, "api.ts");
|
||||
const sourceRuntimeApiPath = path.join(extensionRoot, "runtime-api.ts");
|
||||
const sourceTestApiPath = path.join(extensionRoot, "test-api.ts");
|
||||
const distApiPath = path.join(distExtensionRoot, "api.js");
|
||||
const distRuntimeApiPath = path.join(distExtensionRoot, "runtime-api.js");
|
||||
const distTestApiPath = path.join(distExtensionRoot, "test-api.js");
|
||||
fs.writeFileSync(sourceApiPath, "export const slackApi = 'source';\n", "utf-8");
|
||||
fs.writeFileSync(sourceRuntimeApiPath, "export const slackRuntimeApi = 'source';\n", "utf-8");
|
||||
fs.writeFileSync(sourceTestApiPath, "export const slackTestApi = 'source';\n", "utf-8");
|
||||
fs.writeFileSync(distApiPath, "export const slackApi = 'dist';\n", "utf-8");
|
||||
fs.writeFileSync(distRuntimeApiPath, "export const slackRuntimeApi = 'dist';\n", "utf-8");
|
||||
fs.writeFileSync(distTestApiPath, "export const slackTestApi = 'dist';\n", "utf-8");
|
||||
fs.writeFileSync(
|
||||
path.join(extensionRoot, "internal.ts"),
|
||||
"export const internal = true;\n",
|
||||
@@ -226,8 +230,10 @@ function createBundledPluginPackagePublicSurfaceAliasFixture() {
|
||||
...fixture,
|
||||
distApiPath,
|
||||
distRuntimeApiPath,
|
||||
distTestApiPath,
|
||||
sourceApiPath,
|
||||
sourceRuntimeApiPath,
|
||||
sourceTestApiPath,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -828,9 +834,26 @@ describe("plugin sdk alias helpers", () => {
|
||||
expect(fs.realpathSync(aliases["@openclaw/slack/runtime-api.js"] ?? "")).toBe(
|
||||
fs.realpathSync(sourceRuntimeApiPath),
|
||||
);
|
||||
expect(aliases["@openclaw/slack/test-api.js"]).toBeUndefined();
|
||||
expect(aliases["@openclaw/slack/internal.js"]).toBeUndefined();
|
||||
});
|
||||
|
||||
it("aliases bundled plugin package test surfaces only in private QA mode", () => {
|
||||
const { fixture, sourceTestApiPath } = createBundledPluginPackagePublicSurfaceAliasFixture();
|
||||
const sourcePluginEntry = writePluginEntry(
|
||||
fixture.root,
|
||||
bundledPluginFile("qa-lab", "src/live-transports/slack/slack-live.runtime.ts"),
|
||||
);
|
||||
|
||||
const aliases = withEnv({ OPENCLAW_ENABLE_PRIVATE_QA_CLI: "1", NODE_ENV: undefined }, () =>
|
||||
buildPluginLoaderAliasMap(sourcePluginEntry),
|
||||
);
|
||||
|
||||
expect(fs.realpathSync(aliases["@openclaw/slack/test-api.js"] ?? "")).toBe(
|
||||
fs.realpathSync(sourceTestApiPath),
|
||||
);
|
||||
});
|
||||
|
||||
it("aliases bundled plugin package public surfaces to dist when dist resolution is requested", () => {
|
||||
const { fixture, distApiPath, distRuntimeApiPath } =
|
||||
createBundledPluginPackagePublicSurfaceAliasFixture();
|
||||
|
||||
@@ -331,10 +331,23 @@ function readBundledPluginPackageName(packageJsonPath: string): string | null {
|
||||
}
|
||||
}
|
||||
|
||||
function listBundledPluginPublicSurfaceSourceBasenames(extensionSourceRoot: string): string[] {
|
||||
function isBundledPluginPublicSurfaceSourceBasename(params: {
|
||||
basename: string;
|
||||
includePrivateQa: boolean;
|
||||
}): boolean {
|
||||
if (params.basename === "test-api") {
|
||||
return params.includePrivateQa;
|
||||
}
|
||||
return BUNDLED_PLUGIN_PUBLIC_SURFACE_SOURCE_PATTERN.test(params.basename);
|
||||
}
|
||||
|
||||
function listBundledPluginPublicSurfaceSourceBasenames(params: {
|
||||
extensionSourceRoot: string;
|
||||
includePrivateQa: boolean;
|
||||
}): string[] {
|
||||
try {
|
||||
return fs
|
||||
.readdirSync(extensionSourceRoot, { withFileTypes: true })
|
||||
.readdirSync(params.extensionSourceRoot, { withFileTypes: true })
|
||||
.filter((entry) => entry.isFile())
|
||||
.map((entry) => entry.name)
|
||||
.flatMap((fileName) => {
|
||||
@@ -345,7 +358,12 @@ function listBundledPluginPublicSurfaceSourceBasenames(extensionSourceRoot: stri
|
||||
return [];
|
||||
}
|
||||
const basename = fileName.slice(0, -ext.length);
|
||||
return BUNDLED_PLUGIN_PUBLIC_SURFACE_SOURCE_PATTERN.test(basename) ? [basename] : [];
|
||||
return isBundledPluginPublicSurfaceSourceBasename({
|
||||
basename,
|
||||
includePrivateQa: params.includePrivateQa,
|
||||
})
|
||||
? [basename]
|
||||
: [];
|
||||
})
|
||||
.toSorted();
|
||||
} catch {
|
||||
@@ -410,6 +428,7 @@ function resolveBundledPluginPackagePublicSurfaceAliasMap(params: {
|
||||
isProduction: process.env.NODE_ENV === "production",
|
||||
pluginSdkResolution: params.pluginSdkResolution,
|
||||
});
|
||||
const includePrivateQa = shouldIncludePrivateLocalOnlyPluginSdkSubpaths();
|
||||
const aliasMap: Record<string, string> = {};
|
||||
for (const entry of extensionDirs) {
|
||||
if (!entry.isDirectory()) {
|
||||
@@ -422,9 +441,10 @@ function resolveBundledPluginPackagePublicSurfaceAliasMap(params: {
|
||||
if (!packageName) {
|
||||
continue;
|
||||
}
|
||||
for (const basename of listBundledPluginPublicSurfaceSourceBasenames(
|
||||
path.join(extensionsRoot, dirName),
|
||||
)) {
|
||||
for (const basename of listBundledPluginPublicSurfaceSourceBasenames({
|
||||
extensionSourceRoot: path.join(extensionsRoot, dirName),
|
||||
includePrivateQa,
|
||||
})) {
|
||||
const target = resolveBundledPluginPublicSurfaceAliasTarget({
|
||||
packageRoot,
|
||||
dirName,
|
||||
|
||||
Reference in New Issue
Block a user