
























@@ -1,11 +1,15 @@
1-import { beforeEach, describe, expect, it, vi } from "vitest";
1+import fs from "node:fs";
2+import os from "node:os";
3+import path from "node:path";
4+import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
25import type { PluginChannelCatalogEntry } from "../../plugins/channel-catalog-registry.js";
36import {
47hasBundledChannelPackageState,
58listBundledChannelIdsForPackageState,
69} from "./package-state-probes.js";
710811const listChannelCatalogEntriesMock = vi.hoisted(() => vi.fn());
12+const tempDirs: string[] = [];
9131014vi.mock("../../plugins/channel-catalog-registry.js", () => ({
1115listChannelCatalogEntries: listChannelCatalogEntriesMock,
@@ -30,10 +34,21 @@ function makeBundledChannelCatalogEntry(params: {
3034};
3135}
323637+function removeTempDirs() {
38+for (const tempDir of tempDirs.splice(0)) {
39+fs.rmSync(tempDir, { recursive: true, force: true });
40+}
41+}
42+3343beforeEach(() => {
44+removeTempDirs();
3445listChannelCatalogEntriesMock.mockReset();
3546});
364748+afterEach(() => {
49+removeTempDirs();
50+});
51+3752describe("channel package-state probes", () => {
3853it("uses channel ids when manifest plugin ids differ", () => {
3954listChannelCatalogEntriesMock.mockReturnValue([
@@ -61,4 +76,88 @@ describe("channel package-state probes", () => {
6176}),
6277).toBe(false);
6378});
79+80+it("prefers built bundled package-state probes when the catalog root is source", () => {
81+const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-package-state-probe-"));
82+tempDirs.push(root);
83+const sourceRoot = path.join(root, "extensions", "matrix");
84+const builtRoot = path.join(root, "dist", "extensions", "matrix");
85+fs.mkdirSync(sourceRoot, { recursive: true });
86+fs.mkdirSync(builtRoot, { recursive: true });
87+fs.writeFileSync(
88+path.join(sourceRoot, "auth-presence.ts"),
89+"throw new Error('source probe should not load');\n",
90+"utf8",
91+);
92+fs.writeFileSync(
93+path.join(builtRoot, "auth-presence.js"),
94+"module.exports.hasAnyMatrixAuth = () => true;\n",
95+"utf8",
96+);
97+98+listChannelCatalogEntriesMock.mockReturnValue([
99+{
100+pluginId: "matrix",
101+origin: "bundled",
102+rootDir: sourceRoot,
103+channel: {
104+id: "matrix",
105+persistedAuthState: {
106+specifier: "./auth-presence",
107+exportName: "hasAnyMatrixAuth",
108+},
109+},
110+} satisfies PluginChannelCatalogEntry,
111+]);
112+113+expect(
114+hasBundledChannelPackageState({
115+metadataKey: "persistedAuthState",
116+channelId: "matrix",
117+cfg: {},
118+}),
119+).toBe(true);
120+});
121+122+it("falls back to source package-state probes when built artifacts are stale", () => {
123+const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-package-state-fallback-"));
124+tempDirs.push(root);
125+const sourceRoot = path.join(root, "extensions", "whatsapp");
126+const builtRoot = path.join(root, "dist", "extensions", "whatsapp");
127+fs.mkdirSync(sourceRoot, { recursive: true });
128+fs.mkdirSync(builtRoot, { recursive: true });
129+fs.writeFileSync(
130+path.join(sourceRoot, "auth-presence.js"),
131+"module.exports.hasAnyWhatsAppAuth = () => true;\n",
132+"utf8",
133+);
134+fs.writeFileSync(
135+path.join(builtRoot, "auth-presence.js"),
136+"module.exports.stale = () => false;\n",
137+"utf8",
138+);
139+140+listChannelCatalogEntriesMock.mockReturnValue([
141+{
142+pluginId: "whatsapp",
143+origin: "bundled",
144+rootDir: sourceRoot,
145+channel: {
146+id: "whatsapp",
147+persistedAuthState: {
148+specifier: "./auth-presence",
149+exportName: "hasAnyWhatsAppAuth",
150+},
151+},
152+} satisfies PluginChannelCatalogEntry,
153+]);
154+155+expect(
156+hasBundledChannelPackageState({
157+metadataKey: "persistedAuthState",
158+channelId: "whatsapp",
159+cfg: {},
160+}),
161+).toBe(true);
162+});
64163});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。