From f806b07208883c929c563d206bc2f619abf5fc82 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 14 Mar 2026 00:29:32 +0000 Subject: [PATCH] refactor: share cli install helpers --- src/cli/daemon-cli/install.test.ts | 23 +++++++++++------------ src/cli/nodes-cli/register.camera.ts | 13 ++++++++----- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/cli/daemon-cli/install.test.ts b/src/cli/daemon-cli/install.test.ts index 7401dc3b1a2..320046dad4a 100644 --- a/src/cli/daemon-cli/install.test.ts +++ b/src/cli/daemon-cli/install.test.ts @@ -126,6 +126,15 @@ function expectFirstInstallPlanCallOmitsToken() { expect(firstArg && "token" in firstArg).toBe(false); } +function mockResolvedGatewayTokenSecretRef() { + resolveSecretInputRefMock.mockReturnValue({ + ref: { source: "env", provider: "default", id: "OPENCLAW_GATEWAY_TOKEN" }, + }); + resolveSecretRefValuesMock.mockResolvedValue( + new Map([["env:default:OPENCLAW_GATEWAY_TOKEN", "resolved-from-secretref"]]), + ); +} + const { runDaemonInstall } = await import("./install.js"); const envSnapshot = captureFullEnv(); @@ -195,12 +204,7 @@ describe("runDaemonInstall", () => { }); it("validates token SecretRef but does not serialize resolved token into service env", async () => { - resolveSecretInputRefMock.mockReturnValue({ - ref: { source: "env", provider: "default", id: "OPENCLAW_GATEWAY_TOKEN" }, - }); - resolveSecretRefValuesMock.mockResolvedValue( - new Map([["env:default:OPENCLAW_GATEWAY_TOKEN", "resolved-from-secretref"]]), - ); + mockResolvedGatewayTokenSecretRef(); await runDaemonInstall({ json: true }); @@ -219,12 +223,7 @@ describe("runDaemonInstall", () => { loadConfigMock.mockReturnValue({ gateway: { auth: { mode: "token", token: "${OPENCLAW_GATEWAY_TOKEN}" } }, }); - resolveSecretInputRefMock.mockReturnValue({ - ref: { source: "env", provider: "default", id: "OPENCLAW_GATEWAY_TOKEN" }, - }); - resolveSecretRefValuesMock.mockResolvedValue( - new Map([["env:default:OPENCLAW_GATEWAY_TOKEN", "resolved-from-secretref"]]), - ); + mockResolvedGatewayTokenSecretRef(); await runDaemonInstall({ json: true }); diff --git a/src/cli/nodes-cli/register.camera.ts b/src/cli/nodes-cli/register.camera.ts index 82cde2a35f3..9c813cecc5f 100644 --- a/src/cli/nodes-cli/register.camera.ts +++ b/src/cli/nodes-cli/register.camera.ts @@ -31,6 +31,12 @@ const parseFacing = (value: string): CameraFacing => { throw new Error(`invalid facing: ${value} (expected front|back)`); }; +function getGatewayInvokePayload(raw: unknown): unknown { + return typeof raw === "object" && raw !== null + ? (raw as { payload?: unknown }).payload + : undefined; +} + export function registerNodesCameraCommands(nodes: Command) { const camera = nodes.command("camera").description("Capture camera media from a paired node"); @@ -157,9 +163,7 @@ export function registerNodesCameraCommands(nodes: Command) { }); const raw = await callGatewayCli("node.invoke", opts, invokeParams); - const res = - typeof raw === "object" && raw !== null ? (raw as { payload?: unknown }) : {}; - const payload = parseCameraSnapPayload(res.payload); + const payload = parseCameraSnapPayload(getGatewayInvokePayload(raw)); const filePath = cameraTempPath({ kind: "snap", facing, @@ -229,8 +233,7 @@ export function registerNodesCameraCommands(nodes: Command) { }); const raw = await callGatewayCli("node.invoke", opts, invokeParams); - const res = typeof raw === "object" && raw !== null ? (raw as { payload?: unknown }) : {}; - const payload = parseCameraClipPayload(res.payload); + const payload = parseCameraClipPayload(getGatewayInvokePayload(raw)); const filePath = await writeCameraClipPayloadToFile({ payload, facing,