From cec2435f41c0711ea8dd127849feceaa19987caa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Beteg=C3=B3n?= Date: Tue, 29 Sep 2026 08:39:31 +0200 Subject: [PATCH] fix(sdk): type variadic flags as arrays Stricli passes variadic flags to commands as arrays and the SDK forwards flags unchanged, but the generator declared them with their element type. Calls such as sdk.auth.login({ scope: "org:read" }) type-checked and then failed inside the handler. Co-authored-by: Cursor --- packages/cli/script/generate-sdk.ts | 2 +- packages/cli/test/lib/sdk-flag-types.test.ts | 33 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 packages/cli/test/lib/sdk-flag-types.test.ts diff --git a/packages/cli/script/generate-sdk.ts b/packages/cli/script/generate-sdk.ts index bd24e77f3..1cb4c5308 100644 --- a/packages/cli/script/generate-sdk.ts +++ b/packages/cli/script/generate-sdk.ts @@ -160,7 +160,7 @@ function extractSdkFlags(command: Command): SdkFlagInfo[] { flags.push({ name, kind, - tsType, + tsType: def.variadic ? `Array<${tsType}>` : tsType, optional, default: def.default, brief: def.brief, diff --git a/packages/cli/test/lib/sdk-flag-types.test.ts b/packages/cli/test/lib/sdk-flag-types.test.ts new file mode 100644 index 000000000..9986ad9ef --- /dev/null +++ b/packages/cli/test/lib/sdk-flag-types.test.ts @@ -0,0 +1,33 @@ +/** + * Unit Tests for Generated SDK Flag Types + * + * Stricli passes variadic flags to a command as arrays, and the SDK forwards flags to the + * handler unchanged. The generator used to declare them with their element type, so + * `sdk.auth.login({ scope: "org:read" })` type-checked and then failed inside the handler + * (`flags.scope.flatMap is not a function`). + */ + +import { readFileSync } from "node:fs"; +import { fileURLToPath } from "node:url"; +import { describe, expect, test } from "vitest"; + +const declarations = readFileSync( + fileURLToPath(new URL("../../src/sdk.generated.d.cts", import.meta.url)), + "utf-8" +); + +function paramsType(name: string): string { + const start = declarations.indexOf(`export type ${name} = {`); + if (start === -1) { + throw new Error(`${name} is missing from the generated SDK declarations`); + } + return declarations.slice(start, declarations.indexOf("\n};", start)); +} + +describe("generated SDK flag types", () => { + test("declares variadic flags as arrays and keeps scalar flags scalar", () => { + const login = paramsType("AuthLoginParams"); + expect(login).toContain("scope?: Array;"); + expect(login).toContain("token?: string;"); + }); +});