Skip to content

feat(params): typed enums across parameters; native $ref resolution#41

Open
MrRefactoring wants to merge 5 commits into
masterfrom
chore/enum-field-parameters
Open

feat(params): typed enums across parameters; native $ref resolution#41
MrRefactoring wants to merge 5 commits into
masterfrom
chore/enum-field-parameters

Conversation

@MrRefactoring
Copy link
Copy Markdown
Owner

Summary

  • Closes systemic gaps in apis-code-gen that caused $ref in parameter / body positions to fall through to z.unknown(). createProperty now top-level-checks $ref and emits Type.reference; createSchema handles top-level oneOf and emits z.union([...]) schemas; createParameterModel filters extends to only in: 'extends' parameters so primitive-aliased $refs don't crash with .extend(TrelloIDSchema.shape). mergePathParameters added to the Trello pipeline so path-level params flow into operation-level generation.
  • Removes the Trello-specific workaround that flattened posStringOrNumber to z.number() — the model now correctly emits z.union([z.enum(['top','bottom']), z.number()]).
  • Layered widening for backward compatibility on top of the codegen:
    • CSV fields params for entities with a documented field enum (Action, Attachment, Board, Card, Notification, Organization, Token): accept either CSV string, array, or the typed enum (single or array).
    • Single-value $ref enums (Color, ViewFilter, path *Field params): z.union([z.string(), z.enum([...])]) — keeps loose-string callers compiling while adding autocomplete.
    • Inline JSDoc enums (One of: a, b, c / Valid values: a, b, c) on plain string params get the same 2-branch shape.
    • Positioning params (pos) typed as z.union([z.string(), z.number(), z.enum(['top','bottom'])]) — loose string preserved for backward compat.
  • POST /checklists.name JSDoc now documents the server-side default **Defaults**: \Checklist`` — verified empirically against the live API.

Test plan

  • pnpm run build — clean.
  • pnpm run lint — clean.
  • pnpm vitest run — 71/71 unit tests pass.
  • id: z.unknown() count in src/parameters/: was 195, now 0. Remaining 5 z.unknown() are nested body fields with no schema in swagger (updateCardCustomFields.idCustomField/idValue, getCardAttachment.fields, getEnterpriseBulkOrganizations.idOrganizations, updateEnterpriseJoinRequests) — out of scope for this PR.
  • Empirical check: POST /checklists without name returns a checklist with name: "Checklist"; with name: '' Trello applies the same default.
  • Smoke-check on consumer apps — import { createTrelloClient } from 'trello.js' and await trello.cards.getCard({ id }) should now type id as string (was unknown).

…lution

Regenerated from a sweep of fixes in the upstream apis-code-gen plus
trello-specific transforms that widen schemas for backward compatibility.

Codegen fixes (apis-code-gen):
- createProperty now resolves $ref at the top → emits Type.reference (so
  parameter $refs and body-property $refs become typed schema references
  instead of falling through to z.unknown).
- createSchema handles top-level oneOf → emits z.union([...]) instead of an
  empty object. The Trello-specific workaround that flattened
  posStringOrNumber to z.number() is gone.
- createParameterModel filters extends to only in:'extends' params, so a
  ref-typed property like id doesn't accidentally become an extends base
  (which would crash with .extend(TrelloIDSchema.shape) on a primitive).
- mergePathParameters added to the Trello transform pipeline so path-level
  shared params participate in normal generation.

Resulting parameter changes:
- Path-level {id} params: 200+ files now use TrelloIDSchema (z.string()).
- Field-style CSV query params (Action/Attachment/Board/Card/Notification/
  Organization/Token): 4-branch union (string | string[] | enum | enum[]).
- Single-value $ref enums (Color, ViewFilter, *Field path params): 2-branch
  union (string | enum) for backward compat + autocomplete.
- Inline JSDoc enums ("One of: a, b, c" / "Valid values: a, b, c"): same
  2-branch shape applied to plain string params.
- Positioning params (pos): z.union([string, number, enum(['top','bottom'])])
  — loose string preserved for backward compatibility.
- POST /checklists.name JSDoc now documents the server-side default
  (**Defaults**: Checklist), verified empirically against the live API.

Build clean, lint clean, 71/71 tests pass.
The swagger declared Card.labels as array<TrelloID>, but the live API
returns full Label objects. The codegen's previous z.array(z.unknown())
was loose enough to accept this; with the $ref now resolved natively,
the strict schema rejected real responses.

Patched in fixMismatchedSchemas (apis-code-gen/packages/trello) to
override Card.labels.items to $ref Label.

Live tests now: 223 passed, 78 skipped, 0 failed.
…omFields/tokens; expand members live

Adds wire-shape unit tests for API modules with little or no live coverage —
each test mocks the client and asserts URL/method/searchParams/body of the
sent request. Coverage jumps:

  statements: 65.38% → 78.39%
  branches:   88.33% → 95.00%
  functions:  64.72% → 74.29%
  lines:      65.29% → 78.23%

Per-file gains: src/core 67% → 100%, src/api 64% → 82%. The remaining
uncovered surfaces in members.ts (44%) and organizations.ts (50%) are
endpoints that need premium/enterprise accounts or session-auth.

New unit test files:
- tests/unit/core/batchRun.test.ts        (7 tests for createBatchRun)
- tests/unit/api/batch.test.ts            (3 tests for batch.run)
- tests/unit/api/customFields.test.ts     (8 tests)
- tests/unit/api/enterprises.test.ts      (21 tests)
- tests/unit/api/notifications.test.ts    (11 tests)
- tests/unit/api/plugins.test.ts          (5 tests)
- tests/unit/api/tokens.test.ts           (8 tests)

Members live tests: added individual fetches after listings (board
backgrounds, custom emoji, custom stickers). dismissMemberOneTimeMessage
documented as session-auth-only and skipped.
…xport

TrelloIDSchema was a one-line `z.string()` alias used everywhere via $ref —
no runtime value beyond ergonomics. Added an apis-code-gen transform
(\`inlineTrelloIDRefs\`) that walks the swagger doc and replaces every
\`{\$ref: '#/components/schemas/TrelloID'}\` with an inline
\`{type: 'string'}\` before the generator runs. As a result every parameter
and model field that was \`TrelloIDSchema\` (or \`TrelloIDSchema.nullish()\`)
is now plain \`z.string()\` — 265 files lose a redundant import.

The TrelloID component is kept in components.schemas so the codegen still
produces \`src/models/trelloID.ts\` for callers that imported \`TrelloIDSchema\`
/ \`TrelloID\` from the public API. The schema description is overwritten
with an \`@deprecated\` notice so IDEs surface the warning at the import
site.

71/71 unit tests pass, 223/223 live tests pass.
Adds a post-process step in apis-code-gen/packages/trello/src/index.ts
that, after generation, attaches an `@deprecated` JSDoc block to the
`export type TrelloID = z.infer<typeof TrelloIDSchema>;` line in
`models/trelloID.ts`. Same message style as the deprecation already
attached to `TrelloIDSchema` via the swagger description — IDE now
flags `import { TrelloID }` use sites too, not just `TrelloIDSchema`.

Local trello-only workaround; the codegen itself still attaches the
schema description to the const only. Lifting that to share descriptions
across const + type alias would be a separate apis-code-gen change.
@MrRefactoring MrRefactoring force-pushed the chore/enum-field-parameters branch from df1aeed to c8ed0c0 Compare May 22, 2026 21:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant