@kubb/ast 5.0.0-beta.75 → 5.0.0-beta.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +17 -10
- package/README.md +53 -27
- package/dist/defineMacro-CqX4m8Dq.js +98 -0
- package/dist/defineMacro-CqX4m8Dq.js.map +1 -0
- package/dist/defineMacro-DmGR7vfu.cjs +114 -0
- package/dist/defineMacro-DmGR7vfu.cjs.map +1 -0
- package/dist/defineMacro-DzsACbFo.d.ts +466 -0
- package/dist/index-Cu2zmNxv.d.ts +2188 -0
- package/dist/index.cjs +183 -2179
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +88 -3364
- package/dist/index.js +139 -2101
- package/dist/index.js.map +1 -1
- package/dist/macros.cjs +130 -0
- package/dist/macros.cjs.map +1 -0
- package/dist/macros.d.ts +61 -0
- package/dist/macros.js +128 -0
- package/dist/macros.js.map +1 -0
- package/dist/refs-DNNvJ7jg.cjs +135 -0
- package/dist/refs-DNNvJ7jg.cjs.map +1 -0
- package/dist/refs-xm4Vltrw.js +101 -0
- package/dist/refs-xm4Vltrw.js.map +1 -0
- package/dist/rolldown-runtime-CNktS9qV.js +17 -0
- package/dist/types-Ctz5NB1o.d.ts +244 -0
- package/dist/types.cjs +0 -0
- package/dist/types.d.ts +4 -0
- package/dist/types.js +1 -0
- package/dist/utils.cjs +613 -0
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.ts +353 -0
- package/dist/utils.js +589 -0
- package/dist/utils.js.map +1 -0
- package/dist/visitor-Dk0DNLfC.js +1203 -0
- package/dist/visitor-Dk0DNLfC.js.map +1 -0
- package/dist/visitor-h6dEM3vR.cjs +1567 -0
- package/dist/visitor-h6dEM3vR.cjs.map +1 -0
- package/package.json +18 -7
- package/dist/chunk--u3MIqq1.js +0 -8
- package/src/constants.ts +0 -228
- package/src/factory.ts +0 -742
- package/src/guards.ts +0 -110
- package/src/index.ts +0 -45
- package/src/infer.ts +0 -130
- package/src/mocks.ts +0 -176
- package/src/nodes/base.ts +0 -56
- package/src/nodes/code.ts +0 -304
- package/src/nodes/file.ts +0 -230
- package/src/nodes/function.ts +0 -223
- package/src/nodes/http.ts +0 -119
- package/src/nodes/index.ts +0 -86
- package/src/nodes/operation.ts +0 -111
- package/src/nodes/output.ts +0 -26
- package/src/nodes/parameter.ts +0 -41
- package/src/nodes/property.ts +0 -34
- package/src/nodes/response.ts +0 -43
- package/src/nodes/root.ts +0 -64
- package/src/nodes/schema.ts +0 -656
- package/src/printer.ts +0 -250
- package/src/refs.ts +0 -67
- package/src/resolvers.ts +0 -45
- package/src/transformers.ts +0 -159
- package/src/types.ts +0 -70
- package/src/utils.ts +0 -833
- package/src/visitor.ts +0 -592
package/src/visitor.ts
DELETED
|
@@ -1,592 +0,0 @@
|
|
|
1
|
-
import type { VisitorDepth } from './constants.ts'
|
|
2
|
-
import { visitorDepths, WALK_CONCURRENCY } from './constants.ts'
|
|
3
|
-
import { createParameter, createProperty } from './factory.ts'
|
|
4
|
-
import type { InputNode, Node, OperationNode, OutputNode, ParameterNode, PropertyNode, ResponseNode, SchemaNode } from './nodes/index.ts'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Creates a small async concurrency limiter.
|
|
8
|
-
*
|
|
9
|
-
* At most `concurrency` tasks are in flight at once. Extra tasks are queued.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```ts
|
|
13
|
-
* const limit = createLimit(2)
|
|
14
|
-
* for (const task of [taskA, taskB, taskC]) {
|
|
15
|
-
* await limit(() => task())
|
|
16
|
-
* }
|
|
17
|
-
* // only 2 tasks run at the same time
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
function createLimit(concurrency: number) {
|
|
21
|
-
let active = 0
|
|
22
|
-
const queue: Array<() => void> = []
|
|
23
|
-
|
|
24
|
-
function next() {
|
|
25
|
-
if (active < concurrency && queue.length > 0) {
|
|
26
|
-
active++
|
|
27
|
-
queue.shift()!()
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return function limit<T>(fn: () => Promise<T> | T): Promise<T> {
|
|
32
|
-
return new Promise<T>((resolve, reject) => {
|
|
33
|
-
queue.push(() => {
|
|
34
|
-
Promise.resolve(fn())
|
|
35
|
-
.then(resolve, reject)
|
|
36
|
-
.finally(() => {
|
|
37
|
-
active--
|
|
38
|
-
next()
|
|
39
|
-
})
|
|
40
|
-
})
|
|
41
|
-
next()
|
|
42
|
-
})
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
type LimitFn = ReturnType<typeof createLimit>
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Ordered mapping of `[NodeType, ParentType]` pairs.
|
|
50
|
-
*
|
|
51
|
-
* `ParentOf` uses this map to find parent types.
|
|
52
|
-
*/
|
|
53
|
-
type ParentNodeMap = [
|
|
54
|
-
[InputNode, undefined],
|
|
55
|
-
[OutputNode, undefined],
|
|
56
|
-
[OperationNode, InputNode],
|
|
57
|
-
[SchemaNode, InputNode | OperationNode | SchemaNode | PropertyNode | ParameterNode | ResponseNode],
|
|
58
|
-
[PropertyNode, SchemaNode],
|
|
59
|
-
[ParameterNode, OperationNode],
|
|
60
|
-
[ResponseNode, OperationNode],
|
|
61
|
-
]
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Resolves the parent node type for a given AST node type.
|
|
65
|
-
*
|
|
66
|
-
* This is used by visitor context so `ctx.parent` is correctly typed
|
|
67
|
-
* for each callback.
|
|
68
|
-
*
|
|
69
|
-
* @example
|
|
70
|
-
* ```ts
|
|
71
|
-
* type InputParent = ParentOf<InputNode>
|
|
72
|
-
* // undefined
|
|
73
|
-
* ```
|
|
74
|
-
*
|
|
75
|
-
* @example
|
|
76
|
-
* ```ts
|
|
77
|
-
* type PropertyParent = ParentOf<PropertyNode>
|
|
78
|
-
* // SchemaNode
|
|
79
|
-
* ```
|
|
80
|
-
*
|
|
81
|
-
* @example
|
|
82
|
-
* ```ts
|
|
83
|
-
* type SchemaParent = ParentOf<SchemaNode>
|
|
84
|
-
* // InputNode | OperationNode | SchemaNode | PropertyNode | ParameterNode | ResponseNode
|
|
85
|
-
* ```
|
|
86
|
-
*/
|
|
87
|
-
export type ParentOf<T extends Node, TEntries extends ReadonlyArray<[Node, unknown]> = ParentNodeMap> = TEntries extends [
|
|
88
|
-
infer TEntry extends [Node, unknown],
|
|
89
|
-
...infer TRest extends ReadonlyArray<[Node, unknown]>,
|
|
90
|
-
]
|
|
91
|
-
? T extends TEntry[0]
|
|
92
|
-
? TEntry[1]
|
|
93
|
-
: ParentOf<T, TRest>
|
|
94
|
-
: Node
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Traversal context passed as the second argument to every visitor callback.
|
|
98
|
-
* `parent` is typed from the current node type.
|
|
99
|
-
*
|
|
100
|
-
* @example
|
|
101
|
-
* ```ts
|
|
102
|
-
* const visitor: Visitor = {
|
|
103
|
-
* schema(node, { parent }) {
|
|
104
|
-
* // parent type is narrowed by node kind
|
|
105
|
-
* },
|
|
106
|
-
* }
|
|
107
|
-
* ```
|
|
108
|
-
*/
|
|
109
|
-
export type VisitorContext<T extends Node = Node> = {
|
|
110
|
-
/**
|
|
111
|
-
* Parent node of the currently visited node.
|
|
112
|
-
* For `InputNode`, this is `undefined`.
|
|
113
|
-
*/
|
|
114
|
-
parent?: ParentOf<T>
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Synchronous visitor used by `transform`.
|
|
119
|
-
*
|
|
120
|
-
* @example
|
|
121
|
-
* ```ts
|
|
122
|
-
* const visitor: Visitor = {
|
|
123
|
-
* operation(node) {
|
|
124
|
-
* return { ...node, operationId: `x_${node.operationId}` }
|
|
125
|
-
* },
|
|
126
|
-
* }
|
|
127
|
-
* ```
|
|
128
|
-
*/
|
|
129
|
-
export type Visitor = {
|
|
130
|
-
input?(node: InputNode, context: VisitorContext<InputNode>): void | InputNode
|
|
131
|
-
output?(node: OutputNode, context: VisitorContext<OutputNode>): void | OutputNode
|
|
132
|
-
operation?(node: OperationNode, context: VisitorContext<OperationNode>): void | OperationNode
|
|
133
|
-
schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): void | SchemaNode
|
|
134
|
-
property?(node: PropertyNode, context: VisitorContext<PropertyNode>): void | PropertyNode
|
|
135
|
-
parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): void | ParameterNode
|
|
136
|
-
response?(node: ResponseNode, context: VisitorContext<ResponseNode>): void | ResponseNode
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Utility type for values that can be returned directly or asynchronously.
|
|
141
|
-
*/
|
|
142
|
-
type MaybePromise<T> = T | Promise<T>
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Async visitor for `walk`. Synchronous `Visitor` objects are compatible.
|
|
146
|
-
*
|
|
147
|
-
* @example
|
|
148
|
-
* ```ts
|
|
149
|
-
* const visitor: AsyncVisitor = {
|
|
150
|
-
* async operation(node) {
|
|
151
|
-
* await Promise.resolve(node.operationId)
|
|
152
|
-
* },
|
|
153
|
-
* }
|
|
154
|
-
* ```
|
|
155
|
-
*/
|
|
156
|
-
export type AsyncVisitor = {
|
|
157
|
-
input?(node: InputNode, context: VisitorContext<InputNode>): MaybePromise<void | InputNode>
|
|
158
|
-
output?(node: OutputNode, context: VisitorContext<OutputNode>): MaybePromise<void | OutputNode>
|
|
159
|
-
operation?(node: OperationNode, context: VisitorContext<OperationNode>): MaybePromise<void | OperationNode>
|
|
160
|
-
schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): MaybePromise<void | SchemaNode>
|
|
161
|
-
property?(node: PropertyNode, context: VisitorContext<PropertyNode>): MaybePromise<void | PropertyNode>
|
|
162
|
-
parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): MaybePromise<void | ParameterNode>
|
|
163
|
-
response?(node: ResponseNode, context: VisitorContext<ResponseNode>): MaybePromise<void | ResponseNode>
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Visitor used by `collect`.
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* ```ts
|
|
171
|
-
* const visitor: CollectVisitor<string> = {
|
|
172
|
-
* operation(node) {
|
|
173
|
-
* return node.operationId
|
|
174
|
-
* },
|
|
175
|
-
* }
|
|
176
|
-
* ```
|
|
177
|
-
*/
|
|
178
|
-
export type CollectVisitor<T> = {
|
|
179
|
-
input?(node: InputNode, context: VisitorContext<InputNode>): T | undefined
|
|
180
|
-
output?(node: OutputNode, context: VisitorContext<OutputNode>): T | undefined
|
|
181
|
-
operation?(node: OperationNode, context: VisitorContext<OperationNode>): T | undefined
|
|
182
|
-
schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): T | undefined
|
|
183
|
-
property?(node: PropertyNode, context: VisitorContext<PropertyNode>): T | undefined
|
|
184
|
-
parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): T | undefined
|
|
185
|
-
response?(node: ResponseNode, context: VisitorContext<ResponseNode>): T | undefined
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Options for `transform`.
|
|
190
|
-
*
|
|
191
|
-
* @example
|
|
192
|
-
* ```ts
|
|
193
|
-
* const options: TransformOptions = { depth: 'deep', schema: (node) => node }
|
|
194
|
-
* ```
|
|
195
|
-
*
|
|
196
|
-
* @example
|
|
197
|
-
* ```ts
|
|
198
|
-
* // Only transform the current node, not nested children
|
|
199
|
-
* const options: TransformOptions = { depth: 'shallow', schema: (node) => node }
|
|
200
|
-
* ```
|
|
201
|
-
*/
|
|
202
|
-
export type TransformOptions = Visitor & {
|
|
203
|
-
/**
|
|
204
|
-
* Traversal depth (`'deep'` by default).
|
|
205
|
-
* @default 'deep'
|
|
206
|
-
*/
|
|
207
|
-
depth?: VisitorDepth
|
|
208
|
-
/**
|
|
209
|
-
* Internal parent override used during recursion.
|
|
210
|
-
*/
|
|
211
|
-
parent?: Node
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Options for `walk`.
|
|
216
|
-
*
|
|
217
|
-
* @example
|
|
218
|
-
* ```ts
|
|
219
|
-
* const options: WalkOptions = { depth: 'deep', concurrency: 10, root: () => {} }
|
|
220
|
-
* ```
|
|
221
|
-
*/
|
|
222
|
-
export type WalkOptions = AsyncVisitor & {
|
|
223
|
-
/**
|
|
224
|
-
* Traversal depth (`'deep'` by default).
|
|
225
|
-
* @default 'deep'
|
|
226
|
-
*/
|
|
227
|
-
depth?: VisitorDepth
|
|
228
|
-
/**
|
|
229
|
-
* Maximum number of sibling nodes visited concurrently.
|
|
230
|
-
* @default 30
|
|
231
|
-
*/
|
|
232
|
-
concurrency?: number
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Options for `collect`.
|
|
237
|
-
*
|
|
238
|
-
* @example
|
|
239
|
-
* ```ts
|
|
240
|
-
* const options: CollectOptions<string> = { depth: 'shallow', schema: () => undefined }
|
|
241
|
-
* ```
|
|
242
|
-
*/
|
|
243
|
-
export type CollectOptions<T> = CollectVisitor<T> & {
|
|
244
|
-
/**
|
|
245
|
-
* Traversal depth (`'deep'` by default).
|
|
246
|
-
* @default 'deep'
|
|
247
|
-
*/
|
|
248
|
-
depth?: VisitorDepth
|
|
249
|
-
/**
|
|
250
|
-
* Internal parent override used during recursion.
|
|
251
|
-
*/
|
|
252
|
-
parent?: Node
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Returns the immediate traversable children of `node`.
|
|
257
|
-
*
|
|
258
|
-
* For `Schema` nodes, children (`properties`, `items`, `members`, and non-boolean
|
|
259
|
-
* `additionalProperties`) are only included
|
|
260
|
-
* when `recurse` is `true`; shallow mode skips them.
|
|
261
|
-
*
|
|
262
|
-
* @example
|
|
263
|
-
* ```ts
|
|
264
|
-
* const children = getChildren(operationNode, true)
|
|
265
|
-
* // returns parameters, requestBody schema (if present), and responses
|
|
266
|
-
* ```
|
|
267
|
-
*/
|
|
268
|
-
function getChildren(node: Node, recurse: boolean): Array<Node> {
|
|
269
|
-
switch (node.kind) {
|
|
270
|
-
case 'Input':
|
|
271
|
-
return [...node.schemas, ...node.operations]
|
|
272
|
-
case 'Output':
|
|
273
|
-
return []
|
|
274
|
-
case 'Operation':
|
|
275
|
-
return [...node.parameters, ...(node.requestBody?.content?.flatMap((c) => (c.schema ? [c.schema] : [])) ?? []), ...node.responses]
|
|
276
|
-
case 'Schema': {
|
|
277
|
-
const children: Array<Node> = []
|
|
278
|
-
|
|
279
|
-
if (!recurse) return []
|
|
280
|
-
|
|
281
|
-
if ('properties' in node && node.properties.length > 0) children.push(...node.properties)
|
|
282
|
-
if ('items' in node && node.items) children.push(...node.items)
|
|
283
|
-
if ('members' in node && node.members) children.push(...node.members)
|
|
284
|
-
if ('additionalProperties' in node && node.additionalProperties && node.additionalProperties !== true) children.push(node.additionalProperties)
|
|
285
|
-
|
|
286
|
-
return children
|
|
287
|
-
}
|
|
288
|
-
case 'Property':
|
|
289
|
-
return [node.schema]
|
|
290
|
-
case 'Parameter':
|
|
291
|
-
return [node.schema]
|
|
292
|
-
case 'Response':
|
|
293
|
-
return node.schema ? [node.schema] : []
|
|
294
|
-
case 'FunctionParameter':
|
|
295
|
-
case 'ParameterGroup':
|
|
296
|
-
case 'FunctionParameters':
|
|
297
|
-
case 'Type':
|
|
298
|
-
return []
|
|
299
|
-
default:
|
|
300
|
-
return []
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* Depth-first traversal for side effects. Visitor return values are ignored.
|
|
306
|
-
* Sibling nodes at each level are visited concurrently up to `options.concurrency`
|
|
307
|
-
* (default: `WALK_CONCURRENCY`).
|
|
308
|
-
*
|
|
309
|
-
* @example
|
|
310
|
-
* ```ts
|
|
311
|
-
* await walk(root, {
|
|
312
|
-
* operation(node) {
|
|
313
|
-
* console.log(node.operationId)
|
|
314
|
-
* },
|
|
315
|
-
* })
|
|
316
|
-
* ```
|
|
317
|
-
*
|
|
318
|
-
* @example
|
|
319
|
-
* ```ts
|
|
320
|
-
* // Visit only the current node
|
|
321
|
-
* await walk(root, { depth: 'shallow', root: () => {} })
|
|
322
|
-
* ```
|
|
323
|
-
*/
|
|
324
|
-
export async function walk(node: Node, options: WalkOptions): Promise<void> {
|
|
325
|
-
const recurse = (options.depth ?? visitorDepths.deep) === visitorDepths.deep
|
|
326
|
-
const limit = createLimit(options.concurrency ?? WALK_CONCURRENCY)
|
|
327
|
-
|
|
328
|
-
return _walk(node, options, recurse, limit, undefined)
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
async function _walk(node: Node, visitor: AsyncVisitor, recurse: boolean, limit: LimitFn, parent: Node | undefined): Promise<void> {
|
|
332
|
-
switch (node.kind) {
|
|
333
|
-
case 'Input':
|
|
334
|
-
await limit(() => visitor.input?.(node, { parent: parent as ParentOf<InputNode> }))
|
|
335
|
-
break
|
|
336
|
-
case 'Output':
|
|
337
|
-
await limit(() => visitor.output?.(node, { parent: parent as ParentOf<OutputNode> }))
|
|
338
|
-
break
|
|
339
|
-
case 'Operation':
|
|
340
|
-
await limit(() =>
|
|
341
|
-
visitor.operation?.(node, {
|
|
342
|
-
parent: parent as ParentOf<OperationNode>,
|
|
343
|
-
}),
|
|
344
|
-
)
|
|
345
|
-
break
|
|
346
|
-
case 'Schema':
|
|
347
|
-
await limit(() => visitor.schema?.(node, { parent: parent as ParentOf<SchemaNode> }))
|
|
348
|
-
break
|
|
349
|
-
case 'Property':
|
|
350
|
-
await limit(() => visitor.property?.(node, { parent: parent as ParentOf<PropertyNode> }))
|
|
351
|
-
break
|
|
352
|
-
case 'Parameter':
|
|
353
|
-
await limit(() =>
|
|
354
|
-
visitor.parameter?.(node, {
|
|
355
|
-
parent: parent as ParentOf<ParameterNode>,
|
|
356
|
-
}),
|
|
357
|
-
)
|
|
358
|
-
break
|
|
359
|
-
case 'Response':
|
|
360
|
-
await limit(() => visitor.response?.(node, { parent: parent as ParentOf<ResponseNode> }))
|
|
361
|
-
break
|
|
362
|
-
case 'FunctionParameter':
|
|
363
|
-
case 'ParameterGroup':
|
|
364
|
-
case 'FunctionParameters':
|
|
365
|
-
break
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
const children = getChildren(node, recurse)
|
|
369
|
-
for (const child of children) {
|
|
370
|
-
await _walk(child, visitor, recurse, limit, node)
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
/**
|
|
375
|
-
* Runs a depth-first immutable transform.
|
|
376
|
-
*
|
|
377
|
-
* If a visitor returns a node, it replaces the current node.
|
|
378
|
-
* If it returns `undefined`, the current node stays the same.
|
|
379
|
-
*
|
|
380
|
-
* @example
|
|
381
|
-
* ```ts
|
|
382
|
-
* const next = transform(root, {
|
|
383
|
-
* operation(node) {
|
|
384
|
-
* return { ...node, operationId: `prefixed_${node.operationId}` }
|
|
385
|
-
* },
|
|
386
|
-
* })
|
|
387
|
-
* ```
|
|
388
|
-
*
|
|
389
|
-
* @example
|
|
390
|
-
* ```ts
|
|
391
|
-
* // Shallow mode: only transform the input node
|
|
392
|
-
* const next = transform(root, { depth: 'shallow', root: (node) => node })
|
|
393
|
-
* ```
|
|
394
|
-
*/
|
|
395
|
-
export function transform(node: InputNode, options: TransformOptions): InputNode
|
|
396
|
-
export function transform(node: OutputNode, options: TransformOptions): OutputNode
|
|
397
|
-
export function transform(node: OperationNode, options: TransformOptions): OperationNode
|
|
398
|
-
export function transform(node: SchemaNode, options: TransformOptions): SchemaNode
|
|
399
|
-
export function transform(node: PropertyNode, options: TransformOptions): PropertyNode
|
|
400
|
-
export function transform(node: ParameterNode, options: TransformOptions): ParameterNode
|
|
401
|
-
export function transform(node: ResponseNode, options: TransformOptions): ResponseNode
|
|
402
|
-
export function transform(node: Node, options: TransformOptions): Node
|
|
403
|
-
export function transform(node: Node, options: TransformOptions): Node {
|
|
404
|
-
const { depth, parent, ...visitor } = options
|
|
405
|
-
const recurse = (depth ?? visitorDepths.deep) === visitorDepths.deep
|
|
406
|
-
|
|
407
|
-
switch (node.kind) {
|
|
408
|
-
case 'Input': {
|
|
409
|
-
let input = node
|
|
410
|
-
const replaced = visitor.input?.(input, {
|
|
411
|
-
parent: parent as ParentOf<InputNode>,
|
|
412
|
-
})
|
|
413
|
-
if (replaced) input = replaced
|
|
414
|
-
|
|
415
|
-
return {
|
|
416
|
-
...input,
|
|
417
|
-
schemas: input.schemas.map((s) => transform(s, { ...options, parent: input })),
|
|
418
|
-
operations: input.operations.map((op) => transform(op, { ...options, parent: input })),
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
case 'Output': {
|
|
422
|
-
let output = node
|
|
423
|
-
const replaced = visitor.output?.(output, {
|
|
424
|
-
parent: parent as ParentOf<OutputNode>,
|
|
425
|
-
})
|
|
426
|
-
if (replaced) output = replaced
|
|
427
|
-
|
|
428
|
-
return output
|
|
429
|
-
}
|
|
430
|
-
case 'Operation': {
|
|
431
|
-
let op = node
|
|
432
|
-
const replaced = visitor.operation?.(op, {
|
|
433
|
-
parent: parent as ParentOf<OperationNode>,
|
|
434
|
-
})
|
|
435
|
-
if (replaced) op = replaced
|
|
436
|
-
|
|
437
|
-
return {
|
|
438
|
-
...op,
|
|
439
|
-
parameters: op.parameters.map((p) => transform(p, { ...options, parent: op })),
|
|
440
|
-
requestBody: op.requestBody
|
|
441
|
-
? {
|
|
442
|
-
...op.requestBody,
|
|
443
|
-
content: op.requestBody.content?.map((c) => ({
|
|
444
|
-
...c,
|
|
445
|
-
schema: c.schema ? transform(c.schema, { ...options, parent: op }) : undefined,
|
|
446
|
-
})),
|
|
447
|
-
}
|
|
448
|
-
: undefined,
|
|
449
|
-
responses: op.responses.map((r) => transform(r, { ...options, parent: op })),
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
case 'Schema': {
|
|
453
|
-
let schema = node
|
|
454
|
-
const replaced = visitor.schema?.(schema, {
|
|
455
|
-
parent: parent as ParentOf<SchemaNode>,
|
|
456
|
-
})
|
|
457
|
-
if (replaced) schema = replaced
|
|
458
|
-
|
|
459
|
-
const childOptions = { ...options, parent: schema }
|
|
460
|
-
|
|
461
|
-
return {
|
|
462
|
-
...schema,
|
|
463
|
-
...('properties' in schema && recurse
|
|
464
|
-
? {
|
|
465
|
-
properties: schema.properties.map((p) => transform(p, childOptions)),
|
|
466
|
-
}
|
|
467
|
-
: {}),
|
|
468
|
-
...('items' in schema && recurse ? { items: schema.items?.map((i) => transform(i, childOptions)) } : {}),
|
|
469
|
-
...('members' in schema && recurse ? { members: schema.members?.map((m) => transform(m, childOptions)) } : {}),
|
|
470
|
-
...('additionalProperties' in schema && recurse && schema.additionalProperties && schema.additionalProperties !== true
|
|
471
|
-
? {
|
|
472
|
-
additionalProperties: transform(schema.additionalProperties, childOptions),
|
|
473
|
-
}
|
|
474
|
-
: {}),
|
|
475
|
-
} as SchemaNode
|
|
476
|
-
}
|
|
477
|
-
case 'Property': {
|
|
478
|
-
let prop = node
|
|
479
|
-
const replaced = visitor.property?.(prop, {
|
|
480
|
-
parent: parent as ParentOf<PropertyNode>,
|
|
481
|
-
})
|
|
482
|
-
if (replaced) prop = replaced
|
|
483
|
-
|
|
484
|
-
return createProperty({
|
|
485
|
-
...prop,
|
|
486
|
-
schema: transform(prop.schema, { ...options, parent: prop }),
|
|
487
|
-
})
|
|
488
|
-
}
|
|
489
|
-
case 'Parameter': {
|
|
490
|
-
let param = node
|
|
491
|
-
const replaced = visitor.parameter?.(param, {
|
|
492
|
-
parent: parent as ParentOf<ParameterNode>,
|
|
493
|
-
})
|
|
494
|
-
if (replaced) param = replaced
|
|
495
|
-
|
|
496
|
-
return createParameter({
|
|
497
|
-
...param,
|
|
498
|
-
schema: transform(param.schema, { ...options, parent: param }),
|
|
499
|
-
})
|
|
500
|
-
}
|
|
501
|
-
case 'Response': {
|
|
502
|
-
let response = node
|
|
503
|
-
const replaced = visitor.response?.(response, {
|
|
504
|
-
parent: parent as ParentOf<ResponseNode>,
|
|
505
|
-
})
|
|
506
|
-
if (replaced) response = replaced
|
|
507
|
-
|
|
508
|
-
return {
|
|
509
|
-
...response,
|
|
510
|
-
schema: transform(response.schema, { ...options, parent: response }),
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
case 'FunctionParameter':
|
|
514
|
-
case 'ParameterGroup':
|
|
515
|
-
case 'FunctionParameters':
|
|
516
|
-
case 'Type':
|
|
517
|
-
return node
|
|
518
|
-
default:
|
|
519
|
-
return node
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
/**
|
|
523
|
-
* Runs a depth-first synchronous collection pass.
|
|
524
|
-
*
|
|
525
|
-
* Non-`undefined` values returned by visitor callbacks are appended to the result.
|
|
526
|
-
*
|
|
527
|
-
* @example
|
|
528
|
-
* ```ts
|
|
529
|
-
* const ids = collect(root, {
|
|
530
|
-
* operation(node) {
|
|
531
|
-
* return node.operationId
|
|
532
|
-
* },
|
|
533
|
-
* })
|
|
534
|
-
* ```
|
|
535
|
-
*
|
|
536
|
-
* @example
|
|
537
|
-
* ```ts
|
|
538
|
-
* // Collect from only the current node
|
|
539
|
-
* const values = collect(root, { depth: 'shallow', root: () => 'root' })
|
|
540
|
-
* ```
|
|
541
|
-
*/
|
|
542
|
-
export function collect<T>(node: Node, options: CollectOptions<T>): Array<T> {
|
|
543
|
-
const { depth, parent, ...visitor } = options
|
|
544
|
-
const recurse = (depth ?? visitorDepths.deep) === visitorDepths.deep
|
|
545
|
-
const results: Array<T> = []
|
|
546
|
-
|
|
547
|
-
let v: T | undefined
|
|
548
|
-
switch (node.kind) {
|
|
549
|
-
case 'Input':
|
|
550
|
-
v = visitor.input?.(node, { parent: parent as ParentOf<InputNode> })
|
|
551
|
-
break
|
|
552
|
-
case 'Output':
|
|
553
|
-
v = visitor.output?.(node, { parent: parent as ParentOf<OutputNode> })
|
|
554
|
-
break
|
|
555
|
-
case 'Operation':
|
|
556
|
-
v = visitor.operation?.(node, {
|
|
557
|
-
parent: parent as ParentOf<OperationNode>,
|
|
558
|
-
})
|
|
559
|
-
break
|
|
560
|
-
case 'Schema':
|
|
561
|
-
v = visitor.schema?.(node, { parent: parent as ParentOf<SchemaNode> })
|
|
562
|
-
break
|
|
563
|
-
case 'Property':
|
|
564
|
-
v = visitor.property?.(node, {
|
|
565
|
-
parent: parent as ParentOf<PropertyNode>,
|
|
566
|
-
})
|
|
567
|
-
break
|
|
568
|
-
case 'Parameter':
|
|
569
|
-
v = visitor.parameter?.(node, {
|
|
570
|
-
parent: parent as ParentOf<ParameterNode>,
|
|
571
|
-
})
|
|
572
|
-
break
|
|
573
|
-
case 'Response':
|
|
574
|
-
v = visitor.response?.(node, {
|
|
575
|
-
parent: parent as ParentOf<ResponseNode>,
|
|
576
|
-
})
|
|
577
|
-
break
|
|
578
|
-
case 'FunctionParameter':
|
|
579
|
-
case 'ParameterGroup':
|
|
580
|
-
case 'FunctionParameters':
|
|
581
|
-
break
|
|
582
|
-
}
|
|
583
|
-
if (v !== undefined) results.push(v)
|
|
584
|
-
|
|
585
|
-
for (const child of getChildren(node, recurse)) {
|
|
586
|
-
for (const item of collect(child, { ...options, parent: node })) {
|
|
587
|
-
results.push(item)
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
return results
|
|
592
|
-
}
|