diff --git a/src/agents/tools/nodes-utils.ts b/src/agents/tools/nodes-utils.ts index 49f43c6000..6350294eb5 100644 --- a/src/agents/tools/nodes-utils.ts +++ b/src/agents/tools/nodes-utils.ts @@ -1,26 +1,10 @@ -import type { - NodeListNode, - PairedNode, - PairingList, - PendingRequest, -} from "../../shared/node-list-types.js"; +import { parseNodeList, parsePairingList } from "../../shared/node-list-parse.js"; +import type { NodeListNode } from "../../shared/node-list-types.js"; import { resolveNodeIdFromCandidates } from "../../shared/node-match.js"; import { callGatewayTool, type GatewayCallOptions } from "./gateway.js"; export type { NodeListNode }; -function parseNodeList(value: unknown): NodeListNode[] { - const obj = typeof value === "object" && value !== null ? (value as Record) : {}; - return Array.isArray(obj.nodes) ? (obj.nodes as NodeListNode[]) : []; -} - -function parsePairingList(value: unknown): PairingList { - const obj = typeof value === "object" && value !== null ? (value as Record) : {}; - const pending = Array.isArray(obj.pending) ? (obj.pending as PendingRequest[]) : []; - const paired = Array.isArray(obj.paired) ? (obj.paired as PairedNode[]) : []; - return { pending, paired }; -} - async function loadNodes(opts: GatewayCallOptions): Promise { try { const res = await callGatewayTool("node.list", opts, {}); diff --git a/src/cli/nodes-cli/format.ts b/src/cli/nodes-cli/format.ts index 646c5ac4cc..9a28af7d61 100644 --- a/src/cli/nodes-cli/format.ts +++ b/src/cli/nodes-cli/format.ts @@ -1,16 +1,4 @@ -import type { NodeListNode, PairedNode, PairingList, PendingRequest } from "./types.js"; - -export function parsePairingList(value: unknown): PairingList { - const obj = typeof value === "object" && value !== null ? (value as Record) : {}; - const pending = Array.isArray(obj.pending) ? (obj.pending as PendingRequest[]) : []; - const paired = Array.isArray(obj.paired) ? (obj.paired as PairedNode[]) : []; - return { pending, paired }; -} - -export function parseNodeList(value: unknown): NodeListNode[] { - const obj = typeof value === "object" && value !== null ? (value as Record) : {}; - return Array.isArray(obj.nodes) ? (obj.nodes as NodeListNode[]) : []; -} +export { parseNodeList, parsePairingList } from "../../shared/node-list-parse.js"; export function formatPermissions(raw: unknown) { if (!raw || typeof raw !== "object" || Array.isArray(raw)) { diff --git a/src/shared/node-list-parse.test.ts b/src/shared/node-list-parse.test.ts new file mode 100644 index 0000000000..379f439505 --- /dev/null +++ b/src/shared/node-list-parse.test.ts @@ -0,0 +1,24 @@ +import { describe, expect, it } from "vitest"; +import { parseNodeList, parsePairingList } from "./node-list-parse.js"; + +describe("shared/node-list-parse", () => { + it("parses node.list payloads", () => { + expect(parseNodeList({ nodes: [{ nodeId: "node-1" }] })).toEqual([{ nodeId: "node-1" }]); + expect(parseNodeList({ nodes: "nope" })).toEqual([]); + expect(parseNodeList(null)).toEqual([]); + }); + + it("parses node.pair.list payloads", () => { + expect( + parsePairingList({ + pending: [{ requestId: "r1", nodeId: "n1", ts: 1 }], + paired: [{ nodeId: "n1" }], + }), + ).toEqual({ + pending: [{ requestId: "r1", nodeId: "n1", ts: 1 }], + paired: [{ nodeId: "n1" }], + }); + expect(parsePairingList({ pending: 1, paired: "x" })).toEqual({ pending: [], paired: [] }); + expect(parsePairingList(undefined)).toEqual({ pending: [], paired: [] }); + }); +}); diff --git a/src/shared/node-list-parse.ts b/src/shared/node-list-parse.ts new file mode 100644 index 0000000000..236bbe7364 --- /dev/null +++ b/src/shared/node-list-parse.ts @@ -0,0 +1,17 @@ +import type { NodeListNode, PairedNode, PairingList, PendingRequest } from "./node-list-types.js"; + +function asRecord(value: unknown): Record { + return typeof value === "object" && value !== null ? (value as Record) : {}; +} + +export function parsePairingList(value: unknown): PairingList { + const obj = asRecord(value); + const pending = Array.isArray(obj.pending) ? (obj.pending as PendingRequest[]) : []; + const paired = Array.isArray(obj.paired) ? (obj.paired as PairedNode[]) : []; + return { pending, paired }; +} + +export function parseNodeList(value: unknown): NodeListNode[] { + const obj = asRecord(value); + return Array.isArray(obj.nodes) ? (obj.nodes as NodeListNode[]) : []; +}