From a4b7c99b2e69d6b0d2046e7850f2500584063cea Mon Sep 17 00:00:00 2001 From: Viljami Kuosmanen Date: Mon, 17 Aug 2026 14:30:35 +0300 Subject: [PATCH] fix(cli): stop dropping repeated -p flags for required params citty parses args via node:util.parseArgs, which never enables "multiple" for any arg type, so a repeated string flag (e.g. -p a=1 -p b=2) silently keeps only the last occurrence in args.param -- earlier -p flags vanish with no error. Any operation needing more than one -p (the common case for required path/query params) would then have those earlier params reported as missing and get re-prompted interactively, even though they were passed on the command line. Add collectRepeatedFlag() to recover every -p/--param occurrence directly from rawArgs, and wire it into the generated per-API command template (scripts/generate.ts) so it takes precedence over cittys lossy args.param whenever more than one occurrence is present. Co-Authored-By: Claude Sonnet 5 --- packages/cli/scripts/generate.ts | 7 +++ .../cli/src/commands/apis/access-token.ts | 7 +++ .../src/commands/apis/address-suggestions.ts | 7 +++ packages/cli/src/commands/apis/address.ts | 7 +++ packages/cli/src/commands/apis/ai-agents.ts | 7 +++ packages/cli/src/commands/apis/audit-logs.ts | 7 +++ packages/cli/src/commands/apis/automation.ts | 7 +++ packages/cli/src/commands/apis/billing.ts | 7 +++ .../src/commands/apis/blueprint-manifest.ts | 7 +++ packages/cli/src/commands/apis/calendar.ts | 7 +++ .../src/commands/apis/configuration-hub.ts | 7 +++ packages/cli/src/commands/apis/consent.ts | 7 +++ .../cli/src/commands/apis/customer-portal.ts | 7 +++ packages/cli/src/commands/apis/dashboard.ts | 7 +++ .../cli/src/commands/apis/data-governance.ts | 7 +++ .../cli/src/commands/apis/deduplication.ts | 7 +++ packages/cli/src/commands/apis/design.ts | 7 +++ packages/cli/src/commands/apis/document.ts | 7 +++ .../cli/src/commands/apis/email-settings.ts | 7 +++ .../cli/src/commands/apis/email-template.ts | 7 +++ .../cli/src/commands/apis/entity-mapping.ts | 7 +++ packages/cli/src/commands/apis/entity.ts | 7 +++ .../cli/src/commands/apis/environments.ts | 7 +++ .../cli/src/commands/apis/event-catalog.ts | 7 +++ packages/cli/src/commands/apis/file.ts | 7 +++ packages/cli/src/commands/apis/iban.ts | 7 +++ .../src/commands/apis/integration-toolkit.ts | 7 +++ packages/cli/src/commands/apis/journey.ts | 7 +++ packages/cli/src/commands/apis/kanban.ts | 7 +++ packages/cli/src/commands/apis/message.ts | 7 +++ packages/cli/src/commands/apis/metering.ts | 7 +++ packages/cli/src/commands/apis/notes.ts | 7 +++ .../cli/src/commands/apis/notification.ts | 7 +++ .../cli/src/commands/apis/organization.ts | 7 +++ .../src/commands/apis/partner-directory.ts | 7 +++ packages/cli/src/commands/apis/permissions.ts | 7 +++ .../cli/src/commands/apis/pricing-tier.ts | 7 +++ packages/cli/src/commands/apis/pricing.ts | 7 +++ packages/cli/src/commands/apis/purpose.ts | 7 +++ packages/cli/src/commands/apis/query.ts | 7 +++ packages/cli/src/commands/apis/sandbox.ts | 7 +++ packages/cli/src/commands/apis/sharing.ts | 7 +++ packages/cli/src/commands/apis/snapshot.ts | 7 +++ packages/cli/src/commands/apis/submission.ts | 7 +++ packages/cli/src/commands/apis/targeting.ts | 7 +++ .../src/commands/apis/template-variables.ts | 7 +++ packages/cli/src/commands/apis/user.ts | 7 +++ .../cli/src/commands/apis/validation-rules.ts | 7 +++ packages/cli/src/commands/apis/webhooks.ts | 7 +++ .../src/commands/apis/workflow-definition.ts | 7 +++ packages/cli/src/commands/apis/workflow.ts | 7 +++ packages/cli/src/lib/flag-collector.ts | 43 ++++++++++++++ packages/cli/test/entity-command.test.ts | 54 +++++++++++++++++ packages/cli/test/flag-collector.test.ts | 59 +++++++++++++++++++ 54 files changed, 513 insertions(+) create mode 100644 packages/cli/src/lib/flag-collector.ts create mode 100644 packages/cli/test/entity-command.test.ts create mode 100644 packages/cli/test/flag-collector.test.ts diff --git a/packages/cli/scripts/generate.ts b/packages/cli/scripts/generate.ts index 3e6119b1f..16817896c 100644 --- a/packages/cli/scripts/generate.ts +++ b/packages/cli/scripts/generate.ts @@ -353,6 +353,7 @@ const generateApiCommand = (client: ClientInfo): string => { return `// Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: '${client.kebabName}', description: '${client.title.replace(/'/g, "\\'")}' }, @@ -390,8 +391,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('${client.kebabName}', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/access-token.ts b/packages/cli/src/commands/apis/access-token.ts index a10d10f36..930ef8fe5 100644 --- a/packages/cli/src/commands/apis/access-token.ts +++ b/packages/cli/src/commands/apis/access-token.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'access-token', description: 'Access Token API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('access-token', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/address-suggestions.ts b/packages/cli/src/commands/apis/address-suggestions.ts index d9c16e496..143f59ec9 100644 --- a/packages/cli/src/commands/apis/address-suggestions.ts +++ b/packages/cli/src/commands/apis/address-suggestions.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'address-suggestions', description: 'Address Suggestions API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('address-suggestions', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/address.ts b/packages/cli/src/commands/apis/address.ts index 1c104f354..f676a80a1 100644 --- a/packages/cli/src/commands/apis/address.ts +++ b/packages/cli/src/commands/apis/address.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'address', description: 'Address API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('address', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/ai-agents.ts b/packages/cli/src/commands/apis/ai-agents.ts index 436465123..42b6cb008 100644 --- a/packages/cli/src/commands/apis/ai-agents.ts +++ b/packages/cli/src/commands/apis/ai-agents.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'ai-agents', description: 'AI Agents API - OpenAPI 3.0' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('ai-agents', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/audit-logs.ts b/packages/cli/src/commands/apis/audit-logs.ts index 1d48725b2..341693fd5 100644 --- a/packages/cli/src/commands/apis/audit-logs.ts +++ b/packages/cli/src/commands/apis/audit-logs.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'audit-logs', description: 'Audit Log' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('audit-logs', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/automation.ts b/packages/cli/src/commands/apis/automation.ts index 9a8a97dd6..f5a7f62ab 100644 --- a/packages/cli/src/commands/apis/automation.ts +++ b/packages/cli/src/commands/apis/automation.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'automation', description: 'Automation API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('automation', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/billing.ts b/packages/cli/src/commands/apis/billing.ts index 452d1f9b1..e97cc2746 100644 --- a/packages/cli/src/commands/apis/billing.ts +++ b/packages/cli/src/commands/apis/billing.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'billing', description: 'Billing API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('billing', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/blueprint-manifest.ts b/packages/cli/src/commands/apis/blueprint-manifest.ts index 8a6b14c47..070052121 100644 --- a/packages/cli/src/commands/apis/blueprint-manifest.ts +++ b/packages/cli/src/commands/apis/blueprint-manifest.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'blueprint-manifest', description: 'Blueprint Manifest API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('blueprint-manifest', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/calendar.ts b/packages/cli/src/commands/apis/calendar.ts index f700df539..1b4a188be 100644 --- a/packages/cli/src/commands/apis/calendar.ts +++ b/packages/cli/src/commands/apis/calendar.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'calendar', description: 'Calendar API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('calendar', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/configuration-hub.ts b/packages/cli/src/commands/apis/configuration-hub.ts index bee03ae70..b57921afe 100644 --- a/packages/cli/src/commands/apis/configuration-hub.ts +++ b/packages/cli/src/commands/apis/configuration-hub.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'configuration-hub', description: 'Configuration Hub API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('configuration-hub', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/consent.ts b/packages/cli/src/commands/apis/consent.ts index 490314681..5a7a7db8b 100644 --- a/packages/cli/src/commands/apis/consent.ts +++ b/packages/cli/src/commands/apis/consent.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'consent', description: 'Consent API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('consent', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/customer-portal.ts b/packages/cli/src/commands/apis/customer-portal.ts index 5c5c1842f..b7cdaf04a 100644 --- a/packages/cli/src/commands/apis/customer-portal.ts +++ b/packages/cli/src/commands/apis/customer-portal.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'customer-portal', description: 'Portal API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('customer-portal', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/dashboard.ts b/packages/cli/src/commands/apis/dashboard.ts index c48c1cf9d..1e29303fd 100644 --- a/packages/cli/src/commands/apis/dashboard.ts +++ b/packages/cli/src/commands/apis/dashboard.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'dashboard', description: 'Dashboard API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('dashboard', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/data-governance.ts b/packages/cli/src/commands/apis/data-governance.ts index dff501418..6767d63ed 100644 --- a/packages/cli/src/commands/apis/data-governance.ts +++ b/packages/cli/src/commands/apis/data-governance.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'data-governance', description: 'Data Governance API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('data-governance', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/deduplication.ts b/packages/cli/src/commands/apis/deduplication.ts index 1569bac9d..e79bcbf7b 100644 --- a/packages/cli/src/commands/apis/deduplication.ts +++ b/packages/cli/src/commands/apis/deduplication.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'deduplication', description: 'Deduplication API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('deduplication', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/design.ts b/packages/cli/src/commands/apis/design.ts index aeea70e19..058543951 100644 --- a/packages/cli/src/commands/apis/design.ts +++ b/packages/cli/src/commands/apis/design.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'design', description: 'Design Builder API v2' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('design', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/document.ts b/packages/cli/src/commands/apis/document.ts index 25a042d66..cf528774f 100644 --- a/packages/cli/src/commands/apis/document.ts +++ b/packages/cli/src/commands/apis/document.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'document', description: 'Document API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('document', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/email-settings.ts b/packages/cli/src/commands/apis/email-settings.ts index 32520805c..b5c52b4e0 100644 --- a/packages/cli/src/commands/apis/email-settings.ts +++ b/packages/cli/src/commands/apis/email-settings.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'email-settings', description: 'Messaging Settings API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('email-settings', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/email-template.ts b/packages/cli/src/commands/apis/email-template.ts index 0c4b27fe3..9dccef82c 100644 --- a/packages/cli/src/commands/apis/email-template.ts +++ b/packages/cli/src/commands/apis/email-template.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'email-template', description: 'Email template API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('email-template', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/entity-mapping.ts b/packages/cli/src/commands/apis/entity-mapping.ts index 1fd0fc7cb..900d2d682 100644 --- a/packages/cli/src/commands/apis/entity-mapping.ts +++ b/packages/cli/src/commands/apis/entity-mapping.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'entity-mapping', description: 'Entity Mapping API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('entity-mapping', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/entity.ts b/packages/cli/src/commands/apis/entity.ts index 101731a26..963b3f877 100644 --- a/packages/cli/src/commands/apis/entity.ts +++ b/packages/cli/src/commands/apis/entity.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'entity', description: 'Entity API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('entity', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/environments.ts b/packages/cli/src/commands/apis/environments.ts index 1d725dd98..163a371cb 100644 --- a/packages/cli/src/commands/apis/environments.ts +++ b/packages/cli/src/commands/apis/environments.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'environments', description: 'Environments API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('environments', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/event-catalog.ts b/packages/cli/src/commands/apis/event-catalog.ts index 4ff1ac987..fdf06b7dc 100644 --- a/packages/cli/src/commands/apis/event-catalog.ts +++ b/packages/cli/src/commands/apis/event-catalog.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'event-catalog', description: 'Event Catalog API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('event-catalog', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/file.ts b/packages/cli/src/commands/apis/file.ts index caec36ed8..0a4426283 100644 --- a/packages/cli/src/commands/apis/file.ts +++ b/packages/cli/src/commands/apis/file.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'file', description: 'File API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('file', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/iban.ts b/packages/cli/src/commands/apis/iban.ts index 53ac8efd1..a975d38af 100644 --- a/packages/cli/src/commands/apis/iban.ts +++ b/packages/cli/src/commands/apis/iban.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'iban', description: 'Iban API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('iban', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/integration-toolkit.ts b/packages/cli/src/commands/apis/integration-toolkit.ts index 89930b2ea..ea172c926 100644 --- a/packages/cli/src/commands/apis/integration-toolkit.ts +++ b/packages/cli/src/commands/apis/integration-toolkit.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'integration-toolkit', description: 'Integration Toolkit API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('integration-toolkit', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/journey.ts b/packages/cli/src/commands/apis/journey.ts index f9f7d4cb1..612db683c 100644 --- a/packages/cli/src/commands/apis/journey.ts +++ b/packages/cli/src/commands/apis/journey.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'journey', description: 'Journey API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('journey', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/kanban.ts b/packages/cli/src/commands/apis/kanban.ts index a33e46192..66e049b58 100644 --- a/packages/cli/src/commands/apis/kanban.ts +++ b/packages/cli/src/commands/apis/kanban.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'kanban', description: 'Kanban API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('kanban', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/message.ts b/packages/cli/src/commands/apis/message.ts index 7d75c3d08..f1b9ec4bf 100644 --- a/packages/cli/src/commands/apis/message.ts +++ b/packages/cli/src/commands/apis/message.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'message', description: 'Message API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('message', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/metering.ts b/packages/cli/src/commands/apis/metering.ts index deac3ade2..4582f0861 100644 --- a/packages/cli/src/commands/apis/metering.ts +++ b/packages/cli/src/commands/apis/metering.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'metering', description: 'Metering API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('metering', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/notes.ts b/packages/cli/src/commands/apis/notes.ts index a6ff13fb3..6e2063022 100644 --- a/packages/cli/src/commands/apis/notes.ts +++ b/packages/cli/src/commands/apis/notes.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'notes', description: 'Notes API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('notes', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/notification.ts b/packages/cli/src/commands/apis/notification.ts index 313a0535a..35df6bb91 100644 --- a/packages/cli/src/commands/apis/notification.ts +++ b/packages/cli/src/commands/apis/notification.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'notification', description: 'Notification API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('notification', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/organization.ts b/packages/cli/src/commands/apis/organization.ts index 80b520bbb..0348f8d83 100644 --- a/packages/cli/src/commands/apis/organization.ts +++ b/packages/cli/src/commands/apis/organization.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'organization', description: 'Organization API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('organization', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/partner-directory.ts b/packages/cli/src/commands/apis/partner-directory.ts index 1765a4f16..aab8710b0 100644 --- a/packages/cli/src/commands/apis/partner-directory.ts +++ b/packages/cli/src/commands/apis/partner-directory.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'partner-directory', description: 'Partner Directory API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('partner-directory', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/permissions.ts b/packages/cli/src/commands/apis/permissions.ts index e1cd93cd8..02de1aa81 100644 --- a/packages/cli/src/commands/apis/permissions.ts +++ b/packages/cli/src/commands/apis/permissions.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'permissions', description: 'Permissions API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('permissions', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/pricing-tier.ts b/packages/cli/src/commands/apis/pricing-tier.ts index 425c20813..5a9af2b8b 100644 --- a/packages/cli/src/commands/apis/pricing-tier.ts +++ b/packages/cli/src/commands/apis/pricing-tier.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'pricing-tier', description: 'Pricing Tier API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('pricing-tier', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/pricing.ts b/packages/cli/src/commands/apis/pricing.ts index 2ba5509cc..5cee802b0 100644 --- a/packages/cli/src/commands/apis/pricing.ts +++ b/packages/cli/src/commands/apis/pricing.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'pricing', description: 'Pricing API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('pricing', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/purpose.ts b/packages/cli/src/commands/apis/purpose.ts index f451e68b0..b512b8e60 100644 --- a/packages/cli/src/commands/apis/purpose.ts +++ b/packages/cli/src/commands/apis/purpose.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'purpose', description: 'Purpose API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('purpose', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/query.ts b/packages/cli/src/commands/apis/query.ts index 802cf178f..e34a1b4f9 100644 --- a/packages/cli/src/commands/apis/query.ts +++ b/packages/cli/src/commands/apis/query.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'query', description: 'Query API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('query', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/sandbox.ts b/packages/cli/src/commands/apis/sandbox.ts index e11566c37..5cacd3c27 100644 --- a/packages/cli/src/commands/apis/sandbox.ts +++ b/packages/cli/src/commands/apis/sandbox.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'sandbox', description: 'Sandbox API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('sandbox', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/sharing.ts b/packages/cli/src/commands/apis/sharing.ts index ae21add85..a00c35674 100644 --- a/packages/cli/src/commands/apis/sharing.ts +++ b/packages/cli/src/commands/apis/sharing.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'sharing', description: 'Sharing API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('sharing', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/snapshot.ts b/packages/cli/src/commands/apis/snapshot.ts index cae302883..344c5a7c1 100644 --- a/packages/cli/src/commands/apis/snapshot.ts +++ b/packages/cli/src/commands/apis/snapshot.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'snapshot', description: 'Snapshot API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('snapshot', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/submission.ts b/packages/cli/src/commands/apis/submission.ts index 054ed8098..d2188edeb 100644 --- a/packages/cli/src/commands/apis/submission.ts +++ b/packages/cli/src/commands/apis/submission.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'submission', description: 'Submission API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('submission', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/targeting.ts b/packages/cli/src/commands/apis/targeting.ts index 5b364b472..cff689975 100644 --- a/packages/cli/src/commands/apis/targeting.ts +++ b/packages/cli/src/commands/apis/targeting.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'targeting', description: 'Targeting API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('targeting', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/template-variables.ts b/packages/cli/src/commands/apis/template-variables.ts index 672c89c33..8366f72e3 100644 --- a/packages/cli/src/commands/apis/template-variables.ts +++ b/packages/cli/src/commands/apis/template-variables.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'template-variables', description: 'Template Variables API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('template-variables', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/user.ts b/packages/cli/src/commands/apis/user.ts index 43ae8c6d6..4d274f901 100644 --- a/packages/cli/src/commands/apis/user.ts +++ b/packages/cli/src/commands/apis/user.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'user', description: 'User API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('user', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/validation-rules.ts b/packages/cli/src/commands/apis/validation-rules.ts index cec4f6632..e24828247 100644 --- a/packages/cli/src/commands/apis/validation-rules.ts +++ b/packages/cli/src/commands/apis/validation-rules.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'validation-rules', description: 'Validation Rules API' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('validation-rules', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/webhooks.ts b/packages/cli/src/commands/apis/webhooks.ts index 92f70920d..efc295075 100644 --- a/packages/cli/src/commands/apis/webhooks.ts +++ b/packages/cli/src/commands/apis/webhooks.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'webhooks', description: 'Webhooks' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('webhooks', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/workflow-definition.ts b/packages/cli/src/commands/apis/workflow-definition.ts index f18c23309..0cc0c116a 100644 --- a/packages/cli/src/commands/apis/workflow-definition.ts +++ b/packages/cli/src/commands/apis/workflow-definition.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'workflow-definition', description: 'Workflows Definitions' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('workflow-definition', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/commands/apis/workflow.ts b/packages/cli/src/commands/apis/workflow.ts index bd3098929..17a843424 100644 --- a/packages/cli/src/commands/apis/workflow.ts +++ b/packages/cli/src/commands/apis/workflow.ts @@ -1,6 +1,7 @@ // Auto-generated by scripts/generate.ts — do not edit import { defineCommand } from 'citty'; import { callApi } from '../../lib/call.js'; +import { collectRepeatedFlag } from '../../lib/flag-collector.js'; export default defineCommand({ meta: { name: 'workflow', description: 'Workflows Executions' }, @@ -38,8 +39,14 @@ export default defineCommand({ } } + // citty (via node:util.parseArgs) only keeps the last occurrence of a + // repeated string flag, so args.param silently drops earlier -p flags. + // Recover all of them directly from rawArgs instead. + const paramFlags = collectRepeatedFlag(rawArgs ?? [], ['p', 'param']); + return callApi('workflow', { ...args, + param: paramFlags.length > 0 ? paramFlags : args.param, help: !!(args as Record)._ophelp, _apihelp: !!(args as Record)._apihelp, _args: positionalArgs, diff --git a/packages/cli/src/lib/flag-collector.ts b/packages/cli/src/lib/flag-collector.ts new file mode 100644 index 000000000..e9d4b8f2a --- /dev/null +++ b/packages/cli/src/lib/flag-collector.ts @@ -0,0 +1,43 @@ +/** + * Collects every occurrence of a repeatable string flag (e.g. `-p a=1 -p b=2`) + * directly from rawArgs. + * + * Motivation: citty parses args with `node:util.parseArgs` under the hood + * (see citty's `parseRawArgs`), which never sets `multiple: true` for any + * arg — citty's ArgDef type has no array/repeatable string kind at all. With + * `strict: false`, `parseArgs` silently keeps only the LAST occurrence of a + * repeated string option instead of erroring or collecting them, so + * `args.param` only ever reflects the final `-p` flag. Any operation needing + * more than one `-p key=value` (the common case for required params) would + * lose all but the last, get reported as "missing", and be re-prompted for + * interactively even though the user supplied it on the command line. + * + * This walks rawArgs itself to recover every occurrence, bypassing citty's + * lossy parsing entirely. + */ +export const collectRepeatedFlag = (rawArgs: string[], names: string[]): string[] => { + const values: string[] = []; + const prefixes = names.map((name) => (name.length === 1 ? `-${name}` : `--${name}`)); + + for (let i = 0; i < rawArgs.length; i++) { + const arg = rawArgs[i]; + if (arg === '--') break; + + for (const prefix of prefixes) { + if (arg === prefix) { + const next = rawArgs[i + 1]; + if (next !== undefined) { + values.push(next); + i++; + } + break; + } + if (arg.startsWith(`${prefix}=`)) { + values.push(arg.slice(prefix.length + 1)); + break; + } + } + } + + return values; +}; diff --git a/packages/cli/test/entity-command.test.ts b/packages/cli/test/entity-command.test.ts new file mode 100644 index 000000000..1613a7fce --- /dev/null +++ b/packages/cli/test/entity-command.test.ts @@ -0,0 +1,54 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; + +const callApiMock = vi.fn(); +vi.mock('../src/lib/call.js', () => ({ callApi: (...callArgs: unknown[]) => callApiMock(...callArgs) })); + +describe('entity command — repeated -p flags', () => { + beforeEach(() => { + callApiMock.mockReset(); + }); + + it('forwards every -p flag to callApi, not just the last one (regression)', async () => { + const entityCommand = (await import('../src/commands/apis/entity.js')).default; + + // Simulates what citty's parser actually produces: with two `-p` flags, + // node:util.parseArgs keeps only the last value in args.param, but + // rawArgs still contains both occurrences verbatim. + const rawArgs = ['getEntity', '-p', 'slug=contact', '-p', 'id=abc-123']; + const args = { operation: 'getEntity', param: 'id=abc-123' }; + + // @ts-expect-error — test-only partial CommandContext + await entityCommand.run({ args, rawArgs }); + + expect(callApiMock).toHaveBeenCalledTimes(1); + const [apiName, callArgs] = callApiMock.mock.calls[0]; + expect(apiName).toBe('entity'); + expect(callArgs.param).toEqual(['slug=contact', 'id=abc-123']); + }); + + it('still forwards a single -p flag correctly', async () => { + const entityCommand = (await import('../src/commands/apis/entity.js')).default; + + const rawArgs = ['getEntity', '-p', 'slug=contact']; + const args = { operation: 'getEntity', param: 'slug=contact' }; + + // @ts-expect-error — test-only partial CommandContext + await entityCommand.run({ args, rawArgs }); + + const [, callArgs] = callApiMock.mock.calls[0]; + expect(callArgs.param).toEqual(['slug=contact']); + }); + + it('falls back to args.param when no -p flags are present in rawArgs', async () => { + const entityCommand = (await import('../src/commands/apis/entity.js')).default; + + const rawArgs = ['listSchemas']; + const args = { operation: 'listSchemas', param: undefined }; + + // @ts-expect-error — test-only partial CommandContext + await entityCommand.run({ args, rawArgs }); + + const [, callArgs] = callApiMock.mock.calls[0]; + expect(callArgs.param).toBeUndefined(); + }); +}); diff --git a/packages/cli/test/flag-collector.test.ts b/packages/cli/test/flag-collector.test.ts new file mode 100644 index 000000000..1bfb75a30 --- /dev/null +++ b/packages/cli/test/flag-collector.test.ts @@ -0,0 +1,59 @@ +import { describe, it, expect } from 'vitest'; +import { collectRepeatedFlag } from '../src/lib/flag-collector.js'; + +describe('collectRepeatedFlag', () => { + it('returns empty array when the flag is absent', () => { + expect(collectRepeatedFlag(['entity', 'getEntity'], ['p', 'param'])).toEqual([]); + }); + + it('collects a single short-flag occurrence', () => { + expect(collectRepeatedFlag(['-p', 'slug=contact'], ['p', 'param'])).toEqual(['slug=contact']); + }); + + it('collects multiple short-flag occurrences, in order', () => { + expect(collectRepeatedFlag(['-p', 'id=1', '-p', 'hydrate=true'], ['p', 'param'])).toEqual([ + 'id=1', + 'hydrate=true', + ]); + }); + + it('collects multiple long-flag occurrences', () => { + expect(collectRepeatedFlag(['--param', 'id=1', '--param', 'hydrate=true'], ['p', 'param'])).toEqual([ + 'id=1', + 'hydrate=true', + ]); + }); + + it('collects a mix of short and long flag forms', () => { + expect(collectRepeatedFlag(['-p', 'id=1', '--param', 'hydrate=true'], ['p', 'param'])).toEqual([ + 'id=1', + 'hydrate=true', + ]); + }); + + it('supports --flag=value form without consuming the next token', () => { + expect(collectRepeatedFlag(['--param=id=1', 'positional'], ['p', 'param'])).toEqual(['id=1']); + }); + + it('supports -p=value form', () => { + expect(collectRepeatedFlag(['-p=id=1'], ['p', 'param'])).toEqual(['id=1']); + }); + + it('ignores unrelated flags and positionals interleaved between occurrences', () => { + expect( + collectRepeatedFlag(['getEntity', '-p', 'slug=contact', '--json', '-p', 'id=42', 'trailing'], ['p', 'param']), + ).toEqual(['slug=contact', 'id=42']); + }); + + it('stops scanning at a bare "--" separator', () => { + expect(collectRepeatedFlag(['-p', 'id=1', '--', '-p', 'id=2'], ['p', 'param'])).toEqual(['id=1']); + }); + + it('does not treat a trailing flag with no value as consuming anything', () => { + expect(collectRepeatedFlag(['-p'], ['p', 'param'])).toEqual([]); + }); + + it('does not match flags that merely share a prefix (e.g. --param-extra)', () => { + expect(collectRepeatedFlag(['--param-extra', 'x=1'], ['p', 'param'])).toEqual([]); + }); +});