Skip to content

fix: resolve external $ref files relative to spec file location#2056

Open
chengyixu wants to merge 1 commit intoasyncapi:masterfrom
chengyixu:fix/external-ref-resolution
Open

fix: resolve external $ref files relative to spec file location#2056
chengyixu wants to merge 1 commit intoasyncapi:masterfrom
chengyixu:fix/external-ref-resolution

Conversation

@chengyixu
Copy link

Summary

Fixes #1839 — External $ref files in the same directory are not resolved since the CLI architecture refactoring.

Root Cause

When the CLI was refactored to use GeneratorService, the path option passed to generator.generateFromString() was changed from a string file path to a Specification object:

// Before (working - from commit c1e1b39):
await generator.generateFromString(specification.text(), {...genOption, path: asyncapi});
// `asyncapi` was a string like "./src/contract/asyncapi.yaml"

// After (broken - current code):
await generator.generateFromString(asyncapi.text(), {
  ...genOption,
  path: asyncapi,  // ← Specification object, not a string!
});

The @asyncapi/generator's parser calls convertOldOptionsToNew() which checks typeof oldOptions.path === 'string' to set the source path for resolving relative $ref references. Since a Specification object is not a string, the source path was never set, causing the @asyncapi/parser (and downstream @stoplight/json-ref-readers) to resolve relative paths against the CWD instead of the spec file's directory.

Fix

Use asyncapi.getSource() which returns the file path string (or URL) from the Specification object:

await generator.generateFromString(asyncapi.text(), {
  ...genOption,
  path: asyncapi.getSource(),  // ← Returns string file path or URL
});

Also updated the GeneratorRunOptions interface to correctly type path as string instead of Specification.

Changes

  • src/domains/services/generator.service.ts: Pass asyncapi.getSource() instead of the Specification object as path; fix GeneratorRunOptions.path type from Specification to string
  • test/integration/generate/fromTemplate.test.ts: Add integration test for external $ref resolution from a subdirectory
  • test/unit/services/generator.service.test.ts: Add unit test verifying Specification.getSource() returns a string path

Test plan

  • Existing integration tests pass (no regressions)
  • New test: generate from template with external $ref in subdirectory (./test/fixtures/external-refs/main.yaml)
  • Manual test: create an AsyncAPI spec in a subdirectory referencing other YAML files via $ref and run asyncapi generate fromTemplate

🤖 Generated with Claude Code

…capi#1839)

When the CLI architecture was refactored to use GeneratorService, the
`path` option passed to `generator.generateFromString()` was changed
from a string file path to a Specification object. The generator's
parser checks `typeof oldOptions.path === 'string'` to set the source
path for resolving relative $ref references. Since a Specification
object is not a string, the source path was never set, causing
external file references to fail when the spec is in a subdirectory.

The fix uses `asyncapi.getSource()` which returns the file path string
(or URL) from the Specification object, restoring correct $ref
resolution behavior.

Closes asyncapi#1839

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@changeset-bot
Copy link

changeset-bot bot commented Mar 18, 2026

⚠️ No Changeset found

Latest commit: 4ae000e

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

@sonarqubecloud
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: To Triage

Development

Successfully merging this pull request may close these issues.

[BUG] external files in same directory are not resolved via $ref anymore, since v3.3.0

1 participant