Skip to content

Commit b2f1dc9

Browse files
udamirclaude
andcommitted
Merge lo/asyncapi-v3: Complete AsyncAPI v3 support
- Phase 3: Circular reference tests (direct, indirect, deep) - Phase 4: Edge case tests (sibling content, name collision, error handling) - Phase 5: Full traits and bindings support - Comprehensive test coverage (41 tests total) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2 parents b15768e + 24d17ca commit b2f1dc9

30 files changed

+2529
-12
lines changed

CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
## [0.5.0]
6+
7+
### Added
8+
9+
- **AsyncAPI v3 Support**: Full support for bundling and dereferencing AsyncAPI 3.x documents
10+
- New `asyncapi3.ts` rules module with comprehensive reference mapping
11+
- Support for AsyncAPI v3's restructured architecture (top-level operations, channel-scoped messages)
12+
- Automatic detection of AsyncAPI v3 documents via `asyncapi: 3.0.0` version field
13+
14+
## [0.4.3]
15+
16+
### Features
17+
- OpenAPI 3.x basic support
18+
- Swagger 2.x support
19+
- AsyncAPI 2.x support
20+
- JSON Schema support
21+
- Bundle and dereference functionality
22+
- Circular reference handling with `enableCircular` option
23+
- Error hooks for unresolved references
24+
- Sibling content preservation with `ignoreSibling` option

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "api-ref-bundler",
3-
"version": "0.4.3",
3+
"version": "0.5.0",
44
"description": "Bundle all external $ref in Json based API document into single document",
55
"module": "dist/index.mjs",
66
"main": "dist/index.cjs",

src/rules/asyncapi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DefinitionPointer, RefMapRules } from "../types"
1+
import type { DefinitionPointer, RefMapRules } from "../types"
22
import { schemaRefMap } from "./jsonSchema"
33

44
type AsyncApiComponents = "schemas" | "servers" | "serverVariables" | "channels" | "messages" | "securitySchemes" | "parameters" | "correlationIds" | "operationTraits" | "messageTraits" | "serverBindings" | "channelBindings" | "operationBindings" | "messageBindings"

src/rules/asyncapi3.ts

Lines changed: 109 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DefinitionPointer, RefMapRules } from "../types"
1+
import type { DefinitionPointer, RefMapRules } from "../types"
22
import { schemaRefMap } from "./jsonSchema"
33

44
/**
@@ -10,7 +10,12 @@ import { schemaRefMap } from "./jsonSchema"
1010
* - Root-level channels and operations are not hoisted to components
1111
*/
1212

13-
type AsyncApi3Components = "schemas" | "servers" | "channels" | "operations" | "messages" | "securitySchemes" | "serverVariables" | "parameters" | "correlationIds" | "replies" | "replyAddresses" | "externalDocs" | "tags"
13+
type AsyncApi3Components =
14+
| "schemas" | "servers" | "channels" | "operations" | "messages"
15+
| "securitySchemes" | "serverVariables" | "parameters" | "correlationIds"
16+
| "replies" | "replyAddresses" | "externalDocs" | "tags"
17+
| "operationTraits" | "messageTraits"
18+
| "serverBindings" | "channelBindings" | "operationBindings" | "messageBindings"
1419

1520
const asyncApi3DefPaths: Record<AsyncApi3Components, DefinitionPointer> = {
1621
schemas: "/components/schemas",
@@ -26,6 +31,12 @@ const asyncApi3DefPaths: Record<AsyncApi3Components, DefinitionPointer> = {
2631
replyAddresses: "/components/replyAddresses",
2732
externalDocs: "/components/externalDocs",
2833
tags: "/components/tags",
34+
operationTraits: "/components/operationTraits",
35+
messageTraits: "/components/messageTraits",
36+
serverBindings: "/components/serverBindings",
37+
channelBindings: "/components/channelBindings",
38+
operationBindings: "/components/operationBindings",
39+
messageBindings: "/components/messageBindings",
2940
} as const
3041

3142
const parametersRefMap: RefMapRules = {
@@ -40,14 +51,26 @@ const serversRefMap: RefMapRules = {
4051
"#": asyncApi3DefPaths.servers,
4152
"/variables": {
4253
"/*": { "#": asyncApi3DefPaths.serverVariables }
43-
}
54+
},
55+
"/security": {
56+
"/*": { "#": asyncApi3DefPaths.securitySchemes }
57+
},
58+
"/tags": {
59+
"/*": { "#": asyncApi3DefPaths.tags }
60+
},
61+
"/externalDocs": { "#": asyncApi3DefPaths.externalDocs },
62+
"/bindings": { "#": asyncApi3DefPaths.serverBindings }
4463
}
4564
}
4665

4766
const channelMessageRefMap: RefMapRules = {
4867
"/headers": schemaRefMap(asyncApi3DefPaths.schemas),
4968
"/correlationId": { "#": asyncApi3DefPaths.correlationIds },
5069
"/payload": schemaRefMap(asyncApi3DefPaths.schemas),
70+
"/traits": {
71+
"/*": { "#": asyncApi3DefPaths.messageTraits }
72+
},
73+
"/bindings": { "#": asyncApi3DefPaths.messageBindings }
5174
}
5275

