import { describe, expect, it } from "vitest"; import { buildNpmResolutionInstallFields, recordPluginInstall } from "./installs.js"; function expectRecordedInstall(pluginId: string, next: ReturnType) { expect(next.plugins?.installs?.[pluginId]).toMatchObject({ source: "npm", spec: `${pluginId}@latest`, }); expect(typeof next.plugins?.installs?.[pluginId]?.installedAt).toBe("string"); } function createExpectedResolutionFields( overrides: Partial>, ) { return { resolvedName: undefined, resolvedVersion: undefined, resolvedSpec: undefined, integrity: undefined, shasum: undefined, resolvedAt: undefined, ...overrides, }; } function expectResolutionFieldsCase(params: { input: Parameters[0]; expected: ReturnType; }) { expect(buildNpmResolutionInstallFields(params.input)).toEqual(params.expected); } describe("buildNpmResolutionInstallFields", () => { it.each([ { name: "maps npm resolution metadata into install record fields", input: { name: "@openclaw/demo", version: "1.2.3", resolvedSpec: "@openclaw/demo@1.2.3", integrity: "sha512-abc", shasum: "deadbeef", resolvedAt: "2026-02-22T00:00:00.000Z", }, expected: createExpectedResolutionFields({ resolvedName: "@openclaw/demo", resolvedVersion: "1.2.3", resolvedSpec: "@openclaw/demo@1.2.3", integrity: "sha512-abc", shasum: "deadbeef", resolvedAt: "2026-02-22T00:00:00.000Z", }), }, { name: "returns undefined fields when resolution is missing", input: undefined, expected: createExpectedResolutionFields({}), }, { name: "keeps missing partial resolution fields undefined", input: { name: "@openclaw/demo", }, expected: createExpectedResolutionFields({ resolvedName: "@openclaw/demo", }), }, ] as const)("$name", expectResolutionFieldsCase); }); describe("recordPluginInstall", () => { it("stores install metadata for the plugin id", () => { const next = recordPluginInstall({}, { pluginId: "demo", source: "npm", spec: "demo@latest" }); expectRecordedInstall("demo", next); }); });