fix(openapi-generator): propagate comment from union requestBody to body schema#1149
fix(openapi-generator): propagate comment from union requestBody to body schema#1149bitgo-ai-agent-dev[bot] wants to merge 1 commit into
Conversation
543782d to
768e4f6
Compare
Review — solves TW-295 ✅Reviewed against the Slack thread / TW-295. The fix is correct, minimal, and matches the root cause diagnosed there. Verified end-to-end by reproducing the exact endpoint shape from bitgo-microservices#61023 (
That's exactly the node the On correctness:
One thing worth calling out (not blocking): this propagates the description from the union-level JSDoc (on the named const or the Ready to come out of draft from my side. Generated by Claude Code |
|
Added a note in section 6.2.3.1 of the README (new sub-section under Custom Tags) documenting exactly this: the JSDoc must go on the union codec itself, not on the individual |
6e6342c to
3282654
Compare
|
The However, |
…ody schema
Two gaps in route.ts prevented JSDoc descriptions from reaching the body
schema node for union-of-httpRequest request bodies:
1. derefRequestSchema resolved a named-const ref but dropped the third
element of the findSymbolInitializer tuple (Block | undefined), so
any JSDoc on the named const was silently discarded.
2. parseRequestUnion built the merged body as a brand-new
{ type: 'union', schemas: [] } node and never copied schema.comment
to it, so even when the union schema already carried a comment
(e.g. after fix 1), the body node the lint inspects had none.
Together these mean that a route like:
/** Either a userId or an email */
const AddMemberRequest = t.union([httpRequest({body:{userId}}), ...]);
httpRoute({ request: AddMemberRequest, ... })
now emits a description on requestBody.content['application/json'].schema,
satisfying the missing-request-body-description quality check.
Fixes affect patterns such as POST /enterprise/{id}/safes/{id}/members
where the body enforces userId | email.
Ticket: TW-295
Session-Id: fc63a9af-dca6-4ec9-9637-7afb61367955
Task-Id: a1d22b41-99d1-4474-8e8a-82ff2fe84a38
7c3568c to
78c823c
Compare
| }, | ||
| components: { | ||
| schemas: { | ||
| AddMemberRequest: { |
There was a problem hiding this comment.
This looks a little funky -- there's a schema that isn't used? Is that expected?
There was a problem hiding this comment.
Good catch, and you're reading it right — AddMemberRequest in components.schemas is genuinely never $ref'd anywhere in paths here. It's expected though, not a leftover: the test harness (testCase in testHarness.ts) dumps every top-level declaration that isn't itself a valid route into schemas, regardless of whether it's referenced. AddMemberRequest has to be a named top-level const in this test — that's the point, verifying the comment propagates from a named union ref — but parseRequestUnion/derefRequestSchema fully flattens that union into an inline body schema, so no ref node survives pointing back at it. It's an artifact of the test harness's schema-collection convention, unrelated to the description-propagation fix itself — the real CLI's component-collection pass in cli.ts only includes schemas still reachable via ref, so this dangling entry likely wouldn't show up in a real generated spec. Happy to add a one-line comment above that block if it'd help future readers.
What
derefRequestSchema, preserve theBlockcomment returned as the third element offindSymbolInitializer's tuple instead of discarding it. The comment is now attached tothe resolved schema when no comment is already present.
parseRequestUnion, propagateschema.commentonto the newly created body union node(
{ type: 'union', schemas: [] }) so the description survives into the schema that theOpenAPI generator and lint checks inspect.
Why
api-ts's OpenAPI generator silently dropped JSDoc descriptions on request bodies built asa
t.union([httpRequest(...), httpRequest(...)])pattern (common for endpoints that accepteither a
userIdoremail). The generated spec had no description onrequestBody.content['application/json'].schema, causing themissing-request-body-descriptionquality check to fail even when JSDoc was present in the source.
POST /api/v2/enterprise/{enterpriseId}/safes/{safeId}/members(BitGo/bitgo-microservices#61023)and is the root cause identified in TW-295.
Test plan
route.test.tscase: verifiesbody.commentis populated at IR level when therequest is a named-const union with a JSDoc comment.
openapi/union.test.tscase: verifies end-to-end that the description surfacesin
requestBody.content['application/json'].schema.descriptionin the OpenAPI output.Ticket: TW-295