mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix(plugins): derive media aliases from exports (#122523)
This commit is contained in:
@@ -93,6 +93,23 @@ function writeInternalCorePackageSource(
|
||||
return sourcePath;
|
||||
}
|
||||
|
||||
function writeInternalCorePackageExports(
|
||||
root: string,
|
||||
packageDir: string,
|
||||
subpaths: readonly string[],
|
||||
): void {
|
||||
writeJsonFile(path.join(root, "packages", packageDir, "package.json"), {
|
||||
name: `@openclaw/${packageDir}`,
|
||||
exports: Object.fromEntries(
|
||||
subpaths.map((subpath) => {
|
||||
const exportKey = subpath ? `./${subpath}` : ".";
|
||||
const distFile = `./dist/${subpath || "index"}.mjs`;
|
||||
return [exportKey, { import: distFile, default: distFile }];
|
||||
}),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
function addFakePluginSdkDistExport(root: string, subpath: string): string {
|
||||
const packageJsonPath = path.join(root, "package.json");
|
||||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")) as {
|
||||
@@ -521,7 +538,19 @@ describe("installOpenClawPluginSdkNativeResolver", () => {
|
||||
);
|
||||
const resultSource = writeInternalCorePackageSource(root, "normalization-core", "result.ts");
|
||||
const agentIdSource = writeInternalCorePackageSource(root, "normalization-core", "agent-id.ts");
|
||||
const mediaCoreSource = writeInternalCorePackageSource(root, "media-core", "mime.ts");
|
||||
writeInternalCorePackageExports(root, "normalization-core", [
|
||||
"agent-id",
|
||||
"boolean-coercion",
|
||||
"result",
|
||||
"string-coerce",
|
||||
]);
|
||||
writeInternalCorePackageExports(root, "media-core", ["attachment-classify", "mime"]);
|
||||
const mediaMimeSource = writeInternalCorePackageSource(root, "media-core", "mime.ts");
|
||||
const mediaAttachmentClassifySource = writeInternalCorePackageSource(
|
||||
root,
|
||||
"media-core",
|
||||
"attachment-classify.ts",
|
||||
);
|
||||
const markdownCoreSource = writeInternalCorePackageSource(
|
||||
root,
|
||||
"markdown-core",
|
||||
@@ -543,6 +572,7 @@ describe("installOpenClawPluginSdkNativeResolver", () => {
|
||||
"acp-core",
|
||||
path.join("runtime", "types.ts"),
|
||||
);
|
||||
writeInternalCorePackageExports(root, "acp-core", ["runtime/types"]);
|
||||
const llmCoreSource = writeInternalCorePackageSource(root, "llm-core", "index.ts");
|
||||
const externalPluginEntry = writeExternalPluginEntry(path.join(root, "external-plugin"));
|
||||
const coreSourceParent = path.join(root, "src", "config", "plugin-web-search-config.ts");
|
||||
@@ -560,6 +590,7 @@ describe("installOpenClawPluginSdkNativeResolver", () => {
|
||||
expect(installedAliases).toContain("@openclaw/normalization-core/result");
|
||||
expect(installedAliases).toContain("@openclaw/normalization-core/agent-id");
|
||||
expect(installedAliases).toContain("@openclaw/media-core/mime");
|
||||
expect(installedAliases).toContain("@openclaw/media-core/attachment-classify");
|
||||
expect(installedAliases).toContain("@openclaw/markdown-core/code-spans");
|
||||
expect(installedAliases).toContain("@openclaw/ai/transports");
|
||||
expect(installedAliases).toContain("@openclaw/ai/internal/retry-after");
|
||||
@@ -583,8 +614,11 @@ describe("installOpenClawPluginSdkNativeResolver", () => {
|
||||
fs.realpathSync(requireFromCoreSource.resolve("@openclaw/normalization-core/agent-id")),
|
||||
).toBe(fs.realpathSync(agentIdSource));
|
||||
expect(fs.realpathSync(requireFromCoreSource.resolve("@openclaw/media-core/mime"))).toBe(
|
||||
fs.realpathSync(mediaCoreSource),
|
||||
fs.realpathSync(mediaMimeSource),
|
||||
);
|
||||
expect(
|
||||
fs.realpathSync(requireFromCoreSource.resolve("@openclaw/media-core/attachment-classify")),
|
||||
).toBe(fs.realpathSync(mediaAttachmentClassifySource));
|
||||
expect(
|
||||
fs.realpathSync(requireFromCoreSource.resolve("@openclaw/markdown-core/code-spans")),
|
||||
).toBe(fs.realpathSync(markdownCoreSource));
|
||||
@@ -609,6 +643,7 @@ describe("installOpenClawPluginSdkNativeResolver", () => {
|
||||
).toThrow();
|
||||
expect(() => requireFromPlugin.resolve("@openclaw/normalization-core/result")).toThrow();
|
||||
expect(() => requireFromPlugin.resolve("@openclaw/media-core/mime")).toThrow();
|
||||
expect(() => requireFromPlugin.resolve("@openclaw/media-core/attachment-classify")).toThrow();
|
||||
expect(() => requireFromPlugin.resolve("@openclaw/markdown-core/code-spans")).toThrow();
|
||||
expect(() => requireFromPlugin.resolve("@openclaw/ai/transports")).toThrow();
|
||||
expect(() => requireFromPlugin.resolve("@openclaw/ai/internal/retry-after")).toThrow();
|
||||
|
||||
@@ -91,22 +91,6 @@ const INTERNAL_CORE_PACKAGE_ALIASES = [
|
||||
["internal/shared", path.join("internal", "shared.ts")],
|
||||
],
|
||||
},
|
||||
{
|
||||
packageName: "@openclaw/media-core",
|
||||
packageDir: "media-core",
|
||||
subpaths: [
|
||||
["", "index.ts"],
|
||||
["base64", "base64.ts"],
|
||||
["constants", "constants.ts"],
|
||||
["content-length", "content-length.ts"],
|
||||
["file-name", "file-name.ts"],
|
||||
["inbound-path-policy", "inbound-path-policy.ts"],
|
||||
["inline-image-data-url", "inline-image-data-url.ts"],
|
||||
["media-source-url", "media-source-url.ts"],
|
||||
["mime", "mime.ts"],
|
||||
["read-byte-stream-with-limit", "read-byte-stream-with-limit.ts"],
|
||||
],
|
||||
},
|
||||
{
|
||||
packageName: "@openclaw/llm-core",
|
||||
packageDir: "llm-core",
|
||||
@@ -341,7 +325,7 @@ function listInternalCorePackageNativeAliases(
|
||||
}> = [];
|
||||
const internalCorePackageAliases = [
|
||||
...INTERNAL_CORE_PACKAGE_ALIASES,
|
||||
...["normalization-core", "acp-core"].map((packageDir) => ({
|
||||
...["media-core", "normalization-core", "acp-core"].map((packageDir) => ({
|
||||
packageName: `@openclaw/${packageDir}`,
|
||||
packageDir,
|
||||
subpaths: listWorkspacePackageExportAliasEntries({
|
||||
|
||||
@@ -154,6 +154,32 @@ function writeWorkspacePackageEntry(params: {
|
||||
return { srcFile, distFile };
|
||||
}
|
||||
|
||||
function writeWorkspacePackageExports(
|
||||
root: string,
|
||||
packageDir: string,
|
||||
subpaths: readonly string[],
|
||||
) {
|
||||
mkdirSafeDir(path.join(root, "packages", packageDir));
|
||||
fs.writeFileSync(
|
||||
path.join(root, "packages", packageDir, "package.json"),
|
||||
JSON.stringify(
|
||||
{
|
||||
name: `@openclaw/${packageDir}`,
|
||||
exports: Object.fromEntries(
|
||||
subpaths.map((subpath) => {
|
||||
const exportKey = subpath ? `./${subpath}` : ".";
|
||||
const distFile = `./dist/${subpath || "index"}.mjs`;
|
||||
return [exportKey, { import: distFile, default: distFile }];
|
||||
}),
|
||||
),
|
||||
},
|
||||
null,
|
||||
2,
|
||||
),
|
||||
"utf-8",
|
||||
);
|
||||
}
|
||||
|
||||
type WorkspaceAliasFixture = readonly [
|
||||
alias: `@openclaw/${string}`,
|
||||
packageDir: string,
|
||||
@@ -1148,6 +1174,15 @@ describe("plugin sdk alias helpers", () => {
|
||||
|
||||
it("aliases workspace packages to source when dist artifacts are missing", () => {
|
||||
const fixture = createPluginSdkAliasFixture();
|
||||
writeWorkspacePackageExports(fixture.root, "media-core", ["", "attachment-classify", "mime"]);
|
||||
writeWorkspacePackageExports(fixture.root, "acp-core", ["", "runtime/types"]);
|
||||
writeWorkspacePackageExports(fixture.root, "normalization-core", [
|
||||
"",
|
||||
"agent-id",
|
||||
"boolean-coercion",
|
||||
"result",
|
||||
"string-coerce",
|
||||
]);
|
||||
const workspaceAliases = writeWorkspaceAliasFixtures(fixture.root, [
|
||||
["@openclaw/gateway-client", "gateway-client", "index"],
|
||||
["@openclaw/gateway-client/timeouts", "gateway-client", "timeouts"],
|
||||
@@ -1160,6 +1195,7 @@ describe("plugin sdk alias helpers", () => {
|
||||
["@openclaw/media-generation-core", "media-generation-core", "index"],
|
||||
["@openclaw/media-generation-core/model-ref", "media-generation-core", "model-ref"],
|
||||
["@openclaw/media-core", "media-core", "index"],
|
||||
["@openclaw/media-core/attachment-classify", "media-core", "attachment-classify"],
|
||||
["@openclaw/media-core/mime", "media-core", "mime"],
|
||||
["@openclaw/acp-core", "acp-core", "index"],
|
||||
["@openclaw/acp-core/runtime/types", "acp-core", "runtime/types"],
|
||||
@@ -1193,6 +1229,9 @@ describe("plugin sdk alias helpers", () => {
|
||||
|
||||
it("aliases workspace package subpaths to dist when available", () => {
|
||||
const fixture = createPluginSdkAliasFixture();
|
||||
writeWorkspacePackageExports(fixture.root, "media-core", ["attachment-classify"]);
|
||||
writeWorkspacePackageExports(fixture.root, "acp-core", ["normalize-text"]);
|
||||
writeWorkspacePackageExports(fixture.root, "normalization-core", ["record-coerce"]);
|
||||
const workspaceAliases = writeWorkspaceAliasFixtures(fixture.root, [
|
||||
["@openclaw/gateway-client/readiness", "gateway-client", "readiness"],
|
||||
[
|
||||
@@ -1203,6 +1242,7 @@ describe("plugin sdk alias helpers", () => {
|
||||
["@openclaw/gateway-protocol/frame-guards", "gateway-protocol", "frame-guards"],
|
||||
["@openclaw/markdown-core/render", "markdown-core", "render"],
|
||||
["@openclaw/media-generation-core/catalog", "media-generation-core", "catalog"],
|
||||
["@openclaw/media-core/attachment-classify", "media-core", "attachment-classify"],
|
||||
[
|
||||
"@openclaw/acp-core/normalize-text",
|
||||
"acp-core",
|
||||
@@ -1254,9 +1294,18 @@ describe("plugin sdk alias helpers", () => {
|
||||
);
|
||||
mkdirSafeDir(path.dirname(normalizationAgentId));
|
||||
fs.writeFileSync(normalizationAgentId, "export {};\n", "utf-8");
|
||||
const cwdWithoutOpenClawPackage = makeTempDir();
|
||||
const mediaAttachmentClassify = path.join(
|
||||
fixture.root,
|
||||
"dist",
|
||||
"media-core",
|
||||
"attachment-classify.js",
|
||||
);
|
||||
mkdirSafeDir(path.dirname(mediaAttachmentClassify));
|
||||
fs.writeFileSync(mediaAttachmentClassify, "export {};\n", "utf-8");
|
||||
const staleCheckout = createPluginSdkAliasFixture();
|
||||
writeWorkspacePackageExports(staleCheckout.root, "media-core", ["mime"]);
|
||||
|
||||
const aliases = withCwd(cwdWithoutOpenClawPackage, () =>
|
||||
const aliases = withCwd(staleCheckout.root, () =>
|
||||
withEnv({ NODE_ENV: undefined }, () =>
|
||||
buildPluginLoaderAliasMap(sourcePluginEntry, undefined, undefined, "dist"),
|
||||
),
|
||||
@@ -1268,6 +1317,9 @@ describe("plugin sdk alias helpers", () => {
|
||||
expect(fs.realpathSync(aliases["@openclaw/normalization-core/agent-id"] ?? "")).toBe(
|
||||
fs.realpathSync(normalizationAgentId),
|
||||
);
|
||||
expect(fs.realpathSync(aliases["@openclaw/media-core/attachment-classify"] ?? "")).toBe(
|
||||
fs.realpathSync(mediaAttachmentClassify),
|
||||
);
|
||||
});
|
||||
|
||||
it("aliases bundled plugin package public surfaces for source plugin transforms", () => {
|
||||
|
||||
@@ -517,21 +517,6 @@ const WORKSPACE_PACKAGE_ALIAS_SUBPATHS = [
|
||||
],
|
||||
],
|
||||
["media-generation-core", ["", "capability-model-ref", "catalog", "model-ref", "normalization"]],
|
||||
[
|
||||
"media-core",
|
||||
[
|
||||
"",
|
||||
"base64",
|
||||
"constants",
|
||||
"content-length",
|
||||
"file-name",
|
||||
"inbound-path-policy",
|
||||
"inline-image-data-url",
|
||||
"media-source-url",
|
||||
"mime",
|
||||
"read-byte-stream-with-limit",
|
||||
],
|
||||
],
|
||||
["retry", [""]],
|
||||
[
|
||||
"terminal-core",
|
||||
@@ -669,14 +654,7 @@ export function listWorkspacePackageExportAliasEntries(params: {
|
||||
params.packageDir,
|
||||
"package.json",
|
||||
);
|
||||
const fallbackPackageRoot = resolveOpenClawPackageRootSync({ cwd: process.cwd() });
|
||||
const packageJson =
|
||||
tryReadJsonSync<PluginSdkPackageJson>(packageJsonPath) ??
|
||||
(fallbackPackageRoot
|
||||
? tryReadJsonSync<PluginSdkPackageJson>(
|
||||
path.join(fallbackPackageRoot, "packages", params.packageDir, "package.json"),
|
||||
)
|
||||
: null);
|
||||
const packageJson = tryReadJsonSync<PluginSdkPackageJson>(packageJsonPath);
|
||||
const exports = packageJson?.exports;
|
||||
if (!exports || typeof exports !== "object" || Array.isArray(exports)) {
|
||||
return listRootPackagedWorkspacePackageAliasEntries(params);
|
||||
@@ -914,7 +892,7 @@ function resolveWorkspacePackageAliasMap(params: {
|
||||
const aliasMap: Record<string, string> = {};
|
||||
const workspacePackageAliasEntries = [
|
||||
...WORKSPACE_PACKAGE_ALIAS_ENTRIES,
|
||||
...["normalization-core", "acp-core"].flatMap((packageDir) =>
|
||||
...["media-core", "normalization-core", "acp-core"].flatMap((packageDir) =>
|
||||
listWorkspacePackageExportAliasEntries({
|
||||
packageRoot,
|
||||
packageName: `@openclaw/${packageDir}`,
|
||||
|
||||
Reference in New Issue
Block a user