mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-26 21:17:48 +00:00
130 lines
4.5 KiB
TypeScript
130 lines
4.5 KiB
TypeScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { afterEach, describe, expect, it } from "vitest";
|
|
import {
|
|
auditOpenClawPeerDependenciesInManagedNpmRoot,
|
|
linkOpenClawPeerDependencies,
|
|
relinkOpenClawPeerDependenciesInManagedNpmRoot,
|
|
} from "./plugin-peer-link.js";
|
|
import { cleanupTrackedTempDirs, makeTrackedTempDir } from "./test-helpers/fs-fixtures.js";
|
|
|
|
const tempDirs: string[] = [];
|
|
|
|
afterEach(() => {
|
|
cleanupTrackedTempDirs(tempDirs);
|
|
});
|
|
|
|
function makeTempDir() {
|
|
return makeTrackedTempDir("openclaw-plugin-peer-link", tempDirs);
|
|
}
|
|
|
|
describe("plugin peer links", () => {
|
|
it("relinks openclaw peers in the managed npm root", async () => {
|
|
const npmRoot = makeTempDir();
|
|
const packageDir = path.join(npmRoot, "node_modules", "peer-plugin");
|
|
fs.mkdirSync(packageDir, { recursive: true });
|
|
fs.writeFileSync(
|
|
path.join(packageDir, "package.json"),
|
|
JSON.stringify({
|
|
name: "peer-plugin",
|
|
version: "1.0.0",
|
|
peerDependencies: {
|
|
openclaw: ">=2026.0.0",
|
|
},
|
|
}),
|
|
"utf8",
|
|
);
|
|
|
|
const messages: string[] = [];
|
|
const result = await relinkOpenClawPeerDependenciesInManagedNpmRoot({
|
|
npmRoot,
|
|
logger: {
|
|
info: (message) => messages.push(message),
|
|
warn: (message) => messages.push(message),
|
|
},
|
|
});
|
|
|
|
const linkPath = path.join(packageDir, "node_modules", "openclaw");
|
|
expect(result).toEqual({ checked: 1, attempted: 1, repaired: 1, skipped: 0 });
|
|
expect(fs.lstatSync(linkPath).isSymbolicLink()).toBe(true);
|
|
expect(fs.realpathSync(linkPath)).toBe(fs.realpathSync(process.cwd()));
|
|
expect(messages.join("\n")).toContain('Linked peerDependency "openclaw"');
|
|
});
|
|
|
|
it("audits missing managed npm openclaw peer links without relinking", async () => {
|
|
const npmRoot = makeTempDir();
|
|
const packageDir = path.join(npmRoot, "node_modules", "peer-plugin");
|
|
fs.mkdirSync(packageDir, { recursive: true });
|
|
fs.writeFileSync(
|
|
path.join(packageDir, "package.json"),
|
|
JSON.stringify({
|
|
name: "peer-plugin",
|
|
version: "1.0.0",
|
|
peerDependencies: {
|
|
openclaw: ">=2026.0.0",
|
|
},
|
|
}),
|
|
"utf8",
|
|
);
|
|
|
|
const result = await auditOpenClawPeerDependenciesInManagedNpmRoot({ npmRoot });
|
|
|
|
const linkPath = path.join(packageDir, "node_modules", "openclaw");
|
|
expect(result.checked).toBe(1);
|
|
expect(result.broken).toBe(1);
|
|
expect(result.issues[0]?.packageName).toBe("peer-plugin");
|
|
expect(result.issues[0]?.reason).toContain(linkPath);
|
|
expect(fs.existsSync(linkPath)).toBe(false);
|
|
});
|
|
|
|
it.runIf(process.platform !== "win32")(
|
|
"does not follow a package-local node_modules symlink while linking openclaw peers",
|
|
async () => {
|
|
const root = makeTempDir();
|
|
const packageDir = path.join(root, "peer-plugin");
|
|
const outsideDir = path.join(root, "outside-node-modules");
|
|
fs.mkdirSync(packageDir, { recursive: true });
|
|
fs.mkdirSync(outsideDir, { recursive: true });
|
|
fs.symlinkSync(outsideDir, path.join(packageDir, "node_modules"), "dir");
|
|
|
|
const warnings: string[] = [];
|
|
const result = await linkOpenClawPeerDependencies({
|
|
installedDir: packageDir,
|
|
peerDependencies: {
|
|
openclaw: ">=2026.0.0",
|
|
},
|
|
logger: {
|
|
warn: (message) => warnings.push(message),
|
|
},
|
|
});
|
|
|
|
expect(result).toEqual({ repaired: 0, skipped: 1 });
|
|
expect(fs.existsSync(path.join(outsideDir, "openclaw"))).toBe(false);
|
|
expect(warnings.join("\n")).toContain("is not a real directory");
|
|
},
|
|
);
|
|
|
|
it("does not delete an existing real openclaw package directory", async () => {
|
|
const root = makeTempDir();
|
|
const packageDir = path.join(root, "peer-plugin");
|
|
const existingOpenClawDir = path.join(packageDir, "node_modules", "openclaw");
|
|
fs.mkdirSync(existingOpenClawDir, { recursive: true });
|
|
fs.writeFileSync(path.join(existingOpenClawDir, "package.json"), '{"name":"openclaw"}', "utf8");
|
|
|
|
const warnings: string[] = [];
|
|
const result = await linkOpenClawPeerDependencies({
|
|
installedDir: packageDir,
|
|
peerDependencies: {
|
|
openclaw: ">=2026.0.0",
|
|
},
|
|
logger: {
|
|
warn: (message) => warnings.push(message),
|
|
},
|
|
});
|
|
|
|
expect(result).toEqual({ repaired: 0, skipped: 1 });
|
|
expect(fs.existsSync(path.join(existingOpenClawDir, "package.json"))).toBe(true);
|
|
expect(warnings.join("\n")).toContain("already exists and is not a symlink");
|
|
});
|
|
});
|