fix(analyzer): inline bodies of the same shape took a type name from another operation - #126
Merged
Merged
Conversation
…another operation Synthesized types were keyed only on shape, so two operations that each wrote the same body inline landed on one type, named for whichever was converted first. Uploading a workflow icon meant constructing an UploadStandaloneAiChatAttachmentBody. The same collapse hit inline response bodies, where one operation returned a type named for another endpoint. A body an operation writes inline now scopes what it synthesizes, so each operation gets a type named for itself, nested inline objects included. Bodies the spec names stay shared: a $ref to components/requestBodies or components/responses, a titled schema, an external-file $ref. An event stream resolves one schema twice, as the response body and as the event payload, so the scope is the body rather than each name hint and the two stay on one declared type. Regenerating testdata is byte identical, since those specs name their bodies as components. Closes #125
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.
Closes #125.
What was wrong
Synthesized types are keyed on shape, so two operations that each write the same body inline collapse onto one type, named for whichever the analyzer converted first. Seven single-file upload endpoints all took
UploadStandaloneAiChatAttachmentBody.The same dedup hits inline response bodies, so an operation could return a type named for a different endpoint. #125 assumed output types were already distinct; that holds only because huma emits those response schemas as named components. Untitled inline ones collapse the same way.
The fix
A body an operation writes inline now scopes what it synthesizes. Inside that scope the shape key is prefixed with the body, so each operation gets its own type named for itself. The scope covers the whole subtree, so a nested inline object does not leak one operation's name into another's signature either. Applied to request bodies, response bodies, SSE event payloads, and webhook and callback payloads.
Bodies the spec names stay shared:
$reftocomponents/requestBodiesorcomponents/responses(checked withGoLow().IsReference())title:on the inline schema, or an external-file$ref, both of which already self-nameAn event stream resolves one schema twice, as the response body and as the event payload. Keying on each name hint split that into two identical types, so the key is the body rather than the hint and
StreamEventsResponsestays one type.Tests
internal/analyzer/schemas_operation_body_test.go: per-operation naming for request and response, component$refbodies stay shared, titled bodies stay shared, an event payload declares one type.internal/generator/e2e_operation_body_naming_test.go: generates a two-upload client, compiles it, and runs it against a test server, constructingUploadUserAvatarBodyandUploadWorkflowIconBodyand taking*UploadUserAvatarResponseand*UploadWorkflowIconResponseback.Both fail on canary with
undefined: UploadWorkflowIconBody.Blast radius
Regenerating every spec in
testdata/is byte identical, since those name their bodies as components. Only specs that repeat an inline shape see names move, which is the point.