@kubb/ast 5.0.0-beta.2 → 5.0.0-beta.21

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/src/visitor.ts CHANGED
@@ -176,13 +176,13 @@ export type AsyncVisitor = {
176
176
  * ```
177
177
  */
178
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
179
+ input?(node: InputNode, context: VisitorContext<InputNode>): T | null | undefined
180
+ output?(node: OutputNode, context: VisitorContext<OutputNode>): T | null | undefined
181
+ operation?(node: OperationNode, context: VisitorContext<OperationNode>): T | null | undefined
182
+ schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): T | null | undefined
183
+ property?(node: PropertyNode, context: VisitorContext<PropertyNode>): T | null | undefined
184
+ parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): T | null | undefined
185
+ response?(node: ResponseNode, context: VisitorContext<ResponseNode>): T | null | undefined
186
186
  }
187
187
 
188
188
  /**
@@ -265,39 +265,47 @@ 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): 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> = []
268
+ function* getChildren(node: Node, recurse: boolean): Generator<Node, void, undefined> {
269
+ if (node.kind === 'Input') {
270
+ yield* node.schemas
271
+ yield* node.operations
278
272
 
279
- if (!recurse) return []
273
+ return
274
+ }
275
+ if (node.kind === 'Output') return
276
+ if (node.kind === 'Operation') {
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
280
284
 
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
+ return
286
+ }
287
+ if (node.kind === 'Schema') {
288
+ if (!recurse) return
289
+ if ('properties' in node && node.properties.length > 0) yield* node.properties
290
+ if ('items' in node && node.items) yield* node.items
291
+ if ('members' in node && node.members) yield* node.members
292
+ if ('additionalProperties' in node && node.additionalProperties && node.additionalProperties !== true) yield node.additionalProperties
293
+
294
+ return
295
+ }
296
+ if (node.kind === 'Property') {
297
+ yield node.schema
285
298
 
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 []
299
+ return
300
+ }
301
+ if (node.kind === 'Parameter') {
302
+ yield node.schema
303
+
304
+ return
305
+ }
306
+ if (node.kind === 'Response') {
307
+ if (node.schema) yield node.schema
308
+ return
301
309
  }
302
310
  }
303
311
 
@@ -337,11 +345,7 @@ async function _walk(node: Node, visitor: AsyncVisitor, recurse: boolean, limit:
337
345
  await limit(() => visitor.output?.(node, { parent: parent as ParentOf<OutputNode> }))
338
346
  break
339
347
  case 'Operation':
340
- await limit(() =>
341
- visitor.operation?.(node, {
342
- parent: parent as ParentOf<OperationNode>,
343
- }),
344
- )
348
+ await limit(() => visitor.operation?.(node, { parent: parent as ParentOf<OperationNode> }))
345
349
  break
346
350
  case 'Schema':
347
351
  await limit(() => visitor.schema?.(node, { parent: parent as ParentOf<SchemaNode> }))
@@ -350,19 +354,11 @@ async function _walk(node: Node, visitor: AsyncVisitor, recurse: boolean, limit:
350
354
  await limit(() => visitor.property?.(node, { parent: parent as ParentOf<PropertyNode> }))
351
355
  break
352
356
  case 'Parameter':
353
- await limit(() =>
354
- visitor.parameter?.(node, {
355
- parent: parent as ParentOf<ParameterNode>,
356
- }),
357
- )
357
+ await limit(() => visitor.parameter?.(node, { parent: parent as ParentOf<ParameterNode> }))
358
358
  break
359
359
  case 'Response':
360
360
  await limit(() => visitor.response?.(node, { parent: parent as ParentOf<ResponseNode> }))
361
361
  break
362
- case 'FunctionParameter':
363
- case 'ParameterGroup':
364
- case 'FunctionParameters':
365
- break
366
362
  }
367
363
 
368
364
  const children = getChildren(node, recurse)
@@ -404,125 +400,94 @@ export function transform(node: Node, options: TransformOptions): Node {
404
400
  const { depth, parent, ...visitor } = options
405
401
  const recurse = (depth ?? visitorDepths.deep) === visitorDepths.deep
406
402
 
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
403
+ if (node.kind === 'Input') {
404
+ const input = visitor.input?.(node, { parent: parent as ParentOf<InputNode> }) ?? node
414
405
 
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
- }
406
+ return {
407
+ ...input,
408
+ schemas: input.schemas.map((s) => transform(s, { ...options, parent: input })),
409
+ operations: input.operations.map((op) => transform(op, { ...options, parent: input })),
420
410
  }
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
411
+ }
427
412
 
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
413
+ if (node.kind === 'Output') {
414
+ return visitor.output?.(node, { parent: parent as ParentOf<OutputNode> }) ?? node
415
+ }
483
416
 
484
- return createProperty({
485
- ...prop,
486
- schema: transform(prop.schema, { ...options, parent: prop }),
487
- })
417
+ if (node.kind === 'Operation') {
418
+ const op = visitor.operation?.(node, { parent: parent as ParentOf<OperationNode> }) ?? node
419
+
420
+ return {
421
+ ...op,
422
+ parameters: op.parameters.map((p) => transform(p, { ...options, parent: op })),
423
+ requestBody: op.requestBody
424
+ ? {
425
+ ...op.requestBody,
426
+ content: op.requestBody.content?.map((c) => ({
427
+ ...c,
428
+ schema: c.schema ? transform(c.schema, { ...options, parent: op }) : undefined,
429
+ })),
430
+ }
431
+ : undefined,
432
+ responses: op.responses.map((r) => transform(r, { ...options, parent: op })),
488
433
  }
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
434
+ }
495
435
 
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
436
+ if (node.kind === 'Schema') {
437
+ const schema = visitor.schema?.(node, { parent: parent as ParentOf<SchemaNode> }) ?? node
438
+
439
+ const childOptions = { ...options, parent: schema }
440
+
441
+ return {
442
+ ...schema,
443
+ ...('properties' in schema && recurse
444
+ ? {
445
+ properties: schema.properties.map((p) => transform(p, childOptions)),
446
+ }
447
+ : {}),
448
+ ...('items' in schema && recurse ? { items: schema.items?.map((i) => transform(i, childOptions)) } : {}),
449
+ ...('members' in schema && recurse ? { members: schema.members?.map((m) => transform(m, childOptions)) } : {}),
450
+ ...('additionalProperties' in schema && recurse && schema.additionalProperties && schema.additionalProperties !== true
451
+ ? {
452
+ additionalProperties: transform(schema.additionalProperties, childOptions),
453
+ }
454
+ : {}),
455
+ } as SchemaNode
456
+ }
507
457
 
508
- return {
509
- ...response,
510
- schema: transform(response.schema, { ...options, parent: response }),
511
- }
458
+ if (node.kind === 'Property') {
459
+ const prop = visitor.property?.(node, { parent: parent as ParentOf<PropertyNode> }) ?? node
460
+
461
+ return createProperty({
462
+ ...prop,
463
+ schema: transform(prop.schema, { ...options, parent: prop }),
464
+ })
465
+ }
466
+
467
+ if (node.kind === 'Parameter') {
468
+ const param = visitor.parameter?.(node, { parent: parent as ParentOf<ParameterNode> }) ?? node
469
+
470
+ return createParameter({
471
+ ...param,
472
+ schema: transform(param.schema, { ...options, parent: param }),
473
+ })
474
+ }
475
+
476
+ if (node.kind === 'Response') {
477
+ const response = visitor.response?.(node, { parent: parent as ParentOf<ResponseNode> }) ?? node
478
+
479
+ return {
480
+ ...response,
481
+ schema: transform(response.schema, { ...options, parent: response }),
512
482
  }
513
- case 'FunctionParameter':
514
- case 'ParameterGroup':
515
- case 'FunctionParameters':
516
- case 'Type':
517
- return node
518
- default:
519
- return node
520
483
  }
484
+
485
+ return node
521
486
  }
522
487
  /**
523
488
  * Runs a depth-first synchronous collection pass.
524
489
  *
525
- * Non-`undefined` values returned by visitor callbacks are appended to the result.
490
+ * Non-`null` values returned by visitor callbacks are appended to the result.
526
491
  *
527
492
  * @example
528
493
  * ```ts
@@ -539,12 +504,11 @@ export function transform(node: Node, options: TransformOptions): Node {
539
504
  * const values = collect(root, { depth: 'shallow', root: () => 'root' })
540
505
  * ```
541
506
  */
542
- export function collect<T>(node: Node, options: CollectOptions<T>): Array<T> {
507
+ export function* collectLazy<T>(node: Node, options: CollectOptions<T>): Generator<T, void, undefined> {
543
508
  const { depth, parent, ...visitor } = options
544
509
  const recurse = (depth ?? visitorDepths.deep) === visitorDepths.deep
545
- const results: Array<T> = []
546
510
 
547
- let v: T | undefined
511
+ let v: T | null | undefined
548
512
  switch (node.kind) {
549
513
  case 'Input':
550
514
  v = visitor.input?.(node, { parent: parent as ParentOf<InputNode> })
@@ -553,40 +517,28 @@ export function collect<T>(node: Node, options: CollectOptions<T>): Array<T> {
553
517
  v = visitor.output?.(node, { parent: parent as ParentOf<OutputNode> })
554
518
  break
555
519
  case 'Operation':
556
- v = visitor.operation?.(node, {
557
- parent: parent as ParentOf<OperationNode>,
558
- })
520
+ v = visitor.operation?.(node, { parent: parent as ParentOf<OperationNode> })
559
521
  break
560
522
  case 'Schema':
561
523
  v = visitor.schema?.(node, { parent: parent as ParentOf<SchemaNode> })
562
524
  break
563
525
  case 'Property':
564
- v = visitor.property?.(node, {
565
- parent: parent as ParentOf<PropertyNode>,
566
- })
526
+ v = visitor.property?.(node, { parent: parent as ParentOf<PropertyNode> })
567
527
  break
568
528
  case 'Parameter':
569
- v = visitor.parameter?.(node, {
570
- parent: parent as ParentOf<ParameterNode>,
571
- })
529
+ v = visitor.parameter?.(node, { parent: parent as ParentOf<ParameterNode> })
572
530
  break
573
531
  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':
532
+ v = visitor.response?.(node, { parent: parent as ParentOf<ResponseNode> })
581
533
  break
582
534
  }
583
- if (v !== undefined) results.push(v)
535
+ if (v != null) yield v
584
536
 
585
537
  for (const child of getChildren(node, recurse)) {
586
- for (const item of collect(child, { ...options, parent: node })) {
587
- results.push(item)
588
- }
538
+ yield* collectLazy(child, { ...options, parent: node })
589
539
  }
540
+ }
590
541
 
591
- return results
542
+ export function collect<T>(node: Node, options: CollectOptions<T>): Array<T> {
543
+ return Array.from(collectLazy(node, options))
592
544
  }