mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:10:44 +00:00
fix(plugins): stabilize registry package paths
This commit is contained in:
@@ -64,6 +64,7 @@ function createPluginCandidate(params: {
|
||||
origin?: PluginCandidate["origin"];
|
||||
packageName?: string;
|
||||
packageVersion?: string;
|
||||
packageDir?: string;
|
||||
packageManifest?: OpenClawPackageManifest;
|
||||
}): PluginCandidate {
|
||||
return {
|
||||
@@ -73,7 +74,7 @@ function createPluginCandidate(params: {
|
||||
origin: params.origin ?? "global",
|
||||
packageName: params.packageName,
|
||||
packageVersion: params.packageVersion,
|
||||
packageDir: params.rootDir,
|
||||
packageDir: params.packageDir ?? params.rootDir,
|
||||
packageManifest: params.packageManifest,
|
||||
};
|
||||
}
|
||||
@@ -211,6 +212,33 @@ describe("installed plugin index", () => {
|
||||
expect(contributions.contracts.get("tools")).toEqual(["demo"]);
|
||||
});
|
||||
|
||||
it("keeps packageJson paths root-relative when packageDir is reached through a symlink", () => {
|
||||
const fixture = createRichPluginFixture();
|
||||
const linkParent = makeTempDir();
|
||||
const linkRoot = path.join(linkParent, "linked-demo");
|
||||
try {
|
||||
fs.symlinkSync(fixture.rootDir, linkRoot, "dir");
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
const index = loadInstalledPluginIndex({
|
||||
candidates: [
|
||||
createPluginCandidate({
|
||||
rootDir: fs.realpathSync(fixture.rootDir),
|
||||
packageDir: linkRoot,
|
||||
packageName: "@vendor/demo-plugin",
|
||||
packageVersion: "1.2.3",
|
||||
}),
|
||||
],
|
||||
env: hermeticEnv(),
|
||||
});
|
||||
|
||||
expect(index.plugins[0]?.packageJson).toMatchObject({
|
||||
path: "package.json",
|
||||
});
|
||||
});
|
||||
|
||||
it("exposes cold registry records and owners for existing plugins without install ledgers", () => {
|
||||
const fixture = createRichPluginFixture();
|
||||
const index = loadInstalledPluginIndex({
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
type PluginManifestRegistry,
|
||||
} from "./manifest-registry.js";
|
||||
import type { PluginDiagnostic } from "./manifest-types.js";
|
||||
import { safeRealpathSync } from "./path-safety.js";
|
||||
import { hasKind } from "./slots.js";
|
||||
|
||||
export const INSTALLED_PLUGIN_INDEX_VERSION = 1;
|
||||
@@ -284,10 +285,17 @@ function resolvePackageJsonPath(candidate: PluginCandidate | undefined): string
|
||||
if (!candidate?.packageDir) {
|
||||
return undefined;
|
||||
}
|
||||
const packageJsonPath = path.join(candidate.packageDir, "package.json");
|
||||
const packageDir = safeRealpathSync(candidate.packageDir) ?? path.resolve(candidate.packageDir);
|
||||
const packageJsonPath = path.join(packageDir, "package.json");
|
||||
return fs.existsSync(packageJsonPath) ? packageJsonPath : undefined;
|
||||
}
|
||||
|
||||
function resolvePackageJsonRelativePath(rootDir: string, packageJsonPath: string): string {
|
||||
const resolvedRootDir = safeRealpathSync(rootDir) ?? path.resolve(rootDir);
|
||||
const relativePath = path.relative(resolvedRootDir, packageJsonPath) || "package.json";
|
||||
return relativePath.split(path.sep).join("/");
|
||||
}
|
||||
|
||||
function resolvePackageJsonRecord(params: {
|
||||
candidate: PluginCandidate | undefined;
|
||||
packageJsonPath: string | undefined;
|
||||
@@ -307,7 +315,7 @@ function resolvePackageJsonRecord(params: {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
path: path.relative(params.candidate.rootDir, params.packageJsonPath) || "package.json",
|
||||
path: resolvePackageJsonRelativePath(params.candidate.rootDir, params.packageJsonPath),
|
||||
hash,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user