generate:after hook copies AsyncAPI doc verbatim, leaving external $refs unresolvable at client runtime
- Dominant language
- JavaScript
- Stars
- 1.1k
- Forks
- 397
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 25
Description
## Describe the bug
The built-in `generate:after` hook in `@asyncapi/generator-hooks` (`createAsyncapiFile`) copies the **source AsyncAPI document verbatim** into each generated client's output directory as `asyncapi.{json,yaml}`.
When the source document uses **external `$ref`s** (e.g. `$ref: './commons/servers.yml#/...'`), those references are written into the emitted `asyncapi.yaml` unchanged. Because the referenced sibling files are **not** copied alongside the generated client, the emitted document is not self-contained — the external refs are unresolvable at client runtime.
This breaks consumers that load the emitted document and compile schemas from it. In particular, `@asyncapi/keeper` (used by generated clients to validate messages) fails to resolve the external refs, breaking schema compilation on the send path.
## How to Reproduce
1. Author an AsyncAPI document that splits definitions across files using external `$ref`s (e.g. a `servers.yml` / `messages.yml` referenced via `./commons/...`).
2. Generate a client with a template that ships the `generate:after` hook.
3. Inspect the emitted `asyncapi.yaml` in the output directory — it still contains external `$ref`s like `./commons/servers.yml#/...`.
4. Load that emitted document at runtime (e.g. via `@asyncapi/keeper`) — resolution/compilation fails because the referenced files are absent.
## Expected behavior
The hook should write a **single self-contained document** so it is usable standalone next to the generated client — external `$ref`s inlined (bundled). When the source cannot be bundled (string/URL input with no on-disk path, or a bundling failure), it should gracefully fall back to writing the original source unchanged.
## Additional context
- Source: `apps/hooks/src/index.js` — `createAsyncapiFile` (`generate:after`).
- Proposed approach: bundle the document via `@asyncapi/bundler` when a source file path is available on disk (using the document's own directory as `baseDir` so relative external refs resolve correctly), with a fallback to verbatim copy otherwise.
Contributor guide
Assessment
This issue has not been assessed yet.