@kubb/ast 5.0.0-beta.13 → 5.0.0-beta.15
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/dist/index.cjs +71 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -21
- package/dist/index.js +70 -51
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +2 -2
- package/src/transformers.ts +19 -14
- package/src/utils.ts +22 -11
- package/src/visitor.ts +31 -31
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/ast",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.15",
|
|
4
4
|
"description": "Spec-agnostic AST layer for Kubb. Defines the node tree, visitor pattern, factory functions, and type guards used across all code generation plugins.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ast",
|
package/src/index.ts
CHANGED
|
@@ -28,7 +28,7 @@ export { isInputNode, isOperationNode, isOutputNode, isSchemaNode, narrowSchema
|
|
|
28
28
|
export { createPrinterFactory, definePrinter } from './printer.ts'
|
|
29
29
|
export { extractRefName } from './refs.ts'
|
|
30
30
|
export { childName, collectImports, enumPropName, findDiscriminator } from './resolvers.ts'
|
|
31
|
-
export { mergeAdjacentObjects, setDiscriminatorEnum, setEnumName, simplifyUnion } from './transformers.ts'
|
|
31
|
+
export { mergeAdjacentObjects, mergeAdjacentObjectsLazy, setDiscriminatorEnum, setEnumName, simplifyUnion } from './transformers.ts'
|
|
32
32
|
export type * from './types.ts'
|
|
33
33
|
export {
|
|
34
34
|
caseParams,
|
|
@@ -43,4 +43,4 @@ export {
|
|
|
43
43
|
resolveRefName,
|
|
44
44
|
syncSchemaRef,
|
|
45
45
|
} from './utils.ts'
|
|
46
|
-
export { collect, transform, walk } from './visitor.ts'
|
|
46
|
+
export { collect, collectLazy, transform, walk } from './visitor.ts'
|
package/src/transformers.ts
CHANGED
|
@@ -73,25 +73,30 @@ export function setDiscriminatorEnum({
|
|
|
73
73
|
* ])
|
|
74
74
|
* ```
|
|
75
75
|
*/
|
|
76
|
-
export function
|
|
77
|
-
|
|
76
|
+
export function* mergeAdjacentObjectsLazy(members: Iterable<SchemaNode>): Generator<SchemaNode, void, undefined> {
|
|
77
|
+
let acc: SchemaNode | undefined
|
|
78
|
+
|
|
79
|
+
for (const member of members) {
|
|
78
80
|
const objectMember = narrowSchema(member, 'object')
|
|
79
|
-
if (objectMember && !objectMember.name) {
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
...previousObject,
|
|
86
|
-
properties: [...(previousObject.properties ?? []), ...(objectMember.properties ?? [])],
|
|
81
|
+
if (objectMember && !objectMember.name && acc !== undefined) {
|
|
82
|
+
const accObject = narrowSchema(acc, 'object')
|
|
83
|
+
if (accObject && !accObject.name) {
|
|
84
|
+
acc = createSchema({
|
|
85
|
+
...accObject,
|
|
86
|
+
properties: [...(accObject.properties ?? []), ...(objectMember.properties ?? [])],
|
|
87
87
|
})
|
|
88
|
-
|
|
88
|
+
continue
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
|
+
if (acc !== undefined) yield acc
|
|
92
|
+
acc = member
|
|
93
|
+
}
|
|
91
94
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
+
if (acc !== undefined) yield acc
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function mergeAdjacentObjects(members: Array<SchemaNode>): Array<SchemaNode> {
|
|
99
|
+
return [...mergeAdjacentObjectsLazy(members)]
|
|
95
100
|
}
|
|
96
101
|
|
|
97
102
|
/**
|
package/src/utils.ts
CHANGED
|
@@ -17,7 +17,7 @@ import type {
|
|
|
17
17
|
} from './nodes/index.ts'
|
|
18
18
|
import type { SchemaType } from './nodes/schema.ts'
|
|
19
19
|
import { extractRefName } from './refs.ts'
|
|
20
|
-
import { collect } from './visitor.ts'
|
|
20
|
+
import { collect, collectLazy } from './visitor.ts'
|
|
21
21
|
|
|
22
22
|
const plainStringTypes = new Set<SchemaType>(['string', 'uuid', 'email', 'url', 'datetime'] as const)
|
|
23
23
|
|
|
@@ -775,18 +775,28 @@ export function resolveRefName(node: SchemaNode | undefined): string | undefined
|
|
|
775
775
|
* }
|
|
776
776
|
* ```
|
|
777
777
|
*/
|
|
778
|
-
|
|
779
|
-
|
|
778
|
+
const schemaRefCache = new WeakMap<SchemaNode, ReadonlySet<string>>()
|
|
779
|
+
|
|
780
|
+
function collectSchemaRefs(node: SchemaNode): ReadonlySet<string> {
|
|
781
|
+
const cached = schemaRefCache.get(node)
|
|
782
|
+
if (cached) return cached
|
|
783
|
+
|
|
784
|
+
const refs = new Set<string>()
|
|
780
785
|
collect<void>(node, {
|
|
781
786
|
schema(child) {
|
|
782
787
|
if (child.type === 'ref') {
|
|
783
788
|
const name = resolveRefName(child)
|
|
784
|
-
|
|
785
|
-
if (name) out.add(name)
|
|
789
|
+
if (name) refs.add(name)
|
|
786
790
|
}
|
|
787
|
-
return undefined
|
|
788
791
|
},
|
|
789
792
|
})
|
|
793
|
+
schemaRefCache.set(node, refs)
|
|
794
|
+
return refs
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
export function collectReferencedSchemaNames(node: SchemaNode | undefined, out: Set<string> = new Set()): Set<string> {
|
|
798
|
+
if (!node) return out
|
|
799
|
+
for (const name of collectSchemaRefs(node)) out.add(name)
|
|
790
800
|
return out
|
|
791
801
|
}
|
|
792
802
|
|
|
@@ -842,7 +852,7 @@ export function collectUsedSchemaNames(operations: ReadonlyArray<OperationNode>,
|
|
|
842
852
|
}
|
|
843
853
|
|
|
844
854
|
for (const op of operations) {
|
|
845
|
-
for (const schema of
|
|
855
|
+
for (const schema of collectLazy<SchemaNode>(op, { depth: 'shallow', schema: (node) => node })) {
|
|
846
856
|
visitSchema(schema)
|
|
847
857
|
}
|
|
848
858
|
}
|
|
@@ -902,14 +912,15 @@ export function containsCircularRef(
|
|
|
902
912
|
): boolean {
|
|
903
913
|
if (!node || circularSchemas.size === 0) return false
|
|
904
914
|
|
|
905
|
-
const
|
|
915
|
+
for (const _ of collectLazy<true>(node, {
|
|
906
916
|
schema(child) {
|
|
907
917
|
if (child.type !== 'ref') return undefined
|
|
908
918
|
const name = resolveRefName(child)
|
|
909
|
-
|
|
910
919
|
return name && name !== excludeName && circularSchemas.has(name) ? true : undefined
|
|
911
920
|
},
|
|
912
|
-
})
|
|
921
|
+
})) {
|
|
922
|
+
return true
|
|
923
|
+
}
|
|
913
924
|
|
|
914
|
-
return
|
|
925
|
+
return false
|
|
915
926
|
}
|
package/src/visitor.ts
CHANGED
|
@@ -265,39 +265,40 @@ export type CollectOptions<T> = CollectVisitor<T> & {
|
|
|
265
265
|
* // returns parameters, requestBody schema (if present), and responses
|
|
266
266
|
* ```
|
|
267
267
|
*/
|
|
268
|
-
function getChildren(node: Node, recurse: boolean):
|
|
268
|
+
function* getChildren(node: Node, recurse: boolean): Generator<Node, void, undefined> {
|
|
269
269
|
switch (node.kind) {
|
|
270
270
|
case 'Input':
|
|
271
|
-
|
|
271
|
+
yield* node.schemas
|
|
272
|
+
yield* node.operations
|
|
273
|
+
break
|
|
272
274
|
case 'Output':
|
|
273
|
-
|
|
275
|
+
break
|
|
274
276
|
case 'Operation':
|
|
275
|
-
|
|
277
|
+
yield* node.parameters
|
|
278
|
+
if (node.requestBody?.content) {
|
|
279
|
+
for (const c of node.requestBody.content) {
|
|
280
|
+
if (c.schema) yield c.schema
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
yield* node.responses
|
|
284
|
+
break
|
|
276
285
|
case 'Schema': {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
if (
|
|
280
|
-
|
|
281
|
-
if ('
|
|
282
|
-
|
|
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
|
|
286
|
+
if (!recurse) break
|
|
287
|
+
if ('properties' in node && node.properties.length > 0) yield* node.properties
|
|
288
|
+
if ('items' in node && node.items) yield* node.items
|
|
289
|
+
if ('members' in node && node.members) yield* node.members
|
|
290
|
+
if ('additionalProperties' in node && node.additionalProperties && node.additionalProperties !== true) yield node.additionalProperties
|
|
291
|
+
break
|
|
287
292
|
}
|
|
288
293
|
case 'Property':
|
|
289
|
-
|
|
294
|
+
yield node.schema
|
|
295
|
+
break
|
|
290
296
|
case 'Parameter':
|
|
291
|
-
|
|
297
|
+
yield node.schema
|
|
298
|
+
break
|
|
292
299
|
case 'Response':
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
case 'ParameterGroup':
|
|
296
|
-
case 'FunctionParameters':
|
|
297
|
-
case 'Type':
|
|
298
|
-
return []
|
|
299
|
-
default:
|
|
300
|
-
return []
|
|
300
|
+
if (node.schema) yield node.schema
|
|
301
|
+
break
|
|
301
302
|
}
|
|
302
303
|
}
|
|
303
304
|
|
|
@@ -539,10 +540,9 @@ export function transform(node: Node, options: TransformOptions): Node {
|
|
|
539
540
|
* const values = collect(root, { depth: 'shallow', root: () => 'root' })
|
|
540
541
|
* ```
|
|
541
542
|
*/
|
|
542
|
-
export function
|
|
543
|
+
export function* collectLazy<T>(node: Node, options: CollectOptions<T>): Generator<T, void, undefined> {
|
|
543
544
|
const { depth, parent, ...visitor } = options
|
|
544
545
|
const recurse = (depth ?? visitorDepths.deep) === visitorDepths.deep
|
|
545
|
-
const results: Array<T> = []
|
|
546
546
|
|
|
547
547
|
let v: T | undefined
|
|
548
548
|
switch (node.kind) {
|
|
@@ -580,13 +580,13 @@ export function collect<T>(node: Node, options: CollectOptions<T>): Array<T> {
|
|
|
580
580
|
case 'FunctionParameters':
|
|
581
581
|
break
|
|
582
582
|
}
|
|
583
|
-
if (v !== undefined)
|
|
583
|
+
if (v !== undefined) yield v
|
|
584
584
|
|
|
585
585
|
for (const child of getChildren(node, recurse)) {
|
|
586
|
-
|
|
587
|
-
results.push(item)
|
|
588
|
-
}
|
|
586
|
+
yield* collectLazy(child, { ...options, parent: node })
|
|
589
587
|
}
|
|
588
|
+
}
|
|
590
589
|
|
|
591
|
-
|
|
590
|
+
export function collect<T>(node: Node, options: CollectOptions<T>): Array<T> {
|
|
591
|
+
return Array.from(collectLazy(node, options))
|
|
592
592
|
}
|