feat(codegen): variadic positional for array body options (email read/unread/rm UX)#9
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
@
Summary
Teaches
cli-codegento emit a variadic positional argument when an x-cli option is markedarray: trueAND the field also appears inpositional. Concretely, this fixes the awkwardwspc email read --id eml_A --id eml_BUX uncovered during E2E smoke and replaces it withwspc email read eml_A eml_B, matchingwspc event rm <id>style and thewspc CLIx-codeSamples already in the server-side OpenAPI spec.Depends on companion PR sadcoderlabs/wspc#366 — that PR ships the
positional: ["id"]annotation onemail_mark_read/email_mark_unread/email_delete. Merge order: server PR → prod deploy → sync-spec here → release.Before / after
Help text simplified accordingly — the
--idflag is gone; the positional<id...>carries the same meaning.Codegen change
Five surgical edits in
tools/cli-codegen/emit.ts:variadicPositionalSet— names that appear inpositional[]AND havexCliOptions[name].array === trueargsemission — for those names, emit.argument("<name...>", "name")(commander variadic syntax) instead of single<name>bodyOptionsfilter — skip body fields whose x-cli option key was promoted to a variadic positional (otherwise codegen would emit BOTH a positional and a--flag)bodyPositionalsfilter — exclude variadic positionals from the plain-shorthand emit (they needmapsTorenaming, handled via the body field path)array && !parserbranch) — source the rawstring[]from the positional argument variable (id) instead ofopts.<key>when the option is a variadic positionalThe flag path (
options.<name>.array: truewithoutpositional) keeps working unchanged. This is purely additive — opt in by listing the name inpositional.Tests
tools/cli-codegen/emit.test.ts > "variadic positional binds to mapsTo body field, suppresses --flag"— asserts.argument("<id...>"appears,--id <value>does NOT, the conversion sources fromidnotopts.id, and body emitsids: ids as string[]test/generated/email.test.ts—read/unread/rmintegration tests switched from--idflag invocation to positional. New test names:"... takes variadic positional ids → body.ids[]"npm run typecheck→ passnpm test→ 131 tests pass (1 new codegen unit + 3 updated integration)npm run build→ ESM + DTS passnode dist/cli.js email rm --helpshowsUsage: wspc email rm [options] <id...>(no--id <value>option) ✓E2E (against prod, despite server PR not yet merged)
The CLI binds via
body: { ids: [...] }regardless of how the user inputs them — server contract unchanged. Tested against current prod:The new CLI is forward-compatible: works against current prod (still emits
body.ids); after the companion server PR merges + redeploys,npm run sync-spechere will pick up the matching annotation and a subsequent regen will be a no-op for these three files (already correct).Release blocker reminder
@