5376
const rootChannelsRefMap: RefMapRules = {
@@ -58,7 +81,12 @@ const rootChannelsRefMap: RefMapRules = {
5881
"/parameters": parametersRefMap,
5982
"/messages": {
6083
"/*": channelMessageRefMap
61-
}
84+
},
85+
"/tags": {
86+
"/*": { "#": asyncApi3DefPaths.tags }
87+
},
88+
"/externalDocs": { "#": asyncApi3DefPaths.externalDocs },
89+
"/bindings": { "#": asyncApi3DefPaths.channelBindings }
6290
}
6391
}
6492

@@ -71,7 +99,12 @@ const componentChannelsRefMap: RefMapRules = {
7199
"/parameters": parametersRefMap,
72100
"/messages": {
73101
"/*": channelMessageRefMap
74-
}
102+
},
103+
"/tags": {
104+
"/*": { "#": asyncApi3DefPaths.tags }
105+
},
106+
"/externalDocs": { "#": asyncApi3DefPaths.externalDocs },
107+
"/bindings": { "#": asyncApi3DefPaths.channelBindings }
75108
}
76109
}
77110

@@ -85,8 +118,20 @@ const rootOperationsRefMap: RefMapRules = {
85118
"/channel": {},
86119
"/messages": {
87120
"/*": {}
88-
}
89-
}
121+
},
122+
"/address": { "#": asyncApi3DefPaths.replyAddresses }
123+
},
124+
"/security": {
125+
"/*": { "#": asyncApi3DefPaths.securitySchemes }
126+
},
127+
"/traits": {
128+
"/*": { "#": asyncApi3DefPaths.operationTraits }
129+
},
130+
"/tags": {
131+
"/*": { "#": asyncApi3DefPaths.tags }
132+
},
133+
"/externalDocs": { "#": asyncApi3DefPaths.externalDocs },
134+
"/bindings": { "#": asyncApi3DefPaths.operationBindings }
90135
}
91136
}
92137

@@ -105,8 +150,20 @@ const componentOperationsRefMap: RefMapRules = {
105150
},
106151
"/messages": {
107152
"/*": {}
108-
}
109-
}
153+
},
154+
"/address": { "#": asyncApi3DefPaths.replyAddresses }
155+
},
156+
"/security": {
157+
"/*": { "#": asyncApi3DefPaths.securitySchemes }
158+
},
159+
"/traits": {
160+
"/*": { "#": asyncApi3DefPaths.operationTraits }
161+
},
162+
"/tags": {
163+
"/*": { "#": asyncApi3DefPaths.tags }
164+
},
165+
"/externalDocs": { "#": asyncApi3DefPaths.externalDocs },
166+
"/bindings": { "#": asyncApi3DefPaths.operationBindings }
110167
}
111168
}
112169

@@ -115,6 +172,10 @@ const componentMessageRefMap: RefMapRules = {
115172
"/headers": schemaRefMap(asyncApi3DefPaths.schemas),
116173
"/correlationId": { "#": asyncApi3DefPaths.correlationIds },
117174
"/payload": schemaRefMap(asyncApi3DefPaths.schemas),
175+
"/traits": {
176+
"/*": { "#": asyncApi3DefPaths.messageTraits }
177+
},
178+
"/bindings": { "#": asyncApi3DefPaths.messageBindings }
118179
}
119180

120181
export const asyncApi3RefMap: RefMapRules = {
@@ -146,7 +207,8 @@ export const asyncApi3RefMap: RefMapRules = {
146207
},
147208
"/messages": {
148209
"/*": {}
149-
}
210+
},
211+
"/address": { "#": asyncApi3DefPaths.replyAddresses }
150212
}
151213
},
152214
"/replyAddresses": {
@@ -160,6 +222,43 @@ export const asyncApi3RefMap: RefMapRules = {
160222
},
161223
"/serverVariables": {
162224
"/*": { "#": asyncApi3DefPaths.serverVariables }
225+
},
226+
"/operationTraits": {
227+
"/*": {
228+
"#": asyncApi3DefPaths.operationTraits,
229+
"/tags": {
230+
"/*": { "#": asyncApi3DefPaths.tags }
231+
},
232+
"/externalDocs": { "#": asyncApi3DefPaths.externalDocs },
233+
"/bindings": { "#": asyncApi3DefPaths.operationBindings },
234+
"/security": {
235+
"/*": { "#": asyncApi3DefPaths.securitySchemes }
236+
}
237+
}
238+
},
239+
"/messageTraits": {
240+
"/*": {
241+
"#": asyncApi3DefPaths.messageTraits,
242+
"/headers": schemaRefMap(asyncApi3DefPaths.schemas),
243+
"/correlationId": { "#": asyncApi3DefPaths.correlationIds },
244+
"/tags": {
245+
"/*": { "#": asyncApi3DefPaths.tags }
246+
},
247+
"/externalDocs": { "#": asyncApi3DefPaths.externalDocs },
248+
"/bindings": { "#": asyncApi3DefPaths.messageBindings }
249+
}
250+
},
251+
"/serverBindings": {
252+
"/*": { "#": asyncApi3DefPaths.serverBindings }
253+
},
254+
"/channelBindings": {
255+
"/*": { "#": asyncApi3DefPaths.channelBindings }
256+
},
257+
"/operationBindings": {
258+
"/*": { "#": asyncApi3DefPaths.operationBindings }
259+
},
260+
"/messageBindings": {
261+
"/*": { "#": asyncApi3DefPaths.messageBindings }
163262
}
164263
}
165264
}

0 commit comments

Comments
 (0)