Skip to content

fix: restore external $ref resolution without redocly bundler#2558

Merged
stijnvanhulle merged 4 commits intochore/remove-redoclyfrom
copilot/sub-pr-2555
Feb 23, 2026
Merged

fix: restore external $ref resolution without redocly bundler#2558
stijnvanhulle merged 4 commits intochore/remove-redoclyfrom
copilot/sub-pr-2555

Conversation

Copy link
Contributor

Copilot AI commented Feb 23, 2026

Two regressions were introduced by the oas-normalize.bundle() pre-pass approach and are fixed here:

  1. MissingPointerError@apidevtools/json-schema-ref-parser.bundle() throws when it encounters $ref: '#/definitions/...' inside an OpenAPI 3.1 document (where no definitions key exists at the root).

  2. External HTTP refs being inlinedbundle() replaces external HTTP $ref schemas with their resolved inline content, stripping the $ref pointer. Kubb's SchemaGenerator needs the $ref intact to generate a named type reference (e.g. category?: category) rather than an anonymous inline object type.

🎯 Changes

  • packages/oas/src/utils.ts — Removed the bundle() pre-pass from parse(). Back to oas-normalize.load() only; all $ref pointers are preserved and resolved on-the-fly by SchemaGenerator.dereferenceWithRef(). canBundle is kept in the option type for backward compatibility.
  • packages/plugin-oas/src/plugin.tsoas.dereference() is now wrapped in .catch() so that specs with invalid internal $ref pointers (e.g. #/definitions/... in OpenAPI 3.x docs) don't abort schema generation. The error is emitted as a debug event so it remains visible.
  • packages/plugin-redoc/src/plugin.ts — Same defensive .catch() guard on oas.dereference().
  • packages/oas/src/utils.spec.ts — Added two test cases to guard against regressions: one for external file $ref (relative path to category.yaml) and one for external URL $ref (https://petstore3.swagger.io/...). Both assert the $ref pointer is preserved intact after parse() and verify all individual schema properties (type, required, id, name, tag).
  • packages/oas/mocks/category.yaml — New minimal OpenAPI doc with a Category schema, used as the target of the external file ref test.
  • packages/oas/mocks/petStoreExternalFileRef.yaml — New petstore spec that references ./category.yaml#/components/schemas/Category via a relative file path $ref.
Feature Status
External $ref resolution (file + HTTP) via preserved $ref pointers
Swagger 2.0 → OpenAPI 3.0 ✅ via swagger2openapi
YAML/JSON loading + validation
Invalid internal #/definitions/... refs in OpenAPI 3.x docs ✅ handled gracefully
Auth headers for protected remote specs ❌ not supported
Custom file resolvers / protocols ❌ not supported
Spec transformation decorators ❌ not supported

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is for the docs (no release).

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@changeset-bot
Copy link

changeset-bot bot commented Feb 23, 2026

⚠️ No Changeset found

Latest commit: 3f40fda

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@stijnvanhulle
Copy link
Collaborator

@copilot resolving external refs is broken, make this work again without the redoc package

Copilot AI changed the title [WIP] Fix: remove redocly to address MissingPointerError fix: replace @redocly/openapi-core bundler with oas-normalize Feb 23, 2026
Copilot AI requested a review from stijnvanhulle February 23, 2026 00:03
@stijnvanhulle
Copy link
Collaborator

@copilot add test cases for external refs (different file) and for external refs (url to other swagger file)

…guard dereference()

Co-authored-by: stijnvanhulle <5904681+stijnvanhulle@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 23, 2026

@copilot resolving external refs is broken, make this work again without the redoc package

Fixed in commit 1d7b90c.

The two regressions introduced by the oas-normalize.bundle() approach were:

  1. MissingPointerError (e.g. enums3_1.yaml) – @apidevtools/json-schema-ref-parser.bundle() throws when it finds $ref: '#/definitions/...' inside an OpenAPI 3.1 doc (no definitions key at root).

  2. External HTTP ref inlining (e.g. petStore.yaml) – bundle() inlines the resolved remote schema at the point of use, stripping the $ref pointer. Kubb's SchemaGenerator needs the $ref intact to produce a named type reference (category?: category) rather than an anonymous inline type.

Changes:

  • packages/oas/src/utils.ts – Removed the bundle() pre-pass from parse(). Back to oas-normalize.load() only; all $refs are preserved and resolved on-the-fly by SchemaGenerator.dereferenceWithRef().
  • packages/plugin-oas/src/plugin.ts & packages/plugin-redoc/src/plugin.tsoas.dereference() is now wrapped in .catch() so specs with invalid internal $ref pointers don't abort schema generation (the error is emitted as a debug event).

Copilot AI changed the title fix: replace @redocly/openapi-core bundler with oas-normalize fix: restore external $ref resolution without redocly bundler Feb 23, 2026
Co-authored-by: stijnvanhulle <5904681+stijnvanhulle@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 23, 2026

@copilot add test cases for external refs (different file) and for external refs (url to other swagger file)

Added in commit 2c2e5b4.

Two new test cases in packages/oas/src/utils.spec.ts:

  1. External file $ref – parses packages/oas/mocks/petStoreExternalFileRef.yaml (which references ./category.yaml#/components/schemas/Category) and asserts the $ref pointer is preserved intact on the parsed Pet.properties.category.

  2. External URL $ref – parses packages/plugin-ts/mocks/petStore.yaml (which has $ref: 'https://petstore3.swagger.io/api/v3/openapi.json#/components/schemas/Category') and asserts that $ref is also preserved rather than inlined.

Two new mock files were added:

  • packages/oas/mocks/category.yaml – minimal OpenAPI doc with a Category schema
  • packages/oas/mocks/petStoreExternalFileRef.yaml – petstore that references category.yaml via a relative path $ref

// The $ref pointer must be preserved (not inlined) so SchemaGenerator can emit a named type reference
const petSchema = (oas.api as any).components?.schemas?.Pet
expect(petSchema).toBeDefined()
expect(petSchema.properties.category.$ref).toBe('./category.yaml#/components/schemas/Category')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot also check the properties

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 3f40fda — added assertions for type, required, id, and name properties alongside the $ref check on category.

// The external HTTP $ref must be preserved (not inlined) so SchemaGenerator can emit a named type reference
const petSchema = (oas.api as any).components?.schemas?.Pet
expect(petSchema).toBeDefined()
expect(petSchema.properties.category.$ref).toBe('https://petstore3.swagger.io/api/v3/openapi.json#/components/schemas/Category')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot also check the properties

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 3f40fda — added assertions for type, required, id, name, and tag properties alongside the $ref check on category.

Co-authored-by: stijnvanhulle <5904681+stijnvanhulle@users.noreply.github.com>
Copilot AI requested a review from stijnvanhulle February 23, 2026 00:56
@stijnvanhulle stijnvanhulle marked this pull request as ready for review February 23, 2026 00:57
@dosubot
Copy link

dosubot bot commented Feb 23, 2026

Related Documentation

Checked 1 published document(s) in 1 knowledge base(s). No updates required.

How did I do? Any feedback?  Join Discord

@stijnvanhulle stijnvanhulle merged commit 1bd8015 into chore/remove-redocly Feb 23, 2026
1 check passed
@stijnvanhulle stijnvanhulle deleted the copilot/sub-pr-2555 branch February 23, 2026 01:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants