@kubb/ast 5.0.0-beta.17 → 5.0.0-beta.19
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 +33 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -35
- package/dist/index.js +33 -25
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/nodes/schema.ts +4 -0
- package/src/utils.ts +41 -10
- package/src/visitor.ts +7 -36
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.19",
|
|
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/nodes/schema.ts
CHANGED
package/src/utils.ts
CHANGED
|
@@ -74,16 +74,26 @@ export function isStringType(node: SchemaNode): boolean {
|
|
|
74
74
|
* the desired casing while preserving `OperationNode.parameters` for other consumers.
|
|
75
75
|
* The input array is not mutated. When `casing` is not set, the original array is returned unchanged.
|
|
76
76
|
*/
|
|
77
|
+
const caseParamsCache = new WeakMap<Array<ParameterNode>, Map<string, Array<ParameterNode>>>()
|
|
78
|
+
|
|
77
79
|
export function caseParams(params: Array<ParameterNode>, casing: 'camelcase' | undefined): Array<ParameterNode> {
|
|
78
|
-
if (!casing)
|
|
79
|
-
|
|
80
|
+
if (!casing) return params
|
|
81
|
+
|
|
82
|
+
let byParams = caseParamsCache.get(params)
|
|
83
|
+
if (!byParams) {
|
|
84
|
+
byParams = new Map()
|
|
85
|
+
caseParamsCache.set(params, byParams)
|
|
80
86
|
}
|
|
87
|
+
const cached = byParams.get(casing)
|
|
88
|
+
if (cached) return cached
|
|
81
89
|
|
|
82
|
-
|
|
90
|
+
const result = params.map((param) => {
|
|
83
91
|
const transformed = casing === 'camelcase' || !isValidVarName(param.name) ? camelCase(param.name) : param.name
|
|
84
|
-
|
|
85
92
|
return { ...param, name: transformed }
|
|
86
93
|
})
|
|
94
|
+
|
|
95
|
+
byParams.set(casing, result)
|
|
96
|
+
return result
|
|
87
97
|
}
|
|
88
98
|
|
|
89
99
|
/**
|
|
@@ -723,13 +733,18 @@ export function extractStringsFromNodes(nodes: Array<CodeNode> | undefined): str
|
|
|
723
733
|
if (node.kind === 'Text') return node.value
|
|
724
734
|
if (node.kind === 'Break') return ''
|
|
725
735
|
if (node.kind === 'Jsx') return node.value
|
|
736
|
+
|
|
726
737
|
const parts: string[] = []
|
|
738
|
+
|
|
727
739
|
if ('params' in node && node.params) parts.push(node.params)
|
|
728
740
|
if ('generics' in node && node.generics) parts.push(Array.isArray(node.generics) ? node.generics.join(', ') : node.generics)
|
|
729
741
|
if ('returnType' in node && node.returnType) parts.push(node.returnType)
|
|
730
742
|
if ('type' in node && typeof node.type === 'string') parts.push(node.type)
|
|
743
|
+
|
|
731
744
|
const nested = extractStringsFromNodes(node.nodes)
|
|
745
|
+
|
|
732
746
|
if (nested) parts.push(nested)
|
|
747
|
+
|
|
733
748
|
return parts.join('\n')
|
|
734
749
|
})
|
|
735
750
|
.filter(Boolean)
|
|
@@ -828,12 +843,20 @@ export function collectReferencedSchemaNames(node: SchemaNode | undefined, out:
|
|
|
828
843
|
* allowed.has('OrderStatus') // false when no included operation references OrderStatus
|
|
829
844
|
* ```
|
|
830
845
|
*/
|
|
846
|
+
const usedSchemaNamesCache = new WeakMap<ReadonlyArray<OperationNode>, WeakMap<ReadonlyArray<SchemaNode>, Set<string>>>()
|
|
847
|
+
|
|
831
848
|
export function collectUsedSchemaNames(operations: ReadonlyArray<OperationNode>, schemas: ReadonlyArray<SchemaNode>): Set<string> {
|
|
849
|
+
let byOps = usedSchemaNamesCache.get(operations)
|
|
850
|
+
if (!byOps) {
|
|
851
|
+
byOps = new WeakMap()
|
|
852
|
+
usedSchemaNamesCache.set(operations, byOps)
|
|
853
|
+
}
|
|
854
|
+
const cached = byOps.get(schemas)
|
|
855
|
+
if (cached) return cached
|
|
856
|
+
|
|
832
857
|
const schemaMap = new Map<string, SchemaNode>()
|
|
833
858
|
for (const schema of schemas) {
|
|
834
|
-
if (schema.name)
|
|
835
|
-
schemaMap.set(schema.name, schema)
|
|
836
|
-
}
|
|
859
|
+
if (schema.name) schemaMap.set(schema.name, schema)
|
|
837
860
|
}
|
|
838
861
|
|
|
839
862
|
const result = new Set<string>()
|
|
@@ -844,9 +867,7 @@ export function collectUsedSchemaNames(operations: ReadonlyArray<OperationNode>,
|
|
|
844
867
|
if (!result.has(name)) {
|
|
845
868
|
result.add(name)
|
|
846
869
|
const namedSchema = schemaMap.get(name)
|
|
847
|
-
if (namedSchema)
|
|
848
|
-
visitSchema(namedSchema)
|
|
849
|
-
}
|
|
870
|
+
if (namedSchema) visitSchema(namedSchema)
|
|
850
871
|
}
|
|
851
872
|
}
|
|
852
873
|
}
|
|
@@ -857,9 +878,13 @@ export function collectUsedSchemaNames(operations: ReadonlyArray<OperationNode>,
|
|
|
857
878
|
}
|
|
858
879
|
}
|
|
859
880
|
|
|
881
|
+
byOps.set(schemas, result)
|
|
860
882
|
return result
|
|
861
883
|
}
|
|
862
884
|
|
|
885
|
+
const EMPTY_CIRCULAR_SET = new Set<string>()
|
|
886
|
+
const circularSchemaCache = new WeakMap<ReadonlyArray<SchemaNode>, Set<string>>()
|
|
887
|
+
|
|
863
888
|
/**
|
|
864
889
|
* Identifies all schemas that participate in circular dependency chains, including direct self-loops.
|
|
865
890
|
*
|
|
@@ -870,6 +895,11 @@ export function collectUsedSchemaNames(operations: ReadonlyArray<OperationNode>,
|
|
|
870
895
|
* @note Call this once on the full schema graph, then use `containsCircularRef()` to check individual schemas.
|
|
871
896
|
*/
|
|
872
897
|
export function findCircularSchemas(schemas: ReadonlyArray<SchemaNode>): Set<string> {
|
|
898
|
+
if (schemas.length === 0) return EMPTY_CIRCULAR_SET
|
|
899
|
+
|
|
900
|
+
const cached = circularSchemaCache.get(schemas)
|
|
901
|
+
if (cached) return cached
|
|
902
|
+
|
|
873
903
|
const graph = new Map<string, Set<string>>()
|
|
874
904
|
|
|
875
905
|
for (const schema of schemas) {
|
|
@@ -895,6 +925,7 @@ export function findCircularSchemas(schemas: ReadonlyArray<SchemaNode>): Set<str
|
|
|
895
925
|
}
|
|
896
926
|
}
|
|
897
927
|
|
|
928
|
+
circularSchemaCache.set(schemas, circular)
|
|
898
929
|
return circular
|
|
899
930
|
}
|
|
900
931
|
|
package/src/visitor.ts
CHANGED
|
@@ -407,11 +407,7 @@ export function transform(node: Node, options: TransformOptions): Node {
|
|
|
407
407
|
|
|
408
408
|
switch (node.kind) {
|
|
409
409
|
case 'Input': {
|
|
410
|
-
|
|
411
|
-
const replaced = visitor.input?.(input, {
|
|
412
|
-
parent: parent as ParentOf<InputNode>,
|
|
413
|
-
})
|
|
414
|
-
if (replaced) input = replaced
|
|
410
|
+
const input = visitor.input?.(node, { parent: parent as ParentOf<InputNode> }) ?? node
|
|
415
411
|
|
|
416
412
|
return {
|
|
417
413
|
...input,
|
|
@@ -420,20 +416,11 @@ export function transform(node: Node, options: TransformOptions): Node {
|
|
|
420
416
|
}
|
|
421
417
|
}
|
|
422
418
|
case 'Output': {
|
|
423
|
-
|
|
424
|
-
const replaced = visitor.output?.(output, {
|
|
425
|
-
parent: parent as ParentOf<OutputNode>,
|
|
426
|
-
})
|
|
427
|
-
if (replaced) output = replaced
|
|
428
|
-
|
|
419
|
+
const output = visitor.output?.(node, { parent: parent as ParentOf<OutputNode> }) ?? node
|
|
429
420
|
return output
|
|
430
421
|
}
|
|
431
422
|
case 'Operation': {
|
|
432
|
-
|
|
433
|
-
const replaced = visitor.operation?.(op, {
|
|
434
|
-
parent: parent as ParentOf<OperationNode>,
|
|
435
|
-
})
|
|
436
|
-
if (replaced) op = replaced
|
|
423
|
+
const op = visitor.operation?.(node, { parent: parent as ParentOf<OperationNode> }) ?? node
|
|
437
424
|
|
|
438
425
|
return {
|
|
439
426
|
...op,
|
|
@@ -451,11 +438,7 @@ export function transform(node: Node, options: TransformOptions): Node {
|
|
|
451
438
|
}
|
|
452
439
|
}
|
|
453
440
|
case 'Schema': {
|
|
454
|
-
|
|
455
|
-
const replaced = visitor.schema?.(schema, {
|
|
456
|
-
parent: parent as ParentOf<SchemaNode>,
|
|
457
|
-
})
|
|
458
|
-
if (replaced) schema = replaced
|
|
441
|
+
const schema = visitor.schema?.(node, { parent: parent as ParentOf<SchemaNode> }) ?? node
|
|
459
442
|
|
|
460
443
|
const childOptions = { ...options, parent: schema }
|
|
461
444
|
|
|
@@ -476,11 +459,7 @@ export function transform(node: Node, options: TransformOptions): Node {
|
|
|
476
459
|
} as SchemaNode
|
|
477
460
|
}
|
|
478
461
|
case 'Property': {
|
|
479
|
-
|
|
480
|
-
const replaced = visitor.property?.(prop, {
|
|
481
|
-
parent: parent as ParentOf<PropertyNode>,
|
|
482
|
-
})
|
|
483
|
-
if (replaced) prop = replaced
|
|
462
|
+
const prop = visitor.property?.(node, { parent: parent as ParentOf<PropertyNode> }) ?? node
|
|
484
463
|
|
|
485
464
|
return createProperty({
|
|
486
465
|
...prop,
|
|
@@ -488,11 +467,7 @@ export function transform(node: Node, options: TransformOptions): Node {
|
|
|
488
467
|
})
|
|
489
468
|
}
|
|
490
469
|
case 'Parameter': {
|
|
491
|
-
|
|
492
|
-
const replaced = visitor.parameter?.(param, {
|
|
493
|
-
parent: parent as ParentOf<ParameterNode>,
|
|
494
|
-
})
|
|
495
|
-
if (replaced) param = replaced
|
|
470
|
+
const param = visitor.parameter?.(node, { parent: parent as ParentOf<ParameterNode> }) ?? node
|
|
496
471
|
|
|
497
472
|
return createParameter({
|
|
498
473
|
...param,
|
|
@@ -500,11 +475,7 @@ export function transform(node: Node, options: TransformOptions): Node {
|
|
|
500
475
|
})
|
|
501
476
|
}
|
|
502
477
|
case 'Response': {
|
|
503
|
-
|
|
504
|
-
const replaced = visitor.response?.(response, {
|
|
505
|
-
parent: parent as ParentOf<ResponseNode>,
|
|
506
|
-
})
|
|
507
|
-
if (replaced) response = replaced
|
|
478
|
+
const response = visitor.response?.(node, { parent: parent as ParentOf<ResponseNode> }) ?? node
|
|
508
479
|
|
|
509
480
|
return {
|
|
510
481
|
...response,
|