fix: parse components/headers to resolve crash on header component $ref in schemas#3676
fix: parse components/headers to resolve crash on header component $ref in schemas#3676
components/headers to resolve crash on header component $ref in schemas#3676Conversation
|
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
components/headers to resolve crash on header component $ref in schemas
5f0169d to
a3b88dc
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3676 +/- ##
==========================================
- Coverage 39.39% 39.29% -0.11%
==========================================
Files 520 520
Lines 19279 19323 +44
Branches 5708 5726 +18
==========================================
- Hits 7595 7593 -2
- Misses 9445 9479 +34
- Partials 2239 2251 +12
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
@hey-api/codegen-core
@hey-api/json-schema-ref-parser
@hey-api/nuxt
@hey-api/openapi-ts
@hey-api/shared
@hey-api/spec-types
@hey-api/types
@hey-api/vite-plugin
commit: |
mrlubos
left a comment
There was a problem hiding this comment.
@copilot few notes:
- Make sure to add a handler and test for
responsestoo. You can roll bothresponsesandheadersinto one OpenAPI spec, that's fine. - We need a separate test and test spec for OpenAPI 3.0 and OpenAPI 3.1, you added only tests for 3.0.
- The specs should follow the patterns from other specs (info object, field names and values) and be in YAML format (you're already doing this).
- Prefer
functionsyntax overconstwhere possible. We're migrating from const to function, so clean up the files as you go instead of creating more mess. - This one is just a question for now, but why did you decide to expand the regular expression for
schemapattern instead of adding a new entry for headers?
|
Reviewed PR #3676. The approach of treating Task list (6/6 completed)
|
There was a problem hiding this comment.
The approach is sound — treating header schemas as schema-kind IR nodes avoids pervasive plugin changes and correctly leverages the existing graph walker infrastructure. Two issues worth addressing before merge.
packages/shared/src/ir/graph.ts
Outdated
| parameter: /^#\/components\/parameters\/[^/]+$/, | ||
| requestBody: /^#\/components\/requestBodies\/[^/]+$/, | ||
| schema: /^#\/components\/schemas\/[^/]+$/, | ||
| schema: /^#\/components\/(headers|schemas)\/[^/]+$/, |
There was a problem hiding this comment.
Because pathToName's ROOT_CONTEXT for components skips 2 segments and collects 1, both #/components/headers/Foo and #/components/schemas/Foo derive the base name "Foo". The planner's assignSymbolName will silently rename one (e.g., Foo2), which is non-obvious for users.
This is an edge case — most real-world specs won't have colliding header and schema names — but it's worth calling out. Consider whether the ROOT_CONTEXT should be adjusted to include the component category in the name for headers (e.g., prefix with the header name), or at minimum add a test case to graph.test.ts that asserts #/components/headers/Foo matches 'schema' so the behaviour is documented.
| type: object | ||
| properties: | ||
| rateLimit: | ||
| $ref: '#/components/headers/X-Rate-Limit' |
There was a problem hiding this comment.
The test spec only covers the happy path (header with a schema that is $ref'd from a schema property). Consider adding a case where a header and a schema share the same name to verify the collision-resolution behaviour, and a header whose schema is itself a $ref to another schema (to confirm schemaToIrSchema handles the transitive reference).
|
@pullfrog few notes:
|
|
Addressed all 5 review notes: added Task list (12/12 completed)
|
…s`, add 3.1.x test - Add `header` and `response` as separate top-level IR kinds instead of expanding the `schema` regex pattern - Parse `components/responses` in both 3.0.x and 3.1.x parsers - Add `responses` to `IRComponentsObject` type - Update `WalkEvents` union and `forEach` switch for new event types - Subscribe `@hey-api/typescript` plugin to `header` and `response` events - Create `components-headers.yaml` spec for 3.1.x (with both headers and responses) - Update 3.0.x spec to follow naming conventions and include responses - Convert `parseSchema`/`parseHeader` to `function` syntax - Update graph unit tests for new patterns

Specs that reference
#/components/headers/{name}or#/components/responses/{name}from within a schema (e.g. a schema property) caused an unhandled crash:Symbol finalName has not been resolved yet for [Symbol {"category":"type","resource":"definition","resourceId":"#/components/headers/headers"}#130].The parsers never processed
components.headersorcomponents.responses, soreferenceSymbol()created an unresolvable stub withname: ''. During planning,assignLocalNamescalledsetFinalName(''), then thefinalNamegetter threw because""is falsy.Changes
New IR kinds:
headerandresponseInstead of expanding the
schemaregex to match headers/responses, we introduce dedicated top-level IR kinds:ir/graph.ts— add'header'and'response'toirTopLevelKinds, each with their own regex pattern inmatchIrPointerToGroup, and positioned inpreferGroupsbeforeschemaplugins/shared/types/instance.ts— addheaderandresponsevariants to theWalkEventsunionplugins/shared/utils/instance.ts— addcase 'header':andcase 'response':to theforEachswitchParsers
ir/types.ts— addheaders?: Record<string, IRSchemaObject>andresponses?: Record<string, IRResponseObject>toIRComponentsObject3.0.x/parser/schema.ts,3.1.x/parser/schema.ts— addparseHeader()(extracts a header'sschema) andparseResponse()(extracts a response'scontentschema). Converted tofunctionsyntax.3.0.x/parser/index.ts,3.1.x/parser/index.ts— iteratecomponents.headersandcomponents.responses, calling the respective parse functionsPlugin updates
@hey-api/typescriptv1 — subscribe to'header'and'response'events, processing their schemas through the same type processor as'schema'eventsTests
components-headers.yaml) covering bothcomponents/headersandcomponents/responses"OpenAPI 3.x.x components headers and responses example")headerandresponsepointer patternsResult
Given:
The generator now emits:
instead of crashing. Header components without a
schemaproperty are silently skipped.