@kubb/ast 5.0.0-beta.3 → 5.0.0-beta.31
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/README.md +1 -1
- package/dist/index.cjs +694 -331
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1433 -1007
- package/dist/index.js +682 -332
- package/dist/index.js.map +1 -1
- package/package.json +3 -4
- package/src/dedupe.ts +202 -0
- package/src/dialect.ts +64 -0
- package/src/dispatch.ts +53 -0
- package/src/factory.ts +127 -11
- package/src/guards.ts +18 -3
- package/src/index.ts +11 -3
- package/src/infer.ts +16 -5
- package/src/nodes/base.ts +2 -0
- package/src/nodes/code.ts +21 -21
- package/src/nodes/content.ts +37 -0
- package/src/nodes/file.ts +16 -14
- package/src/nodes/index.ts +7 -3
- package/src/nodes/operation.ts +98 -62
- package/src/nodes/response.ts +21 -14
- package/src/nodes/root.ts +72 -10
- package/src/nodes/schema.ts +9 -3
- package/src/printer.ts +34 -28
- package/src/refs.ts +4 -2
- package/src/resolvers.ts +4 -4
- package/src/signature.ts +135 -0
- package/src/transformers.ts +20 -15
- package/src/types.ts +8 -0
- package/src/utils.ts +109 -68
- package/src/visitor.ts +229 -275
package/dist/index.d.ts
CHANGED
|
@@ -199,7 +199,7 @@ declare const mediaTypes: {
|
|
|
199
199
|
* const kind: NodeKind = 'Schema'
|
|
200
200
|
* ```
|
|
201
201
|
*/
|
|
202
|
-
type NodeKind = 'Input' | 'Output' | 'Operation' | 'Schema' | 'Property' | 'Parameter' | 'Response' | 'FunctionParameter' | 'ParameterGroup' | 'FunctionParameters' | 'Type' | 'ParamsType' | 'File' | 'Import' | 'Export' | 'Source' | 'Const' | 'Function' | 'ArrowFunction' | 'Text' | 'Break' | 'Jsx';
|
|
202
|
+
type NodeKind = 'Input' | 'Output' | 'Operation' | 'Schema' | 'Property' | 'Parameter' | 'Response' | 'RequestBody' | 'Content' | 'FunctionParameter' | 'ParameterGroup' | 'FunctionParameters' | 'Type' | 'ParamsType' | 'File' | 'Import' | 'Export' | 'Source' | 'Const' | 'Function' | 'ArrowFunction' | 'Text' | 'Break' | 'Jsx';
|
|
203
203
|
/**
|
|
204
204
|
* Base shape shared by all AST nodes.
|
|
205
205
|
*
|
|
@@ -251,21 +251,21 @@ type ConstNode = BaseNode & {
|
|
|
251
251
|
* Whether the declaration should be exported.
|
|
252
252
|
* @default false
|
|
253
253
|
*/
|
|
254
|
-
export?: boolean;
|
|
254
|
+
export?: boolean | null;
|
|
255
255
|
/**
|
|
256
256
|
* Optional explicit type annotation.
|
|
257
257
|
* @example 'Pet'
|
|
258
258
|
*/
|
|
259
|
-
type?: string;
|
|
259
|
+
type?: string | null;
|
|
260
260
|
/**
|
|
261
261
|
* JSDoc documentation metadata.
|
|
262
262
|
*/
|
|
263
|
-
JSDoc?: JSDocNode;
|
|
263
|
+
JSDoc?: JSDocNode | null;
|
|
264
264
|
/**
|
|
265
265
|
* Whether to append `as const` to the declaration.
|
|
266
266
|
* @default false
|
|
267
267
|
*/
|
|
268
|
-
asConst?: boolean;
|
|
268
|
+
asConst?: boolean | null;
|
|
269
269
|
/**
|
|
270
270
|
* Child nodes representing the value of the constant (children of the `Const` component).
|
|
271
271
|
* Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
|
|
@@ -297,11 +297,11 @@ type TypeNode = BaseNode & {
|
|
|
297
297
|
* Whether the declaration should be exported.
|
|
298
298
|
* @default false
|
|
299
299
|
*/
|
|
300
|
-
export?: boolean;
|
|
300
|
+
export?: boolean | null;
|
|
301
301
|
/**
|
|
302
302
|
* JSDoc documentation metadata.
|
|
303
303
|
*/
|
|
304
|
-
JSDoc?: JSDocNode;
|
|
304
|
+
JSDoc?: JSDocNode | null;
|
|
305
305
|
/**
|
|
306
306
|
* Child nodes representing the type body (children of the `Type` component).
|
|
307
307
|
* Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
|
|
@@ -338,35 +338,35 @@ type FunctionNode = BaseNode & {
|
|
|
338
338
|
* Whether the function is a default export.
|
|
339
339
|
* @default false
|
|
340
340
|
*/
|
|
341
|
-
default?: boolean;
|
|
341
|
+
default?: boolean | null;
|
|
342
342
|
/**
|
|
343
343
|
* Function parameter list rendered as a string (e.g. from `FunctionParams.toConstructor()`).
|
|
344
344
|
*/
|
|
345
|
-
params?: string;
|
|
345
|
+
params?: string | null;
|
|
346
346
|
/**
|
|
347
347
|
* Whether the function should be exported.
|
|
348
348
|
* @default false
|
|
349
349
|
*/
|
|
350
|
-
export?: boolean;
|
|
350
|
+
export?: boolean | null;
|
|
351
351
|
/**
|
|
352
352
|
* Whether the function is async. When `true`, the return type is wrapped in `Promise<>`.
|
|
353
353
|
* @default false
|
|
354
354
|
*/
|
|
355
|
-
async?: boolean;
|
|
355
|
+
async?: boolean | null;
|
|
356
356
|
/**
|
|
357
357
|
* TypeScript generic type parameters.
|
|
358
358
|
* @example ['T', 'U extends string']
|
|
359
359
|
*/
|
|
360
|
-
generics?: string | string
|
|
360
|
+
generics?: string | Array<string> | null;
|
|
361
361
|
/**
|
|
362
362
|
* Return type annotation.
|
|
363
363
|
* @example 'Pet'
|
|
364
364
|
*/
|
|
365
|
-
returnType?: string;
|
|
365
|
+
returnType?: string | null;
|
|
366
366
|
/**
|
|
367
367
|
* JSDoc documentation metadata.
|
|
368
368
|
*/
|
|
369
|
-
JSDoc?: JSDocNode;
|
|
369
|
+
JSDoc?: JSDocNode | null;
|
|
370
370
|
/**
|
|
371
371
|
* Child nodes representing the function body (children of the `Function` component).
|
|
372
372
|
* Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
|
|
@@ -398,40 +398,40 @@ type ArrowFunctionNode = BaseNode & {
|
|
|
398
398
|
* Whether the function is a default export.
|
|
399
399
|
* @default false
|
|
400
400
|
*/
|
|
401
|
-
default?: boolean;
|
|
401
|
+
default?: boolean | null;
|
|
402
402
|
/**
|
|
403
403
|
* Function parameter list rendered as a string (e.g. from `FunctionParams.toConstructor()`).
|
|
404
404
|
*/
|
|
405
|
-
params?: string;
|
|
405
|
+
params?: string | null;
|
|
406
406
|
/**
|
|
407
407
|
* Whether the arrow function should be exported.
|
|
408
408
|
* @default false
|
|
409
409
|
*/
|
|
410
|
-
export?: boolean;
|
|
410
|
+
export?: boolean | null;
|
|
411
411
|
/**
|
|
412
412
|
* Whether the arrow function is async. When `true`, the return type is wrapped in `Promise<>`.
|
|
413
413
|
* @default false
|
|
414
414
|
*/
|
|
415
|
-
async?: boolean;
|
|
415
|
+
async?: boolean | null;
|
|
416
416
|
/**
|
|
417
417
|
* TypeScript generic type parameters.
|
|
418
418
|
* @example ['T', 'U extends string']
|
|
419
419
|
*/
|
|
420
|
-
generics?: string | string
|
|
420
|
+
generics?: string | Array<string> | null;
|
|
421
421
|
/**
|
|
422
422
|
* Return type annotation.
|
|
423
423
|
* @example 'Pet'
|
|
424
424
|
*/
|
|
425
|
-
returnType?: string;
|
|
425
|
+
returnType?: string | null;
|
|
426
426
|
/**
|
|
427
427
|
* JSDoc documentation metadata.
|
|
428
428
|
*/
|
|
429
|
-
JSDoc?: JSDocNode;
|
|
429
|
+
JSDoc?: JSDocNode | null;
|
|
430
430
|
/**
|
|
431
431
|
* Render the arrow function body as a single-line expression.
|
|
432
432
|
* @default false
|
|
433
433
|
*/
|
|
434
|
-
singleLine?: boolean;
|
|
434
|
+
singleLine?: boolean | null;
|
|
435
435
|
/**
|
|
436
436
|
* Child nodes representing the function body (children of the `Function.Arrow` component).
|
|
437
437
|
* Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
|
|
@@ -510,1079 +510,1123 @@ type JsxNode = BaseNode & {
|
|
|
510
510
|
*/
|
|
511
511
|
type CodeNode = ConstNode | TypeNode | FunctionNode | ArrowFunctionNode | TextNode | BreakNode | JsxNode;
|
|
512
512
|
//#endregion
|
|
513
|
-
//#region src/nodes/
|
|
514
|
-
/**
|
|
515
|
-
* Supported file extensions.
|
|
516
|
-
*/
|
|
517
|
-
type Extname = '.ts' | '.js' | '.tsx' | '.json' | `.${string}`;
|
|
518
|
-
type ImportName = string | Array<string | {
|
|
519
|
-
propertyName: string;
|
|
520
|
-
name?: string;
|
|
521
|
-
}>;
|
|
513
|
+
//#region src/nodes/property.d.ts
|
|
522
514
|
/**
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
* @example Named import (TypeScript: `import { useState } from 'react'`)
|
|
526
|
-
* ```ts
|
|
527
|
-
* createImport({ name: ['useState'], path: 'react' })
|
|
528
|
-
* ```
|
|
529
|
-
*
|
|
530
|
-
* @example Default import (TypeScript: `import React from 'react'`)
|
|
531
|
-
* ```ts
|
|
532
|
-
* createImport({ name: 'React', path: 'react' })
|
|
533
|
-
* ```
|
|
534
|
-
*
|
|
535
|
-
* @example Type-only import (TypeScript: `import type { FC } from 'react'`)
|
|
536
|
-
* ```ts
|
|
537
|
-
* createImport({ name: ['FC'], path: 'react', isTypeOnly: true })
|
|
538
|
-
* ```
|
|
515
|
+
* AST node representing one named object property.
|
|
539
516
|
*
|
|
540
|
-
* @example
|
|
517
|
+
* @example
|
|
541
518
|
* ```ts
|
|
542
|
-
*
|
|
519
|
+
* const property: PropertyNode = {
|
|
520
|
+
* kind: 'Property',
|
|
521
|
+
* name: 'id',
|
|
522
|
+
* schema: createSchema({ type: 'integer' }),
|
|
523
|
+
* required: true,
|
|
524
|
+
* }
|
|
543
525
|
* ```
|
|
544
526
|
*/
|
|
545
|
-
type
|
|
546
|
-
kind: 'Import';
|
|
547
|
-
/**
|
|
548
|
-
* Import name(s) to be used.
|
|
549
|
-
* @example ['useState']
|
|
550
|
-
* @example 'React'
|
|
551
|
-
*/
|
|
552
|
-
name: ImportName;
|
|
527
|
+
type PropertyNode = BaseNode & {
|
|
553
528
|
/**
|
|
554
|
-
*
|
|
555
|
-
* @example '@kubb/core'
|
|
529
|
+
* Node kind.
|
|
556
530
|
*/
|
|
557
|
-
|
|
531
|
+
kind: 'Property';
|
|
558
532
|
/**
|
|
559
|
-
*
|
|
560
|
-
* - `true` generates `import type { Type } from './path'`
|
|
561
|
-
* - `false` generates `import { Type } from './path'`
|
|
562
|
-
* @default false
|
|
533
|
+
* Property key.
|
|
563
534
|
*/
|
|
564
|
-
|
|
535
|
+
name: string;
|
|
565
536
|
/**
|
|
566
|
-
*
|
|
567
|
-
* - `true` generates `import * as Name from './path'`
|
|
568
|
-
* - `false` generates standard import
|
|
569
|
-
* @default false
|
|
537
|
+
* Property schema.
|
|
570
538
|
*/
|
|
571
|
-
|
|
539
|
+
schema: SchemaNode;
|
|
572
540
|
/**
|
|
573
|
-
*
|
|
541
|
+
* Whether the property is required.
|
|
574
542
|
*/
|
|
575
|
-
|
|
543
|
+
required: boolean;
|
|
576
544
|
};
|
|
545
|
+
//#endregion
|
|
546
|
+
//#region src/nodes/schema.d.ts
|
|
547
|
+
type PrimitiveSchemaType =
|
|
577
548
|
/**
|
|
578
|
-
*
|
|
579
|
-
*
|
|
580
|
-
* @example Named export (TypeScript: `export { Pets } from './Pets'`)
|
|
581
|
-
* ```ts
|
|
582
|
-
* createExport({ name: ['Pets'], path: './Pets' })
|
|
583
|
-
* ```
|
|
584
|
-
*
|
|
585
|
-
* @example Type-only export (TypeScript: `export type { Pet } from './Pet'`)
|
|
586
|
-
* ```ts
|
|
587
|
-
* createExport({ name: ['Pet'], path: './Pet', isTypeOnly: true })
|
|
588
|
-
* ```
|
|
589
|
-
*
|
|
590
|
-
* @example Wildcard export (TypeScript: `export * from './utils'`)
|
|
591
|
-
* ```ts
|
|
592
|
-
* createExport({ path: './utils' })
|
|
593
|
-
* ```
|
|
594
|
-
*
|
|
595
|
-
* @example Namespace alias (TypeScript: `export * as utils from './utils'`)
|
|
596
|
-
* ```ts
|
|
597
|
-
* createExport({ name: 'utils', path: './utils', asAlias: true })
|
|
598
|
-
* ```
|
|
549
|
+
* Text value.
|
|
599
550
|
*/
|
|
600
|
-
|
|
601
|
-
kind: 'Export';
|
|
602
|
-
/**
|
|
603
|
-
* Export name(s) to be used. When omitted, generates a wildcard export.
|
|
604
|
-
* @example ['useState']
|
|
605
|
-
* @example 'React'
|
|
606
|
-
*/
|
|
607
|
-
name?: string | Array<string>;
|
|
608
|
-
/**
|
|
609
|
-
* Path for the export.
|
|
610
|
-
* @example '@kubb/core'
|
|
611
|
-
*/
|
|
612
|
-
path: string;
|
|
613
|
-
/**
|
|
614
|
-
* Add type-only export prefix.
|
|
615
|
-
* - `true` generates `export type { Type } from './path'`
|
|
616
|
-
* - `false` generates `export { Type } from './path'`
|
|
617
|
-
* @default false
|
|
618
|
-
*/
|
|
619
|
-
isTypeOnly?: boolean;
|
|
620
|
-
/**
|
|
621
|
-
* Export as an aliased namespace.
|
|
622
|
-
* - `true` generates `export * as aliasName from './path'`
|
|
623
|
-
* - `false` generates a standard export
|
|
624
|
-
* @default false
|
|
625
|
-
*/
|
|
626
|
-
asAlias?: boolean;
|
|
627
|
-
};
|
|
551
|
+
'string'
|
|
628
552
|
/**
|
|
629
|
-
*
|
|
630
|
-
*
|
|
631
|
-
* @example Named exportable source
|
|
632
|
-
* ```ts
|
|
633
|
-
* createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true, isIndexable: true })
|
|
634
|
-
* ```
|
|
635
|
-
*
|
|
636
|
-
* @example Inline unnamed code block
|
|
637
|
-
* ```ts
|
|
638
|
-
* createSource({ nodes: [createText('const x = 1')] })
|
|
639
|
-
* ```
|
|
553
|
+
* Floating-point number.
|
|
640
554
|
*/
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
555
|
+
| 'number'
|
|
556
|
+
/**
|
|
557
|
+
* Integer number.
|
|
558
|
+
*/
|
|
559
|
+
| 'integer'
|
|
560
|
+
/**
|
|
561
|
+
* Big integer number.
|
|
562
|
+
*/
|
|
563
|
+
| 'bigint'
|
|
564
|
+
/**
|
|
565
|
+
* Boolean value.
|
|
566
|
+
*/
|
|
567
|
+
| 'boolean'
|
|
568
|
+
/**
|
|
569
|
+
* Null value.
|
|
570
|
+
*/
|
|
571
|
+
| 'null'
|
|
572
|
+
/**
|
|
573
|
+
* Any value.
|
|
574
|
+
*/
|
|
575
|
+
| 'any'
|
|
576
|
+
/**
|
|
577
|
+
* Unknown value.
|
|
578
|
+
*/
|
|
579
|
+
| 'unknown'
|
|
580
|
+
/**
|
|
581
|
+
* No value (`void`).
|
|
582
|
+
*/
|
|
583
|
+
| 'void'
|
|
584
|
+
/**
|
|
585
|
+
* Never value.
|
|
586
|
+
*/
|
|
587
|
+
| 'never'
|
|
588
|
+
/**
|
|
589
|
+
* Object value.
|
|
590
|
+
*/
|
|
591
|
+
| 'object'
|
|
592
|
+
/**
|
|
593
|
+
* Array value.
|
|
594
|
+
*/
|
|
595
|
+
| 'array'
|
|
596
|
+
/**
|
|
597
|
+
* Date value.
|
|
598
|
+
*/
|
|
599
|
+
| 'date';
|
|
600
|
+
/**
|
|
601
|
+
* Composite schema types.
|
|
602
|
+
*/
|
|
603
|
+
type ComplexSchemaType = 'tuple' | 'union' | 'intersection' | 'enum';
|
|
604
|
+
/**
|
|
605
|
+
* Schema types that need special handling in generators.
|
|
606
|
+
*/
|
|
607
|
+
type SpecialSchemaType = 'ref' | 'datetime' | 'time' | 'uuid' | 'email' | 'url' | 'ipv4' | 'ipv6' | 'blob';
|
|
608
|
+
/**
|
|
609
|
+
* All schema type strings.
|
|
610
|
+
*/
|
|
611
|
+
type SchemaType = PrimitiveSchemaType | ComplexSchemaType | SpecialSchemaType;
|
|
612
|
+
/**
|
|
613
|
+
* Scalar schema types without extra object/array/ref structure.
|
|
614
|
+
*/
|
|
615
|
+
type ScalarSchemaType = Exclude<SchemaType, 'object' | 'array' | 'tuple' | 'union' | 'intersection' | 'enum' | 'ref' | 'datetime' | 'date' | 'time' | 'string' | 'number' | 'integer' | 'bigint' | 'url' | 'uuid' | 'email'>;
|
|
616
|
+
/**
|
|
617
|
+
* Fields shared by all schema nodes.
|
|
618
|
+
*/
|
|
619
|
+
type SchemaNodeBase = BaseNode & {
|
|
652
620
|
/**
|
|
653
|
-
*
|
|
654
|
-
* @default false
|
|
621
|
+
* Node kind.
|
|
655
622
|
*/
|
|
656
|
-
|
|
623
|
+
kind: 'Schema';
|
|
657
624
|
/**
|
|
658
|
-
*
|
|
659
|
-
*
|
|
625
|
+
* Schema name for named definitions (for example, `"Pet"`).
|
|
626
|
+
* Inline schemas omit this field.
|
|
627
|
+
* `null` means kubb has processed this and determined there is no applicable name.
|
|
628
|
+
* `undefined` means the name has not been set yet.
|
|
660
629
|
*/
|
|
661
|
-
|
|
630
|
+
name?: string | null;
|
|
662
631
|
/**
|
|
663
|
-
*
|
|
664
|
-
* Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
|
|
632
|
+
* Short schema title.
|
|
665
633
|
*/
|
|
666
|
-
|
|
667
|
-
};
|
|
668
|
-
/**
|
|
669
|
-
* Represents a fully resolved file in the AST.
|
|
670
|
-
*
|
|
671
|
-
* Created via `createFile()`, which computes the `id`, `name`, and `extname` from the input
|
|
672
|
-
* and deduplicates `imports`, `exports`, and `sources`.
|
|
673
|
-
*
|
|
674
|
-
* @example
|
|
675
|
-
* ```ts
|
|
676
|
-
* const file = createFile({
|
|
677
|
-
* baseName: 'petStore.ts',
|
|
678
|
-
* path: 'src/models/petStore.ts',
|
|
679
|
-
* sources: [createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true })],
|
|
680
|
-
* imports: [createImport({ name: ['z'], path: 'zod' })],
|
|
681
|
-
* exports: [createExport({ name: ['Pet'], path: './petStore' })],
|
|
682
|
-
* })
|
|
683
|
-
* // file.id = SHA256 hash of the path
|
|
684
|
-
* // file.name = 'petStore'
|
|
685
|
-
* // file.extname = '.ts'
|
|
686
|
-
* ```
|
|
687
|
-
*/
|
|
688
|
-
type FileNode<TMeta extends object = object> = BaseNode & {
|
|
689
|
-
kind: 'File';
|
|
634
|
+
title?: string;
|
|
690
635
|
/**
|
|
691
|
-
*
|
|
692
|
-
* @default hash
|
|
636
|
+
* Schema description text.
|
|
693
637
|
*/
|
|
694
|
-
|
|
638
|
+
description?: string;
|
|
695
639
|
/**
|
|
696
|
-
*
|
|
697
|
-
* @link https://nodejs.org/api/path.html#pathformatpathobject
|
|
640
|
+
* Whether `null` is allowed.
|
|
698
641
|
*/
|
|
699
|
-
|
|
642
|
+
nullable?: boolean;
|
|
700
643
|
/**
|
|
701
|
-
*
|
|
702
|
-
* Based on UNIX basename: `${name}${extname}`
|
|
703
|
-
* @link https://nodejs.org/api/path.html#pathbasenamepath-suffix
|
|
644
|
+
* Whether the field is optional.
|
|
704
645
|
*/
|
|
705
|
-
|
|
646
|
+
optional?: boolean;
|
|
706
647
|
/**
|
|
707
|
-
*
|
|
648
|
+
* Both optional and nullable (`optional` + `nullable`).
|
|
708
649
|
*/
|
|
709
|
-
|
|
650
|
+
nullish?: boolean;
|
|
710
651
|
/**
|
|
711
|
-
*
|
|
652
|
+
* Whether the schema is deprecated.
|
|
712
653
|
*/
|
|
713
|
-
|
|
654
|
+
deprecated?: boolean;
|
|
714
655
|
/**
|
|
715
|
-
*
|
|
656
|
+
* Whether the schema is read-only.
|
|
716
657
|
*/
|
|
717
|
-
|
|
658
|
+
readOnly?: boolean;
|
|
718
659
|
/**
|
|
719
|
-
*
|
|
660
|
+
* Whether the schema is write-only.
|
|
720
661
|
*/
|
|
721
|
-
|
|
662
|
+
writeOnly?: boolean;
|
|
722
663
|
/**
|
|
723
|
-
*
|
|
664
|
+
* Default value.
|
|
724
665
|
*/
|
|
725
|
-
|
|
666
|
+
default?: unknown;
|
|
726
667
|
/**
|
|
727
|
-
*
|
|
668
|
+
* Example value.
|
|
728
669
|
*/
|
|
729
|
-
|
|
670
|
+
example?: unknown;
|
|
730
671
|
/**
|
|
731
|
-
*
|
|
672
|
+
* Base primitive type.
|
|
673
|
+
* For example, this is `'string'` for a `uuid` schema.
|
|
732
674
|
*/
|
|
733
|
-
|
|
675
|
+
primitive?: PrimitiveSchemaType;
|
|
734
676
|
/**
|
|
735
|
-
*
|
|
677
|
+
* Schema `format` value.
|
|
736
678
|
*/
|
|
737
|
-
|
|
679
|
+
format?: string;
|
|
738
680
|
};
|
|
739
|
-
//#endregion
|
|
740
|
-
//#region src/nodes/function.d.ts
|
|
741
681
|
/**
|
|
742
|
-
*
|
|
743
|
-
* type annotation. Each language printer renders the variant into its own syntax.
|
|
744
|
-
*
|
|
745
|
-
* - `struct` — an inline anonymous type grouping named fields.
|
|
746
|
-
* TypeScript renders as `{ petId: string; name?: string }`.
|
|
747
|
-
* - `member` — a single named field accessed from a named group type.
|
|
748
|
-
* TypeScript renders as `PathParams['petId']`.
|
|
749
|
-
*
|
|
750
|
-
* @example Reference variant
|
|
751
|
-
* ```ts
|
|
752
|
-
* createParamsType({ variant: 'reference', name: 'QueryParams' })
|
|
753
|
-
* // QueryParams
|
|
754
|
-
* ```
|
|
755
|
-
*
|
|
756
|
-
* @example Struct variant
|
|
757
|
-
* ```ts
|
|
758
|
-
* createParamsType({ variant: 'struct', properties: [{ name: 'petId', optional: false, type: createParamsType({ variant: 'reference', name: 'string' }) }] })
|
|
759
|
-
* // { petId: string }
|
|
760
|
-
* ```
|
|
682
|
+
* Object schema with ordered properties.
|
|
761
683
|
*
|
|
762
|
-
* @example
|
|
684
|
+
* @example
|
|
763
685
|
* ```ts
|
|
764
|
-
*
|
|
765
|
-
*
|
|
686
|
+
* const objectSchema: ObjectSchemaNode = {
|
|
687
|
+
* kind: 'Schema',
|
|
688
|
+
* type: 'object',
|
|
689
|
+
* properties: [],
|
|
690
|
+
* }
|
|
766
691
|
* ```
|
|
767
692
|
*/
|
|
768
|
-
type
|
|
769
|
-
/**
|
|
770
|
-
* Node kind.
|
|
771
|
-
*/
|
|
772
|
-
kind: 'ParamsType';
|
|
773
|
-
} & ({
|
|
693
|
+
type ObjectSchemaNode = SchemaNodeBase & {
|
|
774
694
|
/**
|
|
775
|
-
*
|
|
776
|
-
* TypeScript renders as-is, e.g. `string`, `QueryParams`, `Partial<Config>`.
|
|
695
|
+
* Schema type discriminator.
|
|
777
696
|
*/
|
|
778
|
-
|
|
697
|
+
type: 'object';
|
|
779
698
|
/**
|
|
780
|
-
*
|
|
699
|
+
* Primitive type — always `'object'` for object schemas.
|
|
781
700
|
*/
|
|
782
|
-
|
|
783
|
-
} | {
|
|
701
|
+
primitive: 'object';
|
|
784
702
|
/**
|
|
785
|
-
*
|
|
786
|
-
* TypeScript renders as `{ key: Type; other?: OtherType }`.
|
|
703
|
+
* Ordered object properties.
|
|
787
704
|
*/
|
|
788
|
-
|
|
705
|
+
properties: Array<PropertyNode>;
|
|
789
706
|
/**
|
|
790
|
-
*
|
|
707
|
+
* Additional object properties behavior:
|
|
708
|
+
* - `true`: allow any value
|
|
709
|
+
* - `false`: reject unknown properties (maps to `.strict()` in Zod)
|
|
710
|
+
* - `SchemaNode`: allow values that match that schema
|
|
711
|
+
* - `undefined`: no additional properties constraint (open object)
|
|
791
712
|
*/
|
|
792
|
-
|
|
793
|
-
name: string;
|
|
794
|
-
optional: boolean;
|
|
795
|
-
type: ParamsTypeNode;
|
|
796
|
-
}>;
|
|
797
|
-
} | {
|
|
713
|
+
additionalProperties?: SchemaNode | boolean;
|
|
798
714
|
/**
|
|
799
|
-
*
|
|
800
|
-
* TypeScript renders as `Base['key']`.
|
|
715
|
+
* Pattern-based property schemas.
|
|
801
716
|
*/
|
|
802
|
-
|
|
717
|
+
patternProperties?: Record<string, SchemaNode>;
|
|
803
718
|
/**
|
|
804
|
-
*
|
|
719
|
+
* Minimum number of properties allowed.
|
|
805
720
|
*/
|
|
806
|
-
|
|
721
|
+
minProperties?: number;
|
|
807
722
|
/**
|
|
808
|
-
*
|
|
723
|
+
* Maximum number of properties allowed.
|
|
809
724
|
*/
|
|
810
|
-
|
|
811
|
-
}
|
|
725
|
+
maxProperties?: number;
|
|
726
|
+
};
|
|
812
727
|
/**
|
|
813
|
-
*
|
|
814
|
-
*
|
|
815
|
-
* @example Required parameter
|
|
816
|
-
* `name: Type`
|
|
817
|
-
*
|
|
818
|
-
* @example Optional parameter
|
|
819
|
-
* `name?: Type`
|
|
820
|
-
*
|
|
821
|
-
* @example Parameter with default value
|
|
822
|
-
* `name: Type = defaultValue`
|
|
728
|
+
* Array-like schema (`array` or `tuple`).
|
|
823
729
|
*
|
|
824
|
-
* @example
|
|
825
|
-
*
|
|
730
|
+
* @example
|
|
731
|
+
* ```ts
|
|
732
|
+
* const arraySchema: ArraySchemaNode = {
|
|
733
|
+
* kind: 'Schema',
|
|
734
|
+
* type: 'array',
|
|
735
|
+
* items: [],
|
|
736
|
+
* }
|
|
737
|
+
* ```
|
|
826
738
|
*/
|
|
827
|
-
type
|
|
828
|
-
/**
|
|
829
|
-
* Node kind.
|
|
830
|
-
*/
|
|
831
|
-
kind: 'FunctionParameter';
|
|
832
|
-
/**
|
|
833
|
-
* Parameter name in the generated signature.
|
|
834
|
-
*/
|
|
835
|
-
name: string;
|
|
836
|
-
/**
|
|
837
|
-
* Type annotation as a structured {@link ParamsTypeNode}.
|
|
838
|
-
* Omit for untyped output.
|
|
839
|
-
*
|
|
840
|
-
* @example Reference type node
|
|
841
|
-
* `{ kind: 'ParamsType', variant: 'reference', name: 'string' }` → `petId: string`
|
|
842
|
-
*
|
|
843
|
-
* @example Struct type node
|
|
844
|
-
* `{ kind: 'ParamsType', variant: 'struct', properties: [...] }` → `{ key: Type; other?: OtherType }`
|
|
845
|
-
*
|
|
846
|
-
* @example Member type node
|
|
847
|
-
* `{ kind: 'ParamsType', variant: 'member', base: 'PathParams', key: 'petId' }` → `PathParams['petId']`
|
|
848
|
-
*/
|
|
849
|
-
type?: ParamsTypeNode;
|
|
739
|
+
type ArraySchemaNode = SchemaNodeBase & {
|
|
850
740
|
/**
|
|
851
|
-
*
|
|
852
|
-
*
|
|
853
|
-
* @example Rest parameter
|
|
854
|
-
* `...name: Type[]`
|
|
741
|
+
* Schema type discriminator (`array` or `tuple`).
|
|
855
742
|
*/
|
|
856
|
-
|
|
857
|
-
}
|
|
858
|
-
/**
|
|
859
|
-
* Optional parameter — rendered with `?` and may be omitted by the caller.
|
|
860
|
-
* Cannot be combined with `default` because a defaulted parameter is already optional.
|
|
861
|
-
*/
|
|
862
|
-
& ({
|
|
863
|
-
optional: true;
|
|
864
|
-
default?: never;
|
|
865
|
-
}
|
|
866
|
-
/**
|
|
867
|
-
* Required parameter, or a parameter with a default value.
|
|
868
|
-
*
|
|
869
|
-
* @example Required
|
|
870
|
-
* `name: Type`
|
|
871
|
-
*
|
|
872
|
-
* @example With default
|
|
873
|
-
* `name: Type = default`
|
|
874
|
-
*/
|
|
875
|
-
| {
|
|
876
|
-
optional?: false;
|
|
877
|
-
default?: string;
|
|
878
|
-
});
|
|
879
|
-
/**
|
|
880
|
-
* AST node for a group of related function parameters treated as a single unit.
|
|
881
|
-
*
|
|
882
|
-
* Each language printer decides how to render this group:
|
|
883
|
-
* - TypeScript/JS: destructured object `{ key1, key2 }: { key1: Type1; key2: Type2 } = {}`
|
|
884
|
-
* - Python: keyword-only args or a typed dict parameter
|
|
885
|
-
* - C# / Kotlin: named record / data-class parameter
|
|
886
|
-
*
|
|
887
|
-
* When `inline` is `true`, the group is spread as individual top-level parameters
|
|
888
|
-
* rather than wrapped in a single grouped construct.
|
|
889
|
-
*
|
|
890
|
-
* @example Grouped destructuring
|
|
891
|
-
* `{ id, name }: { id: string; name: string } = {}`
|
|
892
|
-
*
|
|
893
|
-
* @example Inline (spread as individual parameters)
|
|
894
|
-
* `id: string, name: string`
|
|
895
|
-
*/
|
|
896
|
-
type ParameterGroupNode = BaseNode & {
|
|
743
|
+
type: 'array' | 'tuple';
|
|
897
744
|
/**
|
|
898
|
-
*
|
|
745
|
+
* Item schemas.
|
|
899
746
|
*/
|
|
900
|
-
|
|
747
|
+
items?: Array<SchemaNode>;
|
|
901
748
|
/**
|
|
902
|
-
*
|
|
903
|
-
* Rendered as a destructured object or spread inline when `inline` is `true`.
|
|
749
|
+
* Tuple rest-item schema for elements beyond positional `items`.
|
|
904
750
|
*/
|
|
905
|
-
|
|
751
|
+
rest?: SchemaNode;
|
|
906
752
|
/**
|
|
907
|
-
*
|
|
908
|
-
* When absent, printers auto-compute it from `properties`.
|
|
753
|
+
* Minimum item count (or tuple length).
|
|
909
754
|
*/
|
|
910
|
-
|
|
755
|
+
min?: number;
|
|
911
756
|
/**
|
|
912
|
-
*
|
|
913
|
-
* being wrapped in a single grouped construct.
|
|
914
|
-
*
|
|
915
|
-
* @default false
|
|
757
|
+
* Maximum item count (or tuple length).
|
|
916
758
|
*/
|
|
917
|
-
|
|
759
|
+
max?: number;
|
|
918
760
|
/**
|
|
919
|
-
* Whether
|
|
920
|
-
* If omitted, printers infer this from child properties.
|
|
761
|
+
* Whether all items must be unique.
|
|
921
762
|
*/
|
|
922
|
-
|
|
763
|
+
unique?: boolean;
|
|
764
|
+
};
|
|
765
|
+
/**
|
|
766
|
+
* Shared shape for union and intersection schemas.
|
|
767
|
+
*/
|
|
768
|
+
type CompositeSchemaNodeBase = SchemaNodeBase & {
|
|
923
769
|
/**
|
|
924
|
-
*
|
|
925
|
-
* Commonly `'{}'` to allow omitting the argument entirely.
|
|
770
|
+
* Member schemas.
|
|
926
771
|
*/
|
|
927
|
-
|
|
772
|
+
members?: Array<SchemaNode>;
|
|
928
773
|
};
|
|
929
774
|
/**
|
|
930
|
-
*
|
|
931
|
-
*
|
|
932
|
-
* Printers are responsible for sorting (`required` → `optional` → `defaulted`).
|
|
933
|
-
* Nodes are plain immutable data.
|
|
775
|
+
* Union schema, often from `oneOf` or `anyOf`.
|
|
934
776
|
*
|
|
935
|
-
*
|
|
936
|
-
*
|
|
937
|
-
*
|
|
938
|
-
*
|
|
939
|
-
*
|
|
777
|
+
* @example
|
|
778
|
+
* ```ts
|
|
779
|
+
* const unionSchema: UnionSchemaNode = {
|
|
780
|
+
* kind: 'Schema',
|
|
781
|
+
* type: 'union',
|
|
782
|
+
* members: [],
|
|
783
|
+
* }
|
|
784
|
+
* ```
|
|
940
785
|
*/
|
|
941
|
-
type
|
|
786
|
+
type UnionSchemaNode = CompositeSchemaNodeBase & {
|
|
942
787
|
/**
|
|
943
|
-
*
|
|
788
|
+
* Schema type discriminator.
|
|
944
789
|
*/
|
|
945
|
-
|
|
790
|
+
type: 'union';
|
|
946
791
|
/**
|
|
947
|
-
*
|
|
792
|
+
* Discriminator property name from OpenAPI `discriminator.propertyName`.
|
|
948
793
|
*/
|
|
949
|
-
|
|
794
|
+
discriminatorPropertyName?: string;
|
|
795
|
+
/**
|
|
796
|
+
* Logical strategy applied to union members: 'one' means exactly one member must be valid (from `oneOf`),
|
|
797
|
+
* 'any' means any number of members can be valid (from `anyOf`).
|
|
798
|
+
*/
|
|
799
|
+
strategy?: 'one' | 'any';
|
|
950
800
|
};
|
|
951
801
|
/**
|
|
952
|
-
*
|
|
953
|
-
*/
|
|
954
|
-
type FunctionParamNode = FunctionParameterNode | ParameterGroupNode | FunctionParametersNode | ParamsTypeNode;
|
|
955
|
-
/**
|
|
956
|
-
* Handler map keys — one per `FunctionParamNode` kind.
|
|
957
|
-
*/
|
|
958
|
-
type FunctionNodeType = 'functionParameter' | 'parameterGroup' | 'functionParameters' | 'paramsType';
|
|
959
|
-
//#endregion
|
|
960
|
-
//#region src/nodes/property.d.ts
|
|
961
|
-
/**
|
|
962
|
-
* AST node representing one named object property.
|
|
802
|
+
* Intersection schema, often from `allOf`.
|
|
963
803
|
*
|
|
964
804
|
* @example
|
|
965
805
|
* ```ts
|
|
966
|
-
* const
|
|
967
|
-
* kind: '
|
|
968
|
-
*
|
|
969
|
-
*
|
|
970
|
-
* required: true,
|
|
806
|
+
* const intersectionSchema: IntersectionSchemaNode = {
|
|
807
|
+
* kind: 'Schema',
|
|
808
|
+
* type: 'intersection',
|
|
809
|
+
* members: [],
|
|
971
810
|
* }
|
|
972
811
|
* ```
|
|
973
812
|
*/
|
|
974
|
-
type
|
|
813
|
+
type IntersectionSchemaNode = CompositeSchemaNodeBase & {
|
|
975
814
|
/**
|
|
976
|
-
*
|
|
815
|
+
* Schema type discriminator.
|
|
977
816
|
*/
|
|
978
|
-
|
|
817
|
+
type: 'intersection';
|
|
818
|
+
};
|
|
819
|
+
/**
|
|
820
|
+
* One named enum item.
|
|
821
|
+
*/
|
|
822
|
+
type EnumValueNode = {
|
|
979
823
|
/**
|
|
980
|
-
*
|
|
824
|
+
* Enum item name.
|
|
981
825
|
*/
|
|
982
826
|
name: string;
|
|
983
827
|
/**
|
|
984
|
-
*
|
|
828
|
+
* Enum item value.
|
|
985
829
|
*/
|
|
986
|
-
|
|
830
|
+
value: string | number | boolean;
|
|
987
831
|
/**
|
|
988
|
-
*
|
|
832
|
+
* Primitive type of the enum value.
|
|
989
833
|
*/
|
|
990
|
-
|
|
834
|
+
primitive: Extract<PrimitiveSchemaType, 'string' | 'number' | 'boolean'>;
|
|
991
835
|
};
|
|
992
|
-
//#endregion
|
|
993
|
-
//#region src/nodes/schema.d.ts
|
|
994
|
-
type PrimitiveSchemaType =
|
|
995
|
-
/**
|
|
996
|
-
* Text value.
|
|
997
|
-
*/
|
|
998
|
-
'string'
|
|
999
|
-
/**
|
|
1000
|
-
* Floating-point number.
|
|
1001
|
-
*/
|
|
1002
|
-
| 'number'
|
|
1003
|
-
/**
|
|
1004
|
-
* Integer number.
|
|
1005
|
-
*/
|
|
1006
|
-
| 'integer'
|
|
1007
|
-
/**
|
|
1008
|
-
* Big integer number.
|
|
1009
|
-
*/
|
|
1010
|
-
| 'bigint'
|
|
1011
|
-
/**
|
|
1012
|
-
* Boolean value.
|
|
1013
|
-
*/
|
|
1014
|
-
| 'boolean'
|
|
1015
|
-
/**
|
|
1016
|
-
* Null value.
|
|
1017
|
-
*/
|
|
1018
|
-
| 'null'
|
|
1019
|
-
/**
|
|
1020
|
-
* Any value.
|
|
1021
|
-
*/
|
|
1022
|
-
| 'any'
|
|
1023
|
-
/**
|
|
1024
|
-
* Unknown value.
|
|
1025
|
-
*/
|
|
1026
|
-
| 'unknown'
|
|
1027
|
-
/**
|
|
1028
|
-
* No value (`void`).
|
|
1029
|
-
*/
|
|
1030
|
-
| 'void'
|
|
1031
|
-
/**
|
|
1032
|
-
* Never value.
|
|
1033
|
-
*/
|
|
1034
|
-
| 'never'
|
|
1035
|
-
/**
|
|
1036
|
-
* Object value.
|
|
1037
|
-
*/
|
|
1038
|
-
| 'object'
|
|
1039
|
-
/**
|
|
1040
|
-
* Array value.
|
|
1041
|
-
*/
|
|
1042
|
-
| 'array'
|
|
1043
|
-
/**
|
|
1044
|
-
* Date value.
|
|
1045
|
-
*/
|
|
1046
|
-
| 'date';
|
|
1047
|
-
/**
|
|
1048
|
-
* Composite schema types.
|
|
1049
|
-
*/
|
|
1050
|
-
type ComplexSchemaType = 'tuple' | 'union' | 'intersection' | 'enum';
|
|
1051
|
-
/**
|
|
1052
|
-
* Schema types that need special handling in generators.
|
|
1053
|
-
*/
|
|
1054
|
-
type SpecialSchemaType = 'ref' | 'datetime' | 'time' | 'uuid' | 'email' | 'url' | 'ipv4' | 'ipv6' | 'blob';
|
|
1055
|
-
/**
|
|
1056
|
-
* All schema type strings.
|
|
1057
|
-
*/
|
|
1058
|
-
type SchemaType = PrimitiveSchemaType | ComplexSchemaType | SpecialSchemaType;
|
|
1059
836
|
/**
|
|
1060
|
-
*
|
|
837
|
+
* Enum schema node.
|
|
838
|
+
*
|
|
839
|
+
* @example
|
|
840
|
+
* ```ts
|
|
841
|
+
* const enumSchema: EnumSchemaNode = {
|
|
842
|
+
* kind: 'Schema',
|
|
843
|
+
* type: 'enum',
|
|
844
|
+
* enumValues: ['a', 'b'],
|
|
845
|
+
* }
|
|
846
|
+
* ```
|
|
1061
847
|
*/
|
|
1062
|
-
type
|
|
848
|
+
type EnumSchemaNode = SchemaNodeBase & {
|
|
849
|
+
/**
|
|
850
|
+
* Schema type discriminator.
|
|
851
|
+
*/
|
|
852
|
+
type: 'enum';
|
|
853
|
+
/**
|
|
854
|
+
* Enum values in simple form.
|
|
855
|
+
*/
|
|
856
|
+
enumValues?: Array<string | number | boolean | null>;
|
|
857
|
+
/**
|
|
858
|
+
* Enum values in named form.
|
|
859
|
+
* If present, this is used instead of `enumValues`.
|
|
860
|
+
*/
|
|
861
|
+
namedEnumValues?: Array<EnumValueNode>;
|
|
862
|
+
};
|
|
1063
863
|
/**
|
|
1064
|
-
*
|
|
864
|
+
* Reference schema that points to another schema definition.
|
|
865
|
+
*
|
|
866
|
+
* @example
|
|
867
|
+
* ```ts
|
|
868
|
+
* const refSchema: RefSchemaNode = {
|
|
869
|
+
* kind: 'Schema',
|
|
870
|
+
* type: 'ref',
|
|
871
|
+
* ref: '#/components/schemas/Pet',
|
|
872
|
+
* }
|
|
873
|
+
* ```
|
|
1065
874
|
*/
|
|
1066
|
-
type
|
|
875
|
+
type RefSchemaNode = SchemaNodeBase & {
|
|
1067
876
|
/**
|
|
1068
|
-
*
|
|
877
|
+
* Schema type discriminator.
|
|
1069
878
|
*/
|
|
1070
|
-
|
|
879
|
+
type: 'ref';
|
|
1071
880
|
/**
|
|
1072
|
-
*
|
|
1073
|
-
*
|
|
1074
|
-
* `null` means kubb has processed this and determined there is no applicable name.
|
|
1075
|
-
* `undefined` means the name has not been set yet.
|
|
881
|
+
* Referenced schema name.
|
|
882
|
+
* `null` means Kubb has processed this and determined there is no applicable name.
|
|
1076
883
|
*/
|
|
1077
884
|
name?: string | null;
|
|
1078
885
|
/**
|
|
1079
|
-
*
|
|
886
|
+
* Original `$ref` path, for example, `#/components/schemas/Order`.
|
|
887
|
+
* Used to resolve names later.
|
|
1080
888
|
*/
|
|
1081
|
-
|
|
889
|
+
ref?: string;
|
|
1082
890
|
/**
|
|
1083
|
-
*
|
|
891
|
+
* Pattern copied from a sibling `pattern` field.
|
|
1084
892
|
*/
|
|
1085
|
-
|
|
893
|
+
pattern?: string;
|
|
1086
894
|
/**
|
|
1087
|
-
*
|
|
895
|
+
* The fully-parsed schema that this ref resolves to.
|
|
896
|
+
* Populated during OAS parsing when the referenced definition can be resolved.
|
|
897
|
+
* `null` when the ref cannot be resolved or is part of a circular chain.
|
|
898
|
+
* `undefined` when resolution has not been attempted.
|
|
899
|
+
*
|
|
900
|
+
* Useful for inspecting the referenced schema's structure (e.g. `primitive`, `properties`)
|
|
901
|
+
* without following the reference manually.
|
|
1088
902
|
*/
|
|
1089
|
-
|
|
903
|
+
schema?: SchemaNode | null;
|
|
904
|
+
};
|
|
905
|
+
/**
|
|
906
|
+
* Datetime schema.
|
|
907
|
+
*
|
|
908
|
+
* @example
|
|
909
|
+
* ```ts
|
|
910
|
+
* const datetimeSchema: DatetimeSchemaNode = { kind: 'Schema', type: 'datetime' }
|
|
911
|
+
* ```
|
|
912
|
+
*/
|
|
913
|
+
type DatetimeSchemaNode = SchemaNodeBase & {
|
|
1090
914
|
/**
|
|
1091
|
-
*
|
|
915
|
+
* Schema type discriminator.
|
|
1092
916
|
*/
|
|
1093
|
-
|
|
917
|
+
type: 'datetime';
|
|
1094
918
|
/**
|
|
1095
|
-
*
|
|
919
|
+
* Whether the datetime includes a timezone offset (`dateType: 'stringOffset'`).
|
|
1096
920
|
*/
|
|
1097
|
-
|
|
921
|
+
offset?: boolean;
|
|
1098
922
|
/**
|
|
1099
|
-
* Whether the
|
|
923
|
+
* Whether the datetime is local (no timezone, `dateType: 'stringLocal'`).
|
|
1100
924
|
*/
|
|
1101
|
-
|
|
925
|
+
local?: boolean;
|
|
926
|
+
};
|
|
927
|
+
/**
|
|
928
|
+
* Shared base for `date` and `time` schemas.
|
|
929
|
+
*/
|
|
930
|
+
type TemporalSchemaNodeBase<T extends 'date' | 'time'> = SchemaNodeBase & {
|
|
1102
931
|
/**
|
|
1103
|
-
*
|
|
932
|
+
* Schema type discriminator.
|
|
1104
933
|
*/
|
|
1105
|
-
|
|
934
|
+
type: T;
|
|
935
|
+
/**
|
|
936
|
+
* Output representation in generated code.
|
|
937
|
+
*/
|
|
938
|
+
representation: 'date' | 'string';
|
|
939
|
+
};
|
|
940
|
+
/**
|
|
941
|
+
* Date schema node.
|
|
942
|
+
*
|
|
943
|
+
* @example
|
|
944
|
+
* ```ts
|
|
945
|
+
* const dateSchema: DateSchemaNode = { kind: 'Schema', type: 'date', representation: 'string' }
|
|
946
|
+
* ```
|
|
947
|
+
*/
|
|
948
|
+
type DateSchemaNode = TemporalSchemaNodeBase<'date'>;
|
|
949
|
+
/**
|
|
950
|
+
* Time schema node.
|
|
951
|
+
*
|
|
952
|
+
* @example
|
|
953
|
+
* ```ts
|
|
954
|
+
* const timeSchema: TimeSchemaNode = { kind: 'Schema', type: 'time', representation: 'string' }
|
|
955
|
+
* ```
|
|
956
|
+
*/
|
|
957
|
+
type TimeSchemaNode = TemporalSchemaNodeBase<'time'>;
|
|
958
|
+
/**
|
|
959
|
+
* String schema node.
|
|
960
|
+
*
|
|
961
|
+
* @example
|
|
962
|
+
* ```ts
|
|
963
|
+
* const stringSchema: StringSchemaNode = { kind: 'Schema', type: 'string' }
|
|
964
|
+
* ```
|
|
965
|
+
*/
|
|
966
|
+
type StringSchemaNode = SchemaNodeBase & {
|
|
1106
967
|
/**
|
|
1107
|
-
*
|
|
968
|
+
* Schema type discriminator.
|
|
1108
969
|
*/
|
|
1109
|
-
|
|
970
|
+
type: 'string';
|
|
1110
971
|
/**
|
|
1111
|
-
*
|
|
972
|
+
* Minimum string length.
|
|
1112
973
|
*/
|
|
1113
|
-
|
|
974
|
+
min?: number;
|
|
1114
975
|
/**
|
|
1115
|
-
*
|
|
976
|
+
* Maximum string length.
|
|
1116
977
|
*/
|
|
1117
|
-
|
|
978
|
+
max?: number;
|
|
1118
979
|
/**
|
|
1119
|
-
*
|
|
1120
|
-
* For example, this is `'string'` for a `uuid` schema.
|
|
980
|
+
* Regex pattern.
|
|
1121
981
|
*/
|
|
1122
|
-
|
|
982
|
+
pattern?: string;
|
|
1123
983
|
};
|
|
1124
984
|
/**
|
|
1125
|
-
*
|
|
985
|
+
* Numeric schema (`number`, `integer`, or `bigint`).
|
|
1126
986
|
*
|
|
1127
987
|
* @example
|
|
1128
988
|
* ```ts
|
|
1129
|
-
* const
|
|
1130
|
-
* kind: 'Schema',
|
|
1131
|
-
* type: 'object',
|
|
1132
|
-
* properties: [],
|
|
1133
|
-
* }
|
|
989
|
+
* const numberSchema: NumberSchemaNode = { kind: 'Schema', type: 'number' }
|
|
1134
990
|
* ```
|
|
1135
991
|
*/
|
|
1136
|
-
type
|
|
992
|
+
type NumberSchemaNode = SchemaNodeBase & {
|
|
1137
993
|
/**
|
|
1138
994
|
* Schema type discriminator.
|
|
1139
995
|
*/
|
|
1140
|
-
type: '
|
|
996
|
+
type: 'number' | 'integer' | 'bigint';
|
|
1141
997
|
/**
|
|
1142
|
-
*
|
|
998
|
+
* Minimum value.
|
|
1143
999
|
*/
|
|
1144
|
-
|
|
1000
|
+
min?: number;
|
|
1145
1001
|
/**
|
|
1146
|
-
*
|
|
1002
|
+
* Maximum value.
|
|
1147
1003
|
*/
|
|
1148
|
-
|
|
1004
|
+
max?: number;
|
|
1149
1005
|
/**
|
|
1150
|
-
*
|
|
1151
|
-
* - `true`: allow any value
|
|
1152
|
-
* - `false`: reject unknown properties (maps to `.strict()` in Zod)
|
|
1153
|
-
* - `SchemaNode`: allow values that match that schema
|
|
1154
|
-
* - `undefined`: no additional properties constraint (open object)
|
|
1006
|
+
* Exclusive minimum value.
|
|
1155
1007
|
*/
|
|
1156
|
-
|
|
1008
|
+
exclusiveMinimum?: number;
|
|
1157
1009
|
/**
|
|
1158
|
-
*
|
|
1010
|
+
* Exclusive maximum value.
|
|
1159
1011
|
*/
|
|
1160
|
-
|
|
1012
|
+
exclusiveMaximum?: number;
|
|
1161
1013
|
/**
|
|
1162
|
-
*
|
|
1014
|
+
* The value must be a multiple of this number.
|
|
1163
1015
|
*/
|
|
1164
|
-
|
|
1016
|
+
multipleOf?: number;
|
|
1017
|
+
};
|
|
1018
|
+
/**
|
|
1019
|
+
* Scalar schema with no extra constraints.
|
|
1020
|
+
*
|
|
1021
|
+
* @example
|
|
1022
|
+
* ```ts
|
|
1023
|
+
* const anySchema: ScalarSchemaNode = { kind: 'Schema', type: 'any' }
|
|
1024
|
+
* ```
|
|
1025
|
+
*/
|
|
1026
|
+
type ScalarSchemaNode = SchemaNodeBase & {
|
|
1165
1027
|
/**
|
|
1166
|
-
*
|
|
1028
|
+
* Schema type discriminator.
|
|
1167
1029
|
*/
|
|
1168
|
-
|
|
1030
|
+
type: ScalarSchemaType;
|
|
1169
1031
|
};
|
|
1170
1032
|
/**
|
|
1171
|
-
*
|
|
1033
|
+
* URL schema node.
|
|
1034
|
+
* Can include an OpenAPI-style path template for template literal types.
|
|
1172
1035
|
*
|
|
1173
1036
|
* @example
|
|
1174
1037
|
* ```ts
|
|
1175
|
-
* const
|
|
1176
|
-
* kind: 'Schema',
|
|
1177
|
-
* type: 'array',
|
|
1178
|
-
* items: [],
|
|
1179
|
-
* }
|
|
1038
|
+
* const urlSchema: UrlSchemaNode = { kind: 'Schema', type: 'url', path: '/pets/{petId}' }
|
|
1180
1039
|
* ```
|
|
1181
1040
|
*/
|
|
1182
|
-
type
|
|
1041
|
+
type UrlSchemaNode = SchemaNodeBase & {
|
|
1183
1042
|
/**
|
|
1184
|
-
* Schema type discriminator
|
|
1043
|
+
* Schema type discriminator.
|
|
1185
1044
|
*/
|
|
1186
|
-
type: '
|
|
1045
|
+
type: 'url';
|
|
1187
1046
|
/**
|
|
1188
|
-
*
|
|
1047
|
+
* OpenAPI-style path template, for example, `'/pets/{petId}'`.
|
|
1189
1048
|
*/
|
|
1190
|
-
|
|
1049
|
+
path?: string;
|
|
1191
1050
|
/**
|
|
1192
|
-
*
|
|
1051
|
+
* Minimum string length.
|
|
1193
1052
|
*/
|
|
1194
|
-
|
|
1053
|
+
min?: number;
|
|
1195
1054
|
/**
|
|
1196
|
-
*
|
|
1055
|
+
* Maximum string length.
|
|
1056
|
+
*/
|
|
1057
|
+
max?: number;
|
|
1058
|
+
};
|
|
1059
|
+
/**
|
|
1060
|
+
* Format-string schema for string-based formats that support length constraints.
|
|
1061
|
+
*
|
|
1062
|
+
* @example
|
|
1063
|
+
* ```ts
|
|
1064
|
+
* const uuidSchema: FormatStringSchemaNode = { kind: 'Schema', type: 'uuid', min: 36, max: 36 }
|
|
1065
|
+
* ```
|
|
1066
|
+
*/
|
|
1067
|
+
type FormatStringSchemaNode = SchemaNodeBase & {
|
|
1068
|
+
/**
|
|
1069
|
+
* Schema type discriminator.
|
|
1070
|
+
*/
|
|
1071
|
+
type: 'uuid' | 'email';
|
|
1072
|
+
/**
|
|
1073
|
+
* Minimum string length.
|
|
1197
1074
|
*/
|
|
1198
1075
|
min?: number;
|
|
1199
1076
|
/**
|
|
1200
|
-
* Maximum
|
|
1077
|
+
* Maximum string length.
|
|
1201
1078
|
*/
|
|
1202
1079
|
max?: number;
|
|
1080
|
+
};
|
|
1081
|
+
/**
|
|
1082
|
+
* IPv4 address schema node.
|
|
1083
|
+
*
|
|
1084
|
+
* @example
|
|
1085
|
+
* ```ts
|
|
1086
|
+
* const ipv4Schema: Ipv4SchemaNode = { kind: 'Schema', type: 'ipv4' }
|
|
1087
|
+
* ```
|
|
1088
|
+
*/
|
|
1089
|
+
type Ipv4SchemaNode = SchemaNodeBase & {
|
|
1203
1090
|
/**
|
|
1204
|
-
*
|
|
1091
|
+
* Schema type discriminator.
|
|
1205
1092
|
*/
|
|
1206
|
-
|
|
1093
|
+
type: 'ipv4';
|
|
1207
1094
|
};
|
|
1208
1095
|
/**
|
|
1209
|
-
*
|
|
1096
|
+
* IPv6 address schema node.
|
|
1097
|
+
*
|
|
1098
|
+
* @example
|
|
1099
|
+
* ```ts
|
|
1100
|
+
* const ipv6Schema: Ipv6SchemaNode = { kind: 'Schema', type: 'ipv6' }
|
|
1101
|
+
* ```
|
|
1210
1102
|
*/
|
|
1211
|
-
type
|
|
1103
|
+
type Ipv6SchemaNode = SchemaNodeBase & {
|
|
1212
1104
|
/**
|
|
1213
|
-
*
|
|
1105
|
+
* Schema type discriminator.
|
|
1214
1106
|
*/
|
|
1215
|
-
|
|
1107
|
+
type: 'ipv6';
|
|
1216
1108
|
};
|
|
1217
1109
|
/**
|
|
1218
|
-
*
|
|
1110
|
+
* Mapping from schema type literals to concrete schema node types.
|
|
1111
|
+
* Used by `narrowSchema`.
|
|
1112
|
+
*/
|
|
1113
|
+
type SchemaNodeByType = {
|
|
1114
|
+
object: ObjectSchemaNode;
|
|
1115
|
+
array: ArraySchemaNode;
|
|
1116
|
+
tuple: ArraySchemaNode;
|
|
1117
|
+
union: UnionSchemaNode;
|
|
1118
|
+
intersection: IntersectionSchemaNode;
|
|
1119
|
+
enum: EnumSchemaNode;
|
|
1120
|
+
ref: RefSchemaNode;
|
|
1121
|
+
datetime: DatetimeSchemaNode;
|
|
1122
|
+
date: DateSchemaNode;
|
|
1123
|
+
time: TimeSchemaNode;
|
|
1124
|
+
string: StringSchemaNode;
|
|
1125
|
+
number: NumberSchemaNode;
|
|
1126
|
+
integer: NumberSchemaNode;
|
|
1127
|
+
bigint: NumberSchemaNode;
|
|
1128
|
+
boolean: ScalarSchemaNode;
|
|
1129
|
+
null: ScalarSchemaNode;
|
|
1130
|
+
any: ScalarSchemaNode;
|
|
1131
|
+
unknown: ScalarSchemaNode;
|
|
1132
|
+
void: ScalarSchemaNode;
|
|
1133
|
+
never: ScalarSchemaNode;
|
|
1134
|
+
uuid: FormatStringSchemaNode;
|
|
1135
|
+
email: FormatStringSchemaNode;
|
|
1136
|
+
url: UrlSchemaNode;
|
|
1137
|
+
ipv4: Ipv4SchemaNode;
|
|
1138
|
+
ipv6: Ipv6SchemaNode;
|
|
1139
|
+
blob: ScalarSchemaNode;
|
|
1140
|
+
};
|
|
1141
|
+
/**
|
|
1142
|
+
* Union of all schema node types.
|
|
1143
|
+
*/
|
|
1144
|
+
type SchemaNode = ObjectSchemaNode | ArraySchemaNode | UnionSchemaNode | IntersectionSchemaNode | EnumSchemaNode | RefSchemaNode | DatetimeSchemaNode | DateSchemaNode | TimeSchemaNode | StringSchemaNode | NumberSchemaNode | UrlSchemaNode | FormatStringSchemaNode | Ipv4SchemaNode | Ipv6SchemaNode | ScalarSchemaNode;
|
|
1145
|
+
//#endregion
|
|
1146
|
+
//#region src/nodes/content.d.ts
|
|
1147
|
+
/**
|
|
1148
|
+
* AST node representing one content-type entry of a request body or response.
|
|
1149
|
+
*
|
|
1150
|
+
* One entry per content type declared in the spec (e.g. `application/json`,
|
|
1151
|
+
* `multipart/form-data`), each carrying its own body schema.
|
|
1219
1152
|
*
|
|
1220
1153
|
* @example
|
|
1221
1154
|
* ```ts
|
|
1222
|
-
* const
|
|
1223
|
-
* kind: '
|
|
1224
|
-
*
|
|
1225
|
-
*
|
|
1155
|
+
* const content: ContentNode = {
|
|
1156
|
+
* kind: 'Content',
|
|
1157
|
+
* contentType: 'application/json',
|
|
1158
|
+
* schema: createSchema({ type: 'string' }),
|
|
1226
1159
|
* }
|
|
1227
1160
|
* ```
|
|
1228
1161
|
*/
|
|
1229
|
-
type
|
|
1162
|
+
type ContentNode = BaseNode & {
|
|
1230
1163
|
/**
|
|
1231
|
-
*
|
|
1164
|
+
* Node kind.
|
|
1232
1165
|
*/
|
|
1233
|
-
|
|
1166
|
+
kind: 'Content';
|
|
1234
1167
|
/**
|
|
1235
|
-
*
|
|
1168
|
+
* The content type for this entry (e.g. `'application/json'`).
|
|
1236
1169
|
*/
|
|
1237
|
-
|
|
1170
|
+
contentType: string;
|
|
1238
1171
|
/**
|
|
1239
|
-
*
|
|
1240
|
-
|
|
1172
|
+
* Body schema for this content type.
|
|
1173
|
+
*/
|
|
1174
|
+
schema?: SchemaNode;
|
|
1175
|
+
/**
|
|
1176
|
+
* Property keys to exclude from the generated type via `Omit<Type, Keys>`.
|
|
1177
|
+
* Set when a referenced schema has `readOnly`/`writeOnly` fields that should be omitted.
|
|
1178
|
+
*/
|
|
1179
|
+
keysToOmit?: Array<string> | null;
|
|
1180
|
+
};
|
|
1181
|
+
//#endregion
|
|
1182
|
+
//#region src/nodes/file.d.ts
|
|
1183
|
+
/**
|
|
1184
|
+
* Supported file extensions.
|
|
1185
|
+
*/
|
|
1186
|
+
type Extname = '.ts' | '.js' | '.tsx' | '.json' | `.${string}`;
|
|
1187
|
+
type ImportName = string | Array<string | {
|
|
1188
|
+
propertyName: string;
|
|
1189
|
+
name?: string;
|
|
1190
|
+
}>;
|
|
1191
|
+
/**
|
|
1192
|
+
* Represents a language-agnostic import/dependency declaration.
|
|
1193
|
+
*
|
|
1194
|
+
* @example Named import (TypeScript: `import { useState } from 'react'`)
|
|
1195
|
+
* ```ts
|
|
1196
|
+
* createImport({ name: ['useState'], path: 'react' })
|
|
1197
|
+
* ```
|
|
1198
|
+
*
|
|
1199
|
+
* @example Default import (TypeScript: `import React from 'react'`)
|
|
1200
|
+
* ```ts
|
|
1201
|
+
* createImport({ name: 'React', path: 'react' })
|
|
1202
|
+
* ```
|
|
1203
|
+
*
|
|
1204
|
+
* @example Type-only import (TypeScript: `import type { FC } from 'react'`)
|
|
1205
|
+
* ```ts
|
|
1206
|
+
* createImport({ name: ['FC'], path: 'react', isTypeOnly: true })
|
|
1207
|
+
* ```
|
|
1208
|
+
*
|
|
1209
|
+
* @example Namespace import (TypeScript: `import * as React from 'react'`)
|
|
1210
|
+
* ```ts
|
|
1211
|
+
* createImport({ name: 'React', path: 'react', isNameSpace: true })
|
|
1212
|
+
* ```
|
|
1213
|
+
*/
|
|
1214
|
+
type ImportNode = BaseNode & {
|
|
1215
|
+
kind: 'Import';
|
|
1216
|
+
/**
|
|
1217
|
+
* Import name(s) to be used.
|
|
1218
|
+
* @example ['useState']
|
|
1219
|
+
* @example 'React'
|
|
1220
|
+
*/
|
|
1221
|
+
name: ImportName;
|
|
1222
|
+
/**
|
|
1223
|
+
* Path for the import.
|
|
1224
|
+
* @example '@kubb/core'
|
|
1225
|
+
*/
|
|
1226
|
+
path: string;
|
|
1227
|
+
/**
|
|
1228
|
+
* Add type-only import prefix.
|
|
1229
|
+
* - `true` generates `import type { Type } from './path'`
|
|
1230
|
+
* - `false` generates `import { Type } from './path'`
|
|
1231
|
+
* @default false
|
|
1232
|
+
*/
|
|
1233
|
+
isTypeOnly?: boolean | null;
|
|
1234
|
+
/**
|
|
1235
|
+
* Import entire module as namespace.
|
|
1236
|
+
* - `true` generates `import * as Name from './path'`
|
|
1237
|
+
* - `false` generates standard import
|
|
1238
|
+
* @default false
|
|
1239
|
+
*/
|
|
1240
|
+
isNameSpace?: boolean | null;
|
|
1241
|
+
/**
|
|
1242
|
+
* When set, the import path is resolved relative to this root.
|
|
1241
1243
|
*/
|
|
1242
|
-
|
|
1244
|
+
root?: string | null;
|
|
1243
1245
|
};
|
|
1244
1246
|
/**
|
|
1245
|
-
*
|
|
1247
|
+
* Represents a language-agnostic export/public API declaration.
|
|
1246
1248
|
*
|
|
1247
|
-
* @example
|
|
1249
|
+
* @example Named export (TypeScript: `export { Pets } from './Pets'`)
|
|
1248
1250
|
* ```ts
|
|
1249
|
-
*
|
|
1250
|
-
*
|
|
1251
|
-
*
|
|
1252
|
-
*
|
|
1253
|
-
*
|
|
1251
|
+
* createExport({ name: ['Pets'], path: './Pets' })
|
|
1252
|
+
* ```
|
|
1253
|
+
*
|
|
1254
|
+
* @example Type-only export (TypeScript: `export type { Pet } from './Pet'`)
|
|
1255
|
+
* ```ts
|
|
1256
|
+
* createExport({ name: ['Pet'], path: './Pet', isTypeOnly: true })
|
|
1257
|
+
* ```
|
|
1258
|
+
*
|
|
1259
|
+
* @example Wildcard export (TypeScript: `export * from './utils'`)
|
|
1260
|
+
* ```ts
|
|
1261
|
+
* createExport({ path: './utils' })
|
|
1262
|
+
* ```
|
|
1263
|
+
*
|
|
1264
|
+
* @example Namespace alias (TypeScript: `export * as utils from './utils'`)
|
|
1265
|
+
* ```ts
|
|
1266
|
+
* createExport({ name: 'utils', path: './utils', asAlias: true })
|
|
1254
1267
|
* ```
|
|
1255
1268
|
*/
|
|
1256
|
-
type
|
|
1269
|
+
type ExportNode = BaseNode & {
|
|
1270
|
+
kind: 'Export';
|
|
1257
1271
|
/**
|
|
1258
|
-
*
|
|
1272
|
+
* Export name(s) to be used. When omitted, generates a wildcard export.
|
|
1273
|
+
* @example ['useState']
|
|
1274
|
+
* @example 'React'
|
|
1259
1275
|
*/
|
|
1260
|
-
|
|
1261
|
-
};
|
|
1262
|
-
/**
|
|
1263
|
-
* One named enum item.
|
|
1264
|
-
*/
|
|
1265
|
-
type EnumValueNode = {
|
|
1276
|
+
name?: string | Array<string> | null;
|
|
1266
1277
|
/**
|
|
1267
|
-
*
|
|
1278
|
+
* Path for the export.
|
|
1279
|
+
* @example '@kubb/core'
|
|
1268
1280
|
*/
|
|
1269
|
-
|
|
1281
|
+
path: string;
|
|
1270
1282
|
/**
|
|
1271
|
-
*
|
|
1283
|
+
* Add type-only export prefix.
|
|
1284
|
+
* - `true` generates `export type { Type } from './path'`
|
|
1285
|
+
* - `false` generates `export { Type } from './path'`
|
|
1286
|
+
* @default false
|
|
1272
1287
|
*/
|
|
1273
|
-
|
|
1288
|
+
isTypeOnly?: boolean | null;
|
|
1274
1289
|
/**
|
|
1275
|
-
*
|
|
1290
|
+
* Export as an aliased namespace.
|
|
1291
|
+
* - `true` generates `export * as aliasName from './path'`
|
|
1292
|
+
* - `false` generates a standard export
|
|
1293
|
+
* @default false
|
|
1276
1294
|
*/
|
|
1277
|
-
|
|
1295
|
+
asAlias?: boolean | null;
|
|
1278
1296
|
};
|
|
1279
1297
|
/**
|
|
1280
|
-
*
|
|
1298
|
+
* Represents a fragment of source code within a file.
|
|
1281
1299
|
*
|
|
1282
|
-
* @example
|
|
1300
|
+
* @example Named exportable source
|
|
1283
1301
|
* ```ts
|
|
1284
|
-
*
|
|
1285
|
-
*
|
|
1286
|
-
*
|
|
1287
|
-
*
|
|
1288
|
-
*
|
|
1302
|
+
* createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true, isIndexable: true })
|
|
1303
|
+
* ```
|
|
1304
|
+
*
|
|
1305
|
+
* @example Inline unnamed code block
|
|
1306
|
+
* ```ts
|
|
1307
|
+
* createSource({ nodes: [createText('const x = 1')] })
|
|
1289
1308
|
* ```
|
|
1290
1309
|
*/
|
|
1291
|
-
type
|
|
1310
|
+
type SourceNode = BaseNode & {
|
|
1311
|
+
kind: 'Source';
|
|
1292
1312
|
/**
|
|
1293
|
-
*
|
|
1313
|
+
* Optional name identifying this source (used for deduplication and barrel generation).
|
|
1294
1314
|
*/
|
|
1295
|
-
|
|
1315
|
+
name?: string | null;
|
|
1296
1316
|
/**
|
|
1297
|
-
*
|
|
1317
|
+
* Mark this source as a type-only export.
|
|
1318
|
+
* @default false
|
|
1298
1319
|
*/
|
|
1299
|
-
|
|
1320
|
+
isTypeOnly?: boolean | null;
|
|
1300
1321
|
/**
|
|
1301
|
-
*
|
|
1302
|
-
*
|
|
1322
|
+
* Include `export` keyword in the generated source.
|
|
1323
|
+
* @default false
|
|
1303
1324
|
*/
|
|
1304
|
-
|
|
1325
|
+
isExportable?: boolean | null;
|
|
1326
|
+
/**
|
|
1327
|
+
* Include this source in barrel/index file generation.
|
|
1328
|
+
* @default false
|
|
1329
|
+
*/
|
|
1330
|
+
isIndexable?: boolean | null;
|
|
1331
|
+
/**
|
|
1332
|
+
* Structured child nodes representing the content of this source fragment, in DOM order.
|
|
1333
|
+
* Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
|
|
1334
|
+
*/
|
|
1335
|
+
nodes?: Array<CodeNode>;
|
|
1305
1336
|
};
|
|
1306
1337
|
/**
|
|
1307
|
-
*
|
|
1338
|
+
* Represents a fully resolved file in the AST.
|
|
1339
|
+
*
|
|
1340
|
+
* Created via `createFile()`, which computes the `id`, `name`, and `extname` from the input
|
|
1341
|
+
* and deduplicates `imports`, `exports`, and `sources`.
|
|
1308
1342
|
*
|
|
1309
1343
|
* @example
|
|
1310
1344
|
* ```ts
|
|
1311
|
-
* const
|
|
1312
|
-
*
|
|
1313
|
-
*
|
|
1314
|
-
*
|
|
1315
|
-
* }
|
|
1345
|
+
* const file = createFile({
|
|
1346
|
+
* baseName: 'petStore.ts',
|
|
1347
|
+
* path: 'src/models/petStore.ts',
|
|
1348
|
+
* sources: [createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true })],
|
|
1349
|
+
* imports: [createImport({ name: ['z'], path: 'zod' })],
|
|
1350
|
+
* exports: [createExport({ name: ['Pet'], path: './petStore' })],
|
|
1351
|
+
* })
|
|
1352
|
+
* // file.id = SHA256 hash of the path
|
|
1353
|
+
* // file.name = 'petStore'
|
|
1354
|
+
* // file.extname = '.ts'
|
|
1316
1355
|
* ```
|
|
1317
1356
|
*/
|
|
1318
|
-
type
|
|
1357
|
+
type FileNode<TMeta extends object = object> = BaseNode & {
|
|
1358
|
+
kind: 'File';
|
|
1319
1359
|
/**
|
|
1320
|
-
*
|
|
1360
|
+
* Unique identifier derived from a SHA256 hash of the file path. Computed
|
|
1361
|
+
* by `createFile`; callers do not need to provide it.
|
|
1321
1362
|
*/
|
|
1322
|
-
|
|
1363
|
+
id: string;
|
|
1323
1364
|
/**
|
|
1324
|
-
*
|
|
1365
|
+
* File name without extension, derived from `baseName`.
|
|
1366
|
+
* @link https://nodejs.org/api/path.html#pathformatpathobject
|
|
1325
1367
|
*/
|
|
1326
|
-
name
|
|
1368
|
+
name: string;
|
|
1327
1369
|
/**
|
|
1328
|
-
*
|
|
1329
|
-
*
|
|
1370
|
+
* File base name, including extension.
|
|
1371
|
+
* Based on UNIX basename: `${name}${extname}`
|
|
1372
|
+
* @link https://nodejs.org/api/path.html#pathbasenamepath-suffix
|
|
1330
1373
|
*/
|
|
1331
|
-
|
|
1374
|
+
baseName: `${string}.${string}`;
|
|
1332
1375
|
/**
|
|
1333
|
-
*
|
|
1376
|
+
* Full qualified path to the file.
|
|
1334
1377
|
*/
|
|
1335
|
-
|
|
1378
|
+
path: string;
|
|
1336
1379
|
/**
|
|
1337
|
-
*
|
|
1338
|
-
* Populated during OAS parsing when the referenced definition can be resolved.
|
|
1339
|
-
* `undefined` when the ref cannot be resolved or is part of a circular chain.
|
|
1340
|
-
*
|
|
1341
|
-
* Useful for inspecting the referenced schema's structure (e.g. `primitive`, `properties`)
|
|
1342
|
-
* without following the reference manually.
|
|
1380
|
+
* File extension extracted from `baseName`.
|
|
1343
1381
|
*/
|
|
1344
|
-
|
|
1345
|
-
};
|
|
1346
|
-
/**
|
|
1347
|
-
* Datetime schema.
|
|
1348
|
-
*
|
|
1349
|
-
* @example
|
|
1350
|
-
* ```ts
|
|
1351
|
-
* const datetimeSchema: DatetimeSchemaNode = { kind: 'Schema', type: 'datetime' }
|
|
1352
|
-
* ```
|
|
1353
|
-
*/
|
|
1354
|
-
type DatetimeSchemaNode = SchemaNodeBase & {
|
|
1382
|
+
extname: Extname;
|
|
1355
1383
|
/**
|
|
1356
|
-
*
|
|
1384
|
+
* Deduplicated list of source code fragments.
|
|
1357
1385
|
*/
|
|
1358
|
-
|
|
1386
|
+
sources: Array<SourceNode>;
|
|
1359
1387
|
/**
|
|
1360
|
-
*
|
|
1388
|
+
* Deduplicated list of import declarations.
|
|
1361
1389
|
*/
|
|
1362
|
-
|
|
1390
|
+
imports: Array<ImportNode>;
|
|
1363
1391
|
/**
|
|
1364
|
-
*
|
|
1392
|
+
* Deduplicated list of export declarations.
|
|
1365
1393
|
*/
|
|
1366
|
-
|
|
1367
|
-
};
|
|
1368
|
-
/**
|
|
1369
|
-
* Shared base for `date` and `time` schemas.
|
|
1370
|
-
*/
|
|
1371
|
-
type TemporalSchemaNodeBase<T extends 'date' | 'time'> = SchemaNodeBase & {
|
|
1394
|
+
exports: Array<ExportNode>;
|
|
1372
1395
|
/**
|
|
1373
|
-
*
|
|
1396
|
+
* Optional metadata attached to this file (used by plugins for barrel generation etc.).
|
|
1374
1397
|
*/
|
|
1375
|
-
|
|
1398
|
+
meta?: TMeta;
|
|
1376
1399
|
/**
|
|
1377
|
-
*
|
|
1400
|
+
* Optional banner prepended to the generated file content.
|
|
1401
|
+
* Accepts `null` so `resolver.resolveBanner()` results can be passed directly.
|
|
1378
1402
|
*/
|
|
1379
|
-
|
|
1403
|
+
banner?: string | null;
|
|
1404
|
+
/**
|
|
1405
|
+
* Optional footer appended to the generated file content.
|
|
1406
|
+
* Accepts `null` so `resolver.resolveFooter()` results can be passed directly.
|
|
1407
|
+
*/
|
|
1408
|
+
footer?: string | null;
|
|
1380
1409
|
};
|
|
1410
|
+
//#endregion
|
|
1411
|
+
//#region src/nodes/function.d.ts
|
|
1381
1412
|
/**
|
|
1382
|
-
*
|
|
1413
|
+
* AST node representing a language-agnostic type expression used as a function parameter
|
|
1414
|
+
* type annotation. Each language printer renders the variant into its own syntax.
|
|
1383
1415
|
*
|
|
1384
|
-
*
|
|
1416
|
+
* - `struct` — an inline anonymous type grouping named fields.
|
|
1417
|
+
* TypeScript renders as `{ petId: string; name?: string }`.
|
|
1418
|
+
* - `member` — a single named field accessed from a named group type.
|
|
1419
|
+
* TypeScript renders as `PathParams['petId']`.
|
|
1420
|
+
*
|
|
1421
|
+
* @example Reference variant
|
|
1385
1422
|
* ```ts
|
|
1386
|
-
*
|
|
1423
|
+
* createParamsType({ variant: 'reference', name: 'QueryParams' })
|
|
1424
|
+
* // QueryParams
|
|
1387
1425
|
* ```
|
|
1388
|
-
*/
|
|
1389
|
-
type DateSchemaNode = TemporalSchemaNodeBase<'date'>;
|
|
1390
|
-
/**
|
|
1391
|
-
* Time schema node.
|
|
1392
1426
|
*
|
|
1393
|
-
* @example
|
|
1427
|
+
* @example Struct variant
|
|
1394
1428
|
* ```ts
|
|
1395
|
-
*
|
|
1429
|
+
* createParamsType({ variant: 'struct', properties: [{ name: 'petId', optional: false, type: createParamsType({ variant: 'reference', name: 'string' }) }] })
|
|
1430
|
+
* // { petId: string }
|
|
1396
1431
|
* ```
|
|
1397
|
-
*/
|
|
1398
|
-
type TimeSchemaNode = TemporalSchemaNodeBase<'time'>;
|
|
1399
|
-
/**
|
|
1400
|
-
* String schema node.
|
|
1401
1432
|
*
|
|
1402
|
-
* @example
|
|
1433
|
+
* @example Member variant
|
|
1403
1434
|
* ```ts
|
|
1404
|
-
*
|
|
1435
|
+
* createParamsType({ variant: 'member', base: 'PathParams', key: 'petId' })
|
|
1436
|
+
* // PathParams['petId']
|
|
1405
1437
|
* ```
|
|
1406
1438
|
*/
|
|
1407
|
-
type
|
|
1439
|
+
type ParamsTypeNode = BaseNode & {
|
|
1408
1440
|
/**
|
|
1409
|
-
*
|
|
1441
|
+
* Node kind.
|
|
1410
1442
|
*/
|
|
1411
|
-
|
|
1443
|
+
kind: 'ParamsType';
|
|
1444
|
+
} & ({
|
|
1412
1445
|
/**
|
|
1413
|
-
*
|
|
1446
|
+
* Reference variant — a plain type name or identifier.
|
|
1447
|
+
* TypeScript renders as-is, e.g. `string`, `QueryParams`, `Partial<Config>`.
|
|
1414
1448
|
*/
|
|
1415
|
-
|
|
1449
|
+
variant: 'reference';
|
|
1416
1450
|
/**
|
|
1417
|
-
*
|
|
1451
|
+
* The full type name string, e.g. `'string'`, `'QueryParams'`, `'Partial<Config>'`.
|
|
1418
1452
|
*/
|
|
1419
|
-
|
|
1453
|
+
name: string;
|
|
1454
|
+
} | {
|
|
1455
|
+
/**
|
|
1456
|
+
* Struct variant — an inline anonymous type grouping named fields.
|
|
1457
|
+
* TypeScript renders as `{ key: Type; other?: OtherType }`.
|
|
1458
|
+
*/
|
|
1459
|
+
variant: 'struct';
|
|
1460
|
+
/**
|
|
1461
|
+
* Properties of the struct type.
|
|
1462
|
+
*/
|
|
1463
|
+
properties: Array<{
|
|
1464
|
+
name: string;
|
|
1465
|
+
optional: boolean;
|
|
1466
|
+
type: ParamsTypeNode;
|
|
1467
|
+
}>;
|
|
1468
|
+
} | {
|
|
1469
|
+
/**
|
|
1470
|
+
* Member variant — a single named field accessed from a group type.
|
|
1471
|
+
* TypeScript renders as `Base['key']`.
|
|
1472
|
+
*/
|
|
1473
|
+
variant: 'member';
|
|
1474
|
+
/**
|
|
1475
|
+
* Base type name, e.g. `'DeletePetPathParams'`.
|
|
1476
|
+
*/
|
|
1477
|
+
base: string;
|
|
1420
1478
|
/**
|
|
1421
|
-
*
|
|
1479
|
+
* The field name to access, e.g. `'petId'`.
|
|
1422
1480
|
*/
|
|
1423
|
-
|
|
1424
|
-
};
|
|
1481
|
+
key: string;
|
|
1482
|
+
});
|
|
1425
1483
|
/**
|
|
1426
|
-
*
|
|
1484
|
+
* AST node for one function parameter.
|
|
1427
1485
|
*
|
|
1428
|
-
* @example
|
|
1429
|
-
*
|
|
1430
|
-
*
|
|
1431
|
-
*
|
|
1486
|
+
* @example Required parameter
|
|
1487
|
+
* `name: Type`
|
|
1488
|
+
*
|
|
1489
|
+
* @example Optional parameter
|
|
1490
|
+
* `name?: Type`
|
|
1491
|
+
*
|
|
1492
|
+
* @example Parameter with default value
|
|
1493
|
+
* `name: Type = defaultValue`
|
|
1494
|
+
*
|
|
1495
|
+
* @example Rest parameter
|
|
1496
|
+
* `...name: Type[]`
|
|
1432
1497
|
*/
|
|
1433
|
-
type
|
|
1434
|
-
/**
|
|
1435
|
-
* Schema type discriminator.
|
|
1436
|
-
*/
|
|
1437
|
-
type: 'number' | 'integer' | 'bigint';
|
|
1438
|
-
/**
|
|
1439
|
-
* Minimum value.
|
|
1440
|
-
*/
|
|
1441
|
-
min?: number;
|
|
1498
|
+
type FunctionParameterNode = BaseNode & {
|
|
1442
1499
|
/**
|
|
1443
|
-
*
|
|
1500
|
+
* Node kind.
|
|
1444
1501
|
*/
|
|
1445
|
-
|
|
1502
|
+
kind: 'FunctionParameter';
|
|
1446
1503
|
/**
|
|
1447
|
-
*
|
|
1504
|
+
* Parameter name in the generated signature.
|
|
1448
1505
|
*/
|
|
1449
|
-
|
|
1506
|
+
name: string;
|
|
1450
1507
|
/**
|
|
1451
|
-
*
|
|
1508
|
+
* Type annotation as a structured {@link ParamsTypeNode}.
|
|
1509
|
+
* Omit for untyped output.
|
|
1510
|
+
*
|
|
1511
|
+
* @example Reference type node
|
|
1512
|
+
* `{ kind: 'ParamsType', variant: 'reference', name: 'string' }` → `petId: string`
|
|
1513
|
+
*
|
|
1514
|
+
* @example Struct type node
|
|
1515
|
+
* `{ kind: 'ParamsType', variant: 'struct', properties: [...] }` → `{ key: Type; other?: OtherType }`
|
|
1516
|
+
*
|
|
1517
|
+
* @example Member type node
|
|
1518
|
+
* `{ kind: 'ParamsType', variant: 'member', base: 'PathParams', key: 'petId' }` → `PathParams['petId']`
|
|
1452
1519
|
*/
|
|
1453
|
-
|
|
1520
|
+
type?: ParamsTypeNode;
|
|
1454
1521
|
/**
|
|
1455
|
-
*
|
|
1522
|
+
* When `true` the parameter is emitted as a rest parameter.
|
|
1523
|
+
*
|
|
1524
|
+
* @example Rest parameter
|
|
1525
|
+
* `...name: Type[]`
|
|
1456
1526
|
*/
|
|
1457
|
-
|
|
1458
|
-
}
|
|
1527
|
+
rest?: boolean;
|
|
1528
|
+
}
|
|
1459
1529
|
/**
|
|
1460
|
-
|
|
1530
|
+
* Optional parameter — rendered with `?` and may be omitted by the caller.
|
|
1531
|
+
* Cannot be combined with `default` because a defaulted parameter is already optional.
|
|
1532
|
+
*/
|
|
1533
|
+
& ({
|
|
1534
|
+
optional: true;
|
|
1535
|
+
default?: never;
|
|
1536
|
+
}
|
|
1537
|
+
/**
|
|
1538
|
+
* Required parameter, or a parameter with a default value.
|
|
1461
1539
|
*
|
|
1462
|
-
* @example
|
|
1463
|
-
*
|
|
1464
|
-
*
|
|
1465
|
-
*
|
|
1540
|
+
* @example Required
|
|
1541
|
+
* `name: Type`
|
|
1542
|
+
*
|
|
1543
|
+
* @example With default
|
|
1544
|
+
* `name: Type = default`
|
|
1466
1545
|
*/
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
type: ScalarSchemaType;
|
|
1472
|
-
};
|
|
1546
|
+
| {
|
|
1547
|
+
optional?: false;
|
|
1548
|
+
default?: string;
|
|
1549
|
+
});
|
|
1473
1550
|
/**
|
|
1474
|
-
*
|
|
1475
|
-
* Can include an OpenAPI-style path template for template literal types.
|
|
1551
|
+
* AST node for a group of related function parameters treated as a single unit.
|
|
1476
1552
|
*
|
|
1477
|
-
*
|
|
1478
|
-
*
|
|
1479
|
-
*
|
|
1480
|
-
*
|
|
1553
|
+
* Each language printer decides how to render this group:
|
|
1554
|
+
* - TypeScript/JS: destructured object `{ key1, key2 }: { key1: Type1; key2: Type2 } = {}`
|
|
1555
|
+
* - Python: keyword-only args or a typed dict parameter
|
|
1556
|
+
* - C# / Kotlin: named record / data-class parameter
|
|
1557
|
+
*
|
|
1558
|
+
* When `inline` is `true`, the group is spread as individual top-level parameters
|
|
1559
|
+
* rather than wrapped in a single grouped construct.
|
|
1560
|
+
*
|
|
1561
|
+
* @example Grouped destructuring
|
|
1562
|
+
* `{ id, name }: { id: string; name: string } = {}`
|
|
1563
|
+
*
|
|
1564
|
+
* @example Inline (spread as individual parameters)
|
|
1565
|
+
* `id: string, name: string`
|
|
1481
1566
|
*/
|
|
1482
|
-
type
|
|
1483
|
-
/**
|
|
1484
|
-
* Schema type discriminator.
|
|
1485
|
-
*/
|
|
1486
|
-
type: 'url';
|
|
1567
|
+
type ParameterGroupNode = BaseNode & {
|
|
1487
1568
|
/**
|
|
1488
|
-
*
|
|
1569
|
+
* Node kind.
|
|
1489
1570
|
*/
|
|
1490
|
-
|
|
1571
|
+
kind: 'ParameterGroup';
|
|
1491
1572
|
/**
|
|
1492
|
-
*
|
|
1573
|
+
* The individual parameters that form the group.
|
|
1574
|
+
* Rendered as a destructured object or spread inline when `inline` is `true`.
|
|
1493
1575
|
*/
|
|
1494
|
-
|
|
1576
|
+
properties: Array<FunctionParameterNode>;
|
|
1495
1577
|
/**
|
|
1496
|
-
*
|
|
1578
|
+
* Optional explicit type annotation for the whole group.
|
|
1579
|
+
* When absent, printers auto-compute it from `properties`.
|
|
1497
1580
|
*/
|
|
1498
|
-
|
|
1499
|
-
};
|
|
1500
|
-
/**
|
|
1501
|
-
* Format-string schema for string-based formats that support length constraints.
|
|
1502
|
-
*
|
|
1503
|
-
* @example
|
|
1504
|
-
* ```ts
|
|
1505
|
-
* const uuidSchema: FormatStringSchemaNode = { kind: 'Schema', type: 'uuid', min: 36, max: 36 }
|
|
1506
|
-
* ```
|
|
1507
|
-
*/
|
|
1508
|
-
type FormatStringSchemaNode = SchemaNodeBase & {
|
|
1581
|
+
type?: ParamsTypeNode;
|
|
1509
1582
|
/**
|
|
1510
|
-
*
|
|
1583
|
+
* When `true`, `properties` are emitted as individual top-level parameters instead of
|
|
1584
|
+
* being wrapped in a single grouped construct.
|
|
1585
|
+
*
|
|
1586
|
+
* @default false
|
|
1511
1587
|
*/
|
|
1512
|
-
|
|
1588
|
+
inline?: boolean;
|
|
1513
1589
|
/**
|
|
1514
|
-
*
|
|
1590
|
+
* Whether the group as a whole is optional.
|
|
1591
|
+
* If omitted, printers infer this from child properties.
|
|
1515
1592
|
*/
|
|
1516
|
-
|
|
1593
|
+
optional?: boolean;
|
|
1517
1594
|
/**
|
|
1518
|
-
*
|
|
1595
|
+
* Default value for the group, written verbatim after `=`.
|
|
1596
|
+
* Commonly `'{}'` to allow omitting the argument entirely.
|
|
1519
1597
|
*/
|
|
1520
|
-
|
|
1598
|
+
default?: string;
|
|
1521
1599
|
};
|
|
1522
1600
|
/**
|
|
1523
|
-
*
|
|
1601
|
+
* AST node for a complete function parameter list.
|
|
1524
1602
|
*
|
|
1525
|
-
*
|
|
1526
|
-
*
|
|
1527
|
-
*
|
|
1528
|
-
*
|
|
1603
|
+
* Printers are responsible for sorting (`required` → `optional` → `defaulted`).
|
|
1604
|
+
* Nodes are plain immutable data.
|
|
1605
|
+
*
|
|
1606
|
+
* Renders differently depending on the output mode:
|
|
1607
|
+
* - `declaration` → `(id: string, config: Config = {})` — function declaration parameters
|
|
1608
|
+
* - `call` → `(id, { method, url })` — function call arguments
|
|
1609
|
+
* - `keys` → `{ id, config }` — key names only (for destructuring)
|
|
1610
|
+
* - `values` → `{ id: id, config: config }` — key → value pairs
|
|
1529
1611
|
*/
|
|
1530
|
-
type
|
|
1612
|
+
type FunctionParametersNode = BaseNode & {
|
|
1531
1613
|
/**
|
|
1532
|
-
*
|
|
1614
|
+
* Node kind.
|
|
1533
1615
|
*/
|
|
1534
|
-
|
|
1535
|
-
};
|
|
1536
|
-
/**
|
|
1537
|
-
* IPv6 address schema node.
|
|
1538
|
-
*
|
|
1539
|
-
* @example
|
|
1540
|
-
* ```ts
|
|
1541
|
-
* const ipv6Schema: Ipv6SchemaNode = { kind: 'Schema', type: 'ipv6' }
|
|
1542
|
-
* ```
|
|
1543
|
-
*/
|
|
1544
|
-
type Ipv6SchemaNode = SchemaNodeBase & {
|
|
1616
|
+
kind: 'FunctionParameters';
|
|
1545
1617
|
/**
|
|
1546
|
-
*
|
|
1618
|
+
* Ordered parameter nodes.
|
|
1547
1619
|
*/
|
|
1548
|
-
|
|
1620
|
+
params: ReadonlyArray<FunctionParameterNode | ParameterGroupNode>;
|
|
1549
1621
|
};
|
|
1550
1622
|
/**
|
|
1551
|
-
*
|
|
1552
|
-
* Used by `narrowSchema`.
|
|
1623
|
+
* Union of all function-parameter AST node variants used by the function-parameter printer.
|
|
1553
1624
|
*/
|
|
1554
|
-
type
|
|
1555
|
-
object: ObjectSchemaNode;
|
|
1556
|
-
array: ArraySchemaNode;
|
|
1557
|
-
tuple: ArraySchemaNode;
|
|
1558
|
-
union: UnionSchemaNode;
|
|
1559
|
-
intersection: IntersectionSchemaNode;
|
|
1560
|
-
enum: EnumSchemaNode;
|
|
1561
|
-
ref: RefSchemaNode;
|
|
1562
|
-
datetime: DatetimeSchemaNode;
|
|
1563
|
-
date: DateSchemaNode;
|
|
1564
|
-
time: TimeSchemaNode;
|
|
1565
|
-
string: StringSchemaNode;
|
|
1566
|
-
number: NumberSchemaNode;
|
|
1567
|
-
integer: NumberSchemaNode;
|
|
1568
|
-
bigint: NumberSchemaNode;
|
|
1569
|
-
boolean: ScalarSchemaNode;
|
|
1570
|
-
null: ScalarSchemaNode;
|
|
1571
|
-
any: ScalarSchemaNode;
|
|
1572
|
-
unknown: ScalarSchemaNode;
|
|
1573
|
-
void: ScalarSchemaNode;
|
|
1574
|
-
never: ScalarSchemaNode;
|
|
1575
|
-
uuid: FormatStringSchemaNode;
|
|
1576
|
-
email: FormatStringSchemaNode;
|
|
1577
|
-
url: UrlSchemaNode;
|
|
1578
|
-
ipv4: Ipv4SchemaNode;
|
|
1579
|
-
ipv6: Ipv6SchemaNode;
|
|
1580
|
-
blob: ScalarSchemaNode;
|
|
1581
|
-
};
|
|
1625
|
+
type FunctionParamNode = FunctionParameterNode | ParameterGroupNode | FunctionParametersNode | ParamsTypeNode;
|
|
1582
1626
|
/**
|
|
1583
|
-
*
|
|
1627
|
+
* Handler map keys — one per `FunctionParamNode` kind.
|
|
1584
1628
|
*/
|
|
1585
|
-
type
|
|
1629
|
+
type FunctionNodeType = 'functionParameter' | 'parameterGroup' | 'functionParameters' | 'paramsType';
|
|
1586
1630
|
//#endregion
|
|
1587
1631
|
//#region src/nodes/parameter.d.ts
|
|
1588
1632
|
type ParameterLocation = 'path' | 'query' | 'header' | 'cookie';
|
|
@@ -1655,12 +1699,16 @@ type MediaType = 'application/json' | 'application/xml' | 'application/x-www-for
|
|
|
1655
1699
|
/**
|
|
1656
1700
|
* AST node representing one operation response variant.
|
|
1657
1701
|
*
|
|
1702
|
+
* Mirrors {@link OperationNode.requestBody}: the response body schemas live exclusively inside
|
|
1703
|
+
* the `content` array (one entry per content type), so the same schema is never duplicated at the
|
|
1704
|
+
* node root and inside `content`.
|
|
1705
|
+
*
|
|
1658
1706
|
* @example
|
|
1659
1707
|
* ```ts
|
|
1660
1708
|
* const response: ResponseNode = {
|
|
1661
1709
|
* kind: 'Response',
|
|
1662
1710
|
* statusCode: '200',
|
|
1663
|
-
* schema: createSchema({ type: 'string' }),
|
|
1711
|
+
* content: [{ contentType: 'application/json', schema: createSchema({ type: 'string' }) }],
|
|
1664
1712
|
* }
|
|
1665
1713
|
* ```
|
|
1666
1714
|
*/
|
|
@@ -1678,56 +1726,80 @@ type ResponseNode = BaseNode & {
|
|
|
1678
1726
|
*/
|
|
1679
1727
|
description?: string;
|
|
1680
1728
|
/**
|
|
1681
|
-
*
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
*
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
*
|
|
1690
|
-
*
|
|
1729
|
+
* All available content type entries for this response.
|
|
1730
|
+
*
|
|
1731
|
+
* When the adapter `contentType` option is set, this array contains exactly one entry for that
|
|
1732
|
+
* content type. Otherwise it contains one entry per content type declared in the spec, so that
|
|
1733
|
+
* plugins can generate a union of response types (e.g. `application/json` and `application/xml`).
|
|
1734
|
+
* Body-less responses keep a single entry whose `schema` is the empty/`void` placeholder.
|
|
1735
|
+
*
|
|
1736
|
+
* @example
|
|
1737
|
+
* ```ts
|
|
1738
|
+
* // spec response declares both application/json and application/xml
|
|
1739
|
+
* response.content[0].contentType // 'application/json'
|
|
1740
|
+
* response.content[1].contentType // 'application/xml'
|
|
1741
|
+
* ```
|
|
1691
1742
|
*/
|
|
1692
|
-
|
|
1743
|
+
content?: Array<ContentNode>;
|
|
1693
1744
|
};
|
|
1694
1745
|
//#endregion
|
|
1695
1746
|
//#region src/nodes/operation.d.ts
|
|
1696
1747
|
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'TRACE';
|
|
1697
1748
|
/**
|
|
1698
|
-
*
|
|
1749
|
+
* Transport an operation belongs to.
|
|
1750
|
+
*/
|
|
1751
|
+
type OperationProtocol = 'http';
|
|
1752
|
+
/**
|
|
1753
|
+
* AST node representing an operation request body.
|
|
1699
1754
|
*
|
|
1700
|
-
*
|
|
1701
|
-
*
|
|
1702
|
-
*
|
|
1703
|
-
*
|
|
1704
|
-
*
|
|
1705
|
-
*
|
|
1706
|
-
*
|
|
1707
|
-
*
|
|
1708
|
-
*
|
|
1709
|
-
* responses: [],
|
|
1755
|
+
* Body schemas live exclusively inside the `content` array (one entry per content type),
|
|
1756
|
+
* mirroring {@link ResponseNode}.
|
|
1757
|
+
*
|
|
1758
|
+
* @example
|
|
1759
|
+
* ```ts
|
|
1760
|
+
* const requestBody: RequestBodyNode = {
|
|
1761
|
+
* kind: 'RequestBody',
|
|
1762
|
+
* required: true,
|
|
1763
|
+
* content: [{ kind: 'Content', contentType: 'application/json', schema: createSchema({ type: 'string' }) }],
|
|
1710
1764
|
* }
|
|
1711
1765
|
* ```
|
|
1712
1766
|
*/
|
|
1713
|
-
type
|
|
1767
|
+
type RequestBodyNode = BaseNode & {
|
|
1714
1768
|
/**
|
|
1715
1769
|
* Node kind.
|
|
1716
1770
|
*/
|
|
1717
|
-
kind: '
|
|
1771
|
+
kind: 'RequestBody';
|
|
1718
1772
|
/**
|
|
1719
|
-
*
|
|
1773
|
+
* Human-readable request body description.
|
|
1720
1774
|
*/
|
|
1721
|
-
|
|
1775
|
+
description?: string;
|
|
1722
1776
|
/**
|
|
1723
|
-
*
|
|
1777
|
+
* Whether the request body is required (`requestBody.required: true` in the spec).
|
|
1778
|
+
* When `false` or absent, the generated `data` parameter should be optional.
|
|
1724
1779
|
*/
|
|
1725
|
-
|
|
1780
|
+
required?: boolean;
|
|
1726
1781
|
/**
|
|
1727
|
-
*
|
|
1728
|
-
*
|
|
1782
|
+
* All available content type entries for this request body.
|
|
1783
|
+
*
|
|
1784
|
+
* When the adapter `contentType` option is set, this array contains exactly one entry for
|
|
1785
|
+
* that content type. Otherwise it contains one entry per content type declared in the spec,
|
|
1786
|
+
* so that plugins can generate code for every variant (e.g. separate hooks for
|
|
1787
|
+
* `application/json` and `multipart/form-data`).
|
|
1729
1788
|
*/
|
|
1730
|
-
|
|
1789
|
+
content?: Array<ContentNode>;
|
|
1790
|
+
};
|
|
1791
|
+
/**
|
|
1792
|
+
* Fields shared by every operation, regardless of transport.
|
|
1793
|
+
*/
|
|
1794
|
+
type OperationNodeBase = BaseNode & {
|
|
1795
|
+
/**
|
|
1796
|
+
* Node kind.
|
|
1797
|
+
*/
|
|
1798
|
+
kind: 'Operation';
|
|
1799
|
+
/**
|
|
1800
|
+
* Operation identifier, usually from OpenAPI `operationId`.
|
|
1801
|
+
*/
|
|
1802
|
+
operationId: string;
|
|
1731
1803
|
/**
|
|
1732
1804
|
* Group labels for the operation.
|
|
1733
1805
|
* Usually copied from OpenAPI `tags`.
|
|
@@ -1750,54 +1822,64 @@ type OperationNode = BaseNode & {
|
|
|
1750
1822
|
*/
|
|
1751
1823
|
parameters: Array<ParameterNode>;
|
|
1752
1824
|
/**
|
|
1753
|
-
* Request body
|
|
1825
|
+
* Request body for the operation.
|
|
1754
1826
|
*/
|
|
1755
|
-
requestBody?:
|
|
1756
|
-
/**
|
|
1757
|
-
* Human-readable request body description.
|
|
1758
|
-
*/
|
|
1759
|
-
description?: string;
|
|
1760
|
-
/**
|
|
1761
|
-
* Whether the request body is required (`requestBody.required: true` in the spec).
|
|
1762
|
-
* When `false` or absent, the generated `data` parameter should be optional.
|
|
1763
|
-
*/
|
|
1764
|
-
required?: boolean;
|
|
1765
|
-
/**
|
|
1766
|
-
* All available content type entries for this request body.
|
|
1767
|
-
*
|
|
1768
|
-
* When the adapter `contentType` option is set, this array contains exactly one entry for
|
|
1769
|
-
* that content type. Otherwise it contains one entry per content type declared in the spec,
|
|
1770
|
-
* so that plugins can generate code for every variant (e.g. separate hooks for
|
|
1771
|
-
* `application/json` and `multipart/form-data`).
|
|
1772
|
-
*
|
|
1773
|
-
* @example
|
|
1774
|
-
* ```ts
|
|
1775
|
-
* // spec has both application/json and multipart/form-data
|
|
1776
|
-
* requestBody.content[0].contentType // 'application/json'
|
|
1777
|
-
* requestBody.content[1].contentType // 'multipart/form-data'
|
|
1778
|
-
* ```
|
|
1779
|
-
*/
|
|
1780
|
-
content?: Array<{
|
|
1781
|
-
/**
|
|
1782
|
-
* The content type for this entry (e.g. `'application/json'`).
|
|
1783
|
-
*/
|
|
1784
|
-
contentType: string;
|
|
1785
|
-
/**
|
|
1786
|
-
* Request body schema for this content type.
|
|
1787
|
-
*/
|
|
1788
|
-
schema?: SchemaNode;
|
|
1789
|
-
/**
|
|
1790
|
-
* Property keys to exclude from the generated request body type via `Omit<Type, Keys>`.
|
|
1791
|
-
* Set when a referenced schema has `readOnly` fields that should be omitted in request types.
|
|
1792
|
-
*/
|
|
1793
|
-
keysToOmit?: Array<string>;
|
|
1794
|
-
}>;
|
|
1795
|
-
};
|
|
1827
|
+
requestBody?: RequestBodyNode;
|
|
1796
1828
|
/**
|
|
1797
1829
|
* Operation responses.
|
|
1798
1830
|
*/
|
|
1799
1831
|
responses: Array<ResponseNode>;
|
|
1800
1832
|
};
|
|
1833
|
+
/**
|
|
1834
|
+
* Operation served over HTTP/REST (OpenAPI). `method` and `path` are guaranteed.
|
|
1835
|
+
*
|
|
1836
|
+
* @example
|
|
1837
|
+
* ```ts
|
|
1838
|
+
* const operation: HttpOperationNode = {
|
|
1839
|
+
* kind: 'Operation',
|
|
1840
|
+
* operationId: 'listPets',
|
|
1841
|
+
* protocol: 'http',
|
|
1842
|
+
* method: 'GET',
|
|
1843
|
+
* path: '/pets',
|
|
1844
|
+
* tags: [],
|
|
1845
|
+
* parameters: [],
|
|
1846
|
+
* responses: [],
|
|
1847
|
+
* }
|
|
1848
|
+
* ```
|
|
1849
|
+
*/
|
|
1850
|
+
type HttpOperationNode = OperationNodeBase & {
|
|
1851
|
+
/**
|
|
1852
|
+
* Transport the operation belongs to.
|
|
1853
|
+
*/
|
|
1854
|
+
protocol?: 'http';
|
|
1855
|
+
/**
|
|
1856
|
+
* HTTP method like `'GET'`.
|
|
1857
|
+
*/
|
|
1858
|
+
method: HttpMethod;
|
|
1859
|
+
/**
|
|
1860
|
+
* OpenAPI-style path string, for example `/pets/{petId}`, with `{param}` notation preserved.
|
|
1861
|
+
*/
|
|
1862
|
+
path: string;
|
|
1863
|
+
};
|
|
1864
|
+
/**
|
|
1865
|
+
* Operation for a non-HTTP transport. HTTP-only fields are forbidden.
|
|
1866
|
+
*/
|
|
1867
|
+
type GenericOperationNode = OperationNodeBase & {
|
|
1868
|
+
/**
|
|
1869
|
+
* Transport the operation belongs to.
|
|
1870
|
+
*/
|
|
1871
|
+
protocol?: Exclude<OperationProtocol, 'http'>;
|
|
1872
|
+
method?: never;
|
|
1873
|
+
path?: never;
|
|
1874
|
+
};
|
|
1875
|
+
/**
|
|
1876
|
+
* AST node representing one API operation.
|
|
1877
|
+
*
|
|
1878
|
+
* Discriminated on `protocol`: an {@link HttpOperationNode} (`protocol: 'http'`) guarantees
|
|
1879
|
+
* `method` and `path`, while a {@link GenericOperationNode} omits them. Narrow with
|
|
1880
|
+
* `isHttpOperationNode(node)` or `node.protocol === 'http'` before reading `method`/`path`.
|
|
1881
|
+
*/
|
|
1882
|
+
type OperationNode = HttpOperationNode | GenericOperationNode;
|
|
1801
1883
|
//#endregion
|
|
1802
1884
|
//#region src/nodes/output.d.ts
|
|
1803
1885
|
/**
|
|
@@ -1826,32 +1908,62 @@ type OutputNode = BaseNode & {
|
|
|
1826
1908
|
//#endregion
|
|
1827
1909
|
//#region src/nodes/root.d.ts
|
|
1828
1910
|
/**
|
|
1829
|
-
*
|
|
1830
|
-
*
|
|
1911
|
+
* Metadata for an API document, populated by the adapter and available to every generator.
|
|
1912
|
+
*
|
|
1913
|
+
* All fields are plain JSON-serializable values — no `Set`, no `Map`, no class instances.
|
|
1914
|
+
* Computed fields (`circularNames`, `enumNames`) are pre-calculated once during the adapter
|
|
1915
|
+
* pre-scan so generators never need to iterate the full schema list themselves.
|
|
1831
1916
|
*
|
|
1832
1917
|
* @example
|
|
1833
1918
|
* ```ts
|
|
1834
|
-
* const meta: InputMeta = { title: 'Pet
|
|
1919
|
+
* const meta: InputMeta = { title: 'Pet Store', version: '1.0.0', baseURL: 'https://petstore.swagger.io/v2', circularNames: [], enumNames: [] }
|
|
1835
1920
|
* ```
|
|
1836
1921
|
*/
|
|
1837
1922
|
type InputMeta = {
|
|
1838
1923
|
/**
|
|
1839
|
-
* API title
|
|
1924
|
+
* API title from `info.title` in the source document.
|
|
1840
1925
|
*/
|
|
1841
1926
|
title?: string;
|
|
1842
1927
|
/**
|
|
1843
|
-
* API description
|
|
1928
|
+
* API description from `info.description` in the source document.
|
|
1844
1929
|
*/
|
|
1845
1930
|
description?: string;
|
|
1846
1931
|
/**
|
|
1847
|
-
* API version string
|
|
1932
|
+
* API version string from `info.version` in the source document.
|
|
1848
1933
|
*/
|
|
1849
1934
|
version?: string;
|
|
1850
1935
|
/**
|
|
1851
|
-
* Resolved
|
|
1852
|
-
|
|
1936
|
+
* Resolved base URL from the first matching server entry in the source document.
|
|
1937
|
+
*/
|
|
1938
|
+
baseURL?: string | null;
|
|
1939
|
+
/**
|
|
1940
|
+
* Names of schemas that participate in a circular reference chain.
|
|
1941
|
+
* Computed once during the adapter pre-scan — use this instead of calling
|
|
1942
|
+
* `findCircularSchemas` per generator call.
|
|
1943
|
+
*
|
|
1944
|
+
* Convert to a `Set` once at the start of a generator, not per-schema,
|
|
1945
|
+
* to keep lookup O(1) without repeated allocations.
|
|
1946
|
+
*
|
|
1947
|
+
* @example Wrap a circular schema in z.lazy()
|
|
1948
|
+
* ```ts
|
|
1949
|
+
* const circular = new Set(meta.circularNames)
|
|
1950
|
+
* if (circular.has(schema.name)) { ... }
|
|
1951
|
+
* ```
|
|
1952
|
+
*/
|
|
1953
|
+
circularNames: ReadonlyArray<string>;
|
|
1954
|
+
/**
|
|
1955
|
+
* Names of schemas whose type is `enum`.
|
|
1956
|
+
* Computed once during the adapter pre-scan — use this instead of filtering
|
|
1957
|
+
* schemas per generator call.
|
|
1958
|
+
*
|
|
1959
|
+
* Convert to a `Set` once at the start of a generator when you need repeated
|
|
1960
|
+
* membership checks, rather than calling `.includes()` per schema.
|
|
1961
|
+
*
|
|
1962
|
+
* @example Check if a referenced schema is an enum
|
|
1963
|
+
* `const enums = new Set(meta.enumNames)`
|
|
1964
|
+
* `const isEnum = enums.has(schemaName)`
|
|
1853
1965
|
*/
|
|
1854
|
-
|
|
1966
|
+
enumNames: ReadonlyArray<string>;
|
|
1855
1967
|
};
|
|
1856
1968
|
/**
|
|
1857
1969
|
* Input AST node that contains all schemas and operations for one API document.
|
|
@@ -1880,7 +1992,38 @@ type InputNode = BaseNode & {
|
|
|
1880
1992
|
*/
|
|
1881
1993
|
operations: Array<OperationNode>;
|
|
1882
1994
|
/**
|
|
1883
|
-
*
|
|
1995
|
+
* Document metadata populated by the adapter.
|
|
1996
|
+
*/
|
|
1997
|
+
meta: InputMeta;
|
|
1998
|
+
};
|
|
1999
|
+
/**
|
|
2000
|
+
* Streaming variant of `InputNode` for memory-efficient processing of large API specs.
|
|
2001
|
+
*
|
|
2002
|
+
* `schemas` and `operations` are `AsyncIterable` rather than arrays — each `for await`
|
|
2003
|
+
* loop creates a fresh parse pass from the cached in-memory document, so multiple
|
|
2004
|
+
* consumers (plugins) can iterate independently without keeping all nodes in memory.
|
|
2005
|
+
*
|
|
2006
|
+
* @example
|
|
2007
|
+
* ```ts
|
|
2008
|
+
* for await (const schema of inputStreamNode.schemas) {
|
|
2009
|
+
* // only this one SchemaNode is live here; previous ones are GC-eligible
|
|
2010
|
+
* }
|
|
2011
|
+
* ```
|
|
2012
|
+
*/
|
|
2013
|
+
type InputStreamNode = {
|
|
2014
|
+
kind: 'Input';
|
|
2015
|
+
/**
|
|
2016
|
+
* Lazily parsed schema nodes. Each `for await` creates a fresh parse pass, so
|
|
2017
|
+
* multiple plugins can iterate independently without sharing state.
|
|
2018
|
+
*/
|
|
2019
|
+
schemas: AsyncIterable<SchemaNode>;
|
|
2020
|
+
/**
|
|
2021
|
+
* Lazily parsed operation nodes. Each `for await` creates a fresh parse pass, so
|
|
2022
|
+
* multiple plugins can iterate independently without sharing state.
|
|
2023
|
+
*/
|
|
2024
|
+
operations: AsyncIterable<OperationNode>;
|
|
2025
|
+
/**
|
|
2026
|
+
* Document metadata available immediately, before the first yielded node.
|
|
1884
2027
|
*/
|
|
1885
2028
|
meta?: InputMeta;
|
|
1886
2029
|
};
|
|
@@ -1905,7 +2048,198 @@ type InputNode = BaseNode & {
|
|
|
1905
2048
|
* }
|
|
1906
2049
|
* ```
|
|
1907
2050
|
*/
|
|
1908
|
-
type Node = InputNode | OutputNode | OperationNode | SchemaNode | PropertyNode | ParameterNode | ResponseNode | FunctionParamNode | FileNode | ImportNode | ExportNode | SourceNode | ConstNode | TypeNode | ParamsTypeNode | FunctionNode | ArrowFunctionNode;
|
|
2051
|
+
type Node = InputNode | OutputNode | OperationNode | SchemaNode | PropertyNode | ParameterNode | ResponseNode | RequestBodyNode | ContentNode | FunctionParamNode | FileNode | ImportNode | ExportNode | SourceNode | ConstNode | TypeNode | ParamsTypeNode | FunctionNode | ArrowFunctionNode;
|
|
2052
|
+
//#endregion
|
|
2053
|
+
//#region src/dedupe.d.ts
|
|
2054
|
+
/**
|
|
2055
|
+
* A canonical destination for a deduplicated shape: the shared schema name and
|
|
2056
|
+
* the synthetic `$ref` path that points at it.
|
|
2057
|
+
*/
|
|
2058
|
+
type DedupeCanonical = {
|
|
2059
|
+
/**
|
|
2060
|
+
* Canonical schema name every duplicate occurrence refers to.
|
|
2061
|
+
*/
|
|
2062
|
+
name: string;
|
|
2063
|
+
/**
|
|
2064
|
+
* `$ref` path stored on the generated `ref` nodes (for example `#/components/schemas/Status`).
|
|
2065
|
+
*/
|
|
2066
|
+
ref: string;
|
|
2067
|
+
};
|
|
2068
|
+
/**
|
|
2069
|
+
* The result of {@link buildDedupePlan}: a lookup from structural signature to its
|
|
2070
|
+
* canonical target, plus the freshly hoisted definitions that must be added to
|
|
2071
|
+
* the schema list.
|
|
2072
|
+
*/
|
|
2073
|
+
type DedupePlan = {
|
|
2074
|
+
/**
|
|
2075
|
+
* Maps a structural signature to the canonical schema that represents it.
|
|
2076
|
+
*/
|
|
2077
|
+
canonicalBySignature: Map<string, DedupeCanonical>;
|
|
2078
|
+
/**
|
|
2079
|
+
* New top-level schema definitions created for inline shapes that had no existing
|
|
2080
|
+
* named component. Nested duplicates inside each definition are already collapsed.
|
|
2081
|
+
*/
|
|
2082
|
+
hoisted: Array<SchemaNode>;
|
|
2083
|
+
};
|
|
2084
|
+
/**
|
|
2085
|
+
* Options that inject the naming and candidate policy into {@link buildDedupePlan}.
|
|
2086
|
+
* The mechanics (grouping, counting, rewriting) live here; the policy lives in the caller.
|
|
2087
|
+
*/
|
|
2088
|
+
type BuildDedupePlanOptions = {
|
|
2089
|
+
/**
|
|
2090
|
+
* Returns `true` when a node should be deduplicated. This is the only gate, so it must
|
|
2091
|
+
* reject both ineligible kinds (return `false` for anything other than, say, enums and
|
|
2092
|
+
* objects) and unsafe shapes (e.g. nodes that reference a circular schema).
|
|
2093
|
+
*/
|
|
2094
|
+
isCandidate: (node: SchemaNode) => boolean;
|
|
2095
|
+
/**
|
|
2096
|
+
* Produces the canonical name for an inline shape with no existing named component.
|
|
2097
|
+
* Return `null` to leave the shape inline (for example when no contextual name exists).
|
|
2098
|
+
*/
|
|
2099
|
+
nameFor: (node: SchemaNode, signature: string) => string | null;
|
|
2100
|
+
/**
|
|
2101
|
+
* Builds the `$ref` path for a canonical name.
|
|
2102
|
+
*/
|
|
2103
|
+
refFor: (name: string) => string;
|
|
2104
|
+
/**
|
|
2105
|
+
* Minimum number of occurrences before a shape is deduplicated.
|
|
2106
|
+
*
|
|
2107
|
+
* @default 2
|
|
2108
|
+
*/
|
|
2109
|
+
minOccurrences?: number;
|
|
2110
|
+
};
|
|
2111
|
+
/**
|
|
2112
|
+
* Rewrites a node, replacing every candidate sub-schema whose signature has a canonical
|
|
2113
|
+
* target with a `ref` to that target. Replacing a node with a `ref` prunes its subtree,
|
|
2114
|
+
* so nested duplicates inside a replaced shape are not visited again.
|
|
2115
|
+
*
|
|
2116
|
+
* Pass `skipRootMatch` when rewriting a canonical definition so its own root is not
|
|
2117
|
+
* turned into a reference to itself; nested duplicates are still collapsed.
|
|
2118
|
+
*
|
|
2119
|
+
* @example
|
|
2120
|
+
* ```ts
|
|
2121
|
+
* const next = applyDedupe(operationNode, plan.canonicalBySignature)
|
|
2122
|
+
* ```
|
|
2123
|
+
*/
|
|
2124
|
+
declare function applyDedupe(node: SchemaNode, canonicalBySignature: ReadonlyMap<string, DedupeCanonical>, skipRootMatch?: boolean): SchemaNode;
|
|
2125
|
+
declare function applyDedupe(node: OperationNode, canonicalBySignature: ReadonlyMap<string, DedupeCanonical>, skipRootMatch?: boolean): OperationNode;
|
|
2126
|
+
/**
|
|
2127
|
+
* Scans a forest of schema and operation nodes and produces a {@link DedupePlan}.
|
|
2128
|
+
*
|
|
2129
|
+
* A shape that occurs at least `minOccurrences` times is deduplicated: if any occurrence
|
|
2130
|
+
* is a named top-level schema, that name becomes the canonical (so other top-level duplicates
|
|
2131
|
+
* and inline copies turn into references to it); otherwise a new definition is hoisted using
|
|
2132
|
+
* `nameFor`. The plan is then applied per node with {@link applyDedupe}.
|
|
2133
|
+
*
|
|
2134
|
+
* @example
|
|
2135
|
+
* ```ts
|
|
2136
|
+
* const plan = buildDedupePlan([...schemaNodes, ...operationNodes], {
|
|
2137
|
+
* isCandidate: (node) => node.type === 'enum' || node.type === 'object',
|
|
2138
|
+
* nameFor: (node) => node.name ?? null,
|
|
2139
|
+
* refFor: (name) => `#/components/schemas/${name}`,
|
|
2140
|
+
* })
|
|
2141
|
+
* ```
|
|
2142
|
+
*/
|
|
2143
|
+
declare function buildDedupePlan(roots: ReadonlyArray<Node>, options: BuildDedupePlanOptions): DedupePlan;
|
|
2144
|
+
//#endregion
|
|
2145
|
+
//#region src/dialect.d.ts
|
|
2146
|
+
/**
|
|
2147
|
+
* The spec-specific decisions a schema parser makes while converting a source
|
|
2148
|
+
* document's schemas into Kubb AST nodes.
|
|
2149
|
+
*
|
|
2150
|
+
* Everything else in an adapter's schema pipeline is generic JSON Schema shared
|
|
2151
|
+
* across specs; the dialect is the one seam where a spec differs — the
|
|
2152
|
+
* "dialect layer" analogue of a database driver targeting Postgres vs MySQL.
|
|
2153
|
+
* Pair it with {@link dispatch}: the rule table decides *which* converter runs,
|
|
2154
|
+
* the dialect answers the spec-specific questions inside them.
|
|
2155
|
+
*
|
|
2156
|
+
* The guard methods (`isReference`, `isDiscriminator`) are type predicates so
|
|
2157
|
+
* converters narrow the schema after a check; the type parameters carry those
|
|
2158
|
+
* narrowed types through.
|
|
2159
|
+
*
|
|
2160
|
+
* Scope: this is the seam for the **JSON Schema family** — OpenAPI, AsyncAPI, and
|
|
2161
|
+
* plain JSON Schema all share `$ref`, `allOf`/`oneOf`, `enum`, and `format`, and
|
|
2162
|
+
* differ only in these few decisions. A spec built on a different type system
|
|
2163
|
+
* (e.g. GraphQL, with non-null wrappers, interfaces, and named-type references
|
|
2164
|
+
* instead of `$ref`) does not implement a `SchemaDialect`; it reuses the universal
|
|
2165
|
+
* layer directly — the `Adapter` port, the AST factories, and {@link dispatch}
|
|
2166
|
+
* with its own rule table — to emit the same nodes.
|
|
2167
|
+
*
|
|
2168
|
+
* @typeParam TSchema - The adapter's schema object type (e.g. an OpenAPI `SchemaObject`).
|
|
2169
|
+
* @typeParam TRef - The narrowed `$ref` pointer type `isReference` proves.
|
|
2170
|
+
* @typeParam TDiscriminated - The narrowed discriminated-schema type `isDiscriminator` proves.
|
|
2171
|
+
* @typeParam TDocument - The source document `resolveRef` resolves against.
|
|
2172
|
+
*/
|
|
2173
|
+
type SchemaDialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown> = {
|
|
2174
|
+
/** Identifies the dialect in logs and while debugging dispatch. */name: string; /** Whether a schema should be treated as nullable. */
|
|
2175
|
+
isNullable: (schema?: TSchema) => boolean; /** Whether a value is a `$ref` pointer object. */
|
|
2176
|
+
isReference: (value?: unknown) => value is TRef; /** Whether a schema carries a structured discriminator (polymorphism). */
|
|
2177
|
+
isDiscriminator: (value?: unknown) => value is TDiscriminated; /** Whether a schema represents binary data (converted to a `blob` node). */
|
|
2178
|
+
isBinary: (schema: TSchema) => boolean; /** Resolves a local `$ref` pointer against the document, or nullish when it cannot. */
|
|
2179
|
+
resolveRef: <TResolved>(document: TDocument, ref: string) => TResolved | null | undefined;
|
|
2180
|
+
};
|
|
2181
|
+
/**
|
|
2182
|
+
* Identity helper that types a {@link SchemaDialect} for an adapter. Like
|
|
2183
|
+
* `defineParser`, it adds no runtime behavior — it pins the dialect's type for
|
|
2184
|
+
* inference and gives adapter authors a discoverable anchor.
|
|
2185
|
+
*
|
|
2186
|
+
* @example
|
|
2187
|
+
* ```ts
|
|
2188
|
+
* export const oasDialect = defineSchemaDialect({
|
|
2189
|
+
* name: 'oas',
|
|
2190
|
+
* isNullable,
|
|
2191
|
+
* isReference,
|
|
2192
|
+
* isDiscriminator,
|
|
2193
|
+
* isBinary: (schema) => schema.type === 'string' && schema.contentMediaType === 'application/octet-stream',
|
|
2194
|
+
* resolveRef,
|
|
2195
|
+
* })
|
|
2196
|
+
* ```
|
|
2197
|
+
*/
|
|
2198
|
+
declare function defineSchemaDialect<TSchema, TRef, TDiscriminated, TDocument>(dialect: SchemaDialect<TSchema, TRef, TDiscriminated, TDocument>): SchemaDialect<TSchema, TRef, TDiscriminated, TDocument>;
|
|
2199
|
+
//#endregion
|
|
2200
|
+
//#region src/dispatch.d.ts
|
|
2201
|
+
/**
|
|
2202
|
+
* One entry in an ordered dispatch table: a predicate paired with a converter.
|
|
2203
|
+
*
|
|
2204
|
+
* @typeParam TContext - Per-input context handed to every rule. A spec adapter typically
|
|
2205
|
+
* pre-computes this once per node (the source spec node plus derived fields like a
|
|
2206
|
+
* normalized type or resolved options) so individual rules stay cheap predicates.
|
|
2207
|
+
* @typeParam TNode - The node a rule produces, e.g. a Kubb AST `SchemaNode`.
|
|
2208
|
+
*/
|
|
2209
|
+
type DispatchRule<TContext, TNode> = {
|
|
2210
|
+
/** Identifies the rule when reading the table or debugging which branch ran. */name: string; /** Returns `true` when this rule is responsible for the given context. */
|
|
2211
|
+
match: (context: TContext) => boolean;
|
|
2212
|
+
/**
|
|
2213
|
+
* Produces a node for the context, or `null` to fall through to the next rule.
|
|
2214
|
+
*
|
|
2215
|
+
* Returning `null` lets a broad `match` defer: e.g. "has a `format`" matches many schemas,
|
|
2216
|
+
* but only some formats are convertible — the rest fall through to plain `type` handling.
|
|
2217
|
+
*/
|
|
2218
|
+
convert: (context: TContext) => TNode | null;
|
|
2219
|
+
};
|
|
2220
|
+
/**
|
|
2221
|
+
* Walks an ordered list of {@link DispatchRule}s and returns the first node produced.
|
|
2222
|
+
*
|
|
2223
|
+
* This is the shared backbone for spec adapters (OpenAPI today, AsyncAPI and others later).
|
|
2224
|
+
* The contract an adapter follows is intentionally minimal:
|
|
2225
|
+
*
|
|
2226
|
+
* context → [rule.match → rule.convert] → node
|
|
2227
|
+
*
|
|
2228
|
+
* An adapter derives a context from a source spec node, then declares an ordered table of
|
|
2229
|
+
* rules mapping spec shapes onto Kubb AST nodes. To add support for a new spec, write a new
|
|
2230
|
+
* context type and a new rules table — the traversal here is reused unchanged.
|
|
2231
|
+
*
|
|
2232
|
+
* Order is significant: earlier rules win, so list higher-precedence or more specific shapes
|
|
2233
|
+
* first (e.g. composition keywords before plain `type`). A rule whose `match` returns `true`
|
|
2234
|
+
* may still `convert` to `null` to defer to later rules. When no rule produces a node this
|
|
2235
|
+
* returns `null`, leaving the caller to apply its own fallback.
|
|
2236
|
+
*
|
|
2237
|
+
* @example
|
|
2238
|
+
* ```ts
|
|
2239
|
+
* const node = dispatch(schemaRules, schemaContext) ?? createSchema({ type: fallbackType })
|
|
2240
|
+
* ```
|
|
2241
|
+
*/
|
|
2242
|
+
declare function dispatch<TContext, TNode>(rules: ReadonlyArray<DispatchRule<TContext, TNode>>, context: TContext): TNode | null;
|
|
1909
2243
|
//#endregion
|
|
1910
2244
|
//#region src/infer.d.ts
|
|
1911
2245
|
/**
|
|
@@ -1913,15 +2247,25 @@ type Node = InputNode | OutputNode | OperationNode | SchemaNode | PropertyNode |
|
|
|
1913
2247
|
*/
|
|
1914
2248
|
type ParserOptions = {
|
|
1915
2249
|
/**
|
|
1916
|
-
* How `format: 'date-time'` schemas are represented
|
|
2250
|
+
* How `format: 'date-time'` schemas are represented downstream.
|
|
2251
|
+
* - `false` falls through to a plain `string` (no validation).
|
|
2252
|
+
* - `'string'` emits a datetime string node.
|
|
2253
|
+
* - `'stringOffset'` emits a datetime node with timezone offset.
|
|
2254
|
+
* - `'stringLocal'` emits a local datetime node.
|
|
2255
|
+
* - `'date'` emits a `date` node (JavaScript `Date` object).
|
|
1917
2256
|
*/
|
|
1918
2257
|
dateType: false | 'string' | 'stringOffset' | 'stringLocal' | 'date';
|
|
1919
2258
|
/**
|
|
1920
|
-
*
|
|
2259
|
+
* How `type: 'integer'` (and `format: 'int64'`) maps to TypeScript.
|
|
2260
|
+
* - `'number'` fits most JSON APIs; loses precision above `Number.MAX_SAFE_INTEGER`.
|
|
2261
|
+
* - `'bigint'` is exact for 64-bit IDs, but does not round-trip through JSON.
|
|
2262
|
+
*
|
|
2263
|
+
* @default 'number'
|
|
1921
2264
|
*/
|
|
1922
2265
|
integerType?: 'number' | 'bigint';
|
|
1923
2266
|
/**
|
|
1924
|
-
* AST type used when
|
|
2267
|
+
* AST type used when a schema's type cannot be inferred from the spec
|
|
2268
|
+
* (`additionalProperties: true`, missing `type`, ...).
|
|
1925
2269
|
*/
|
|
1926
2270
|
unknownType: 'any' | 'unknown' | 'void';
|
|
1927
2271
|
/**
|
|
@@ -1929,7 +2273,8 @@ type ParserOptions = {
|
|
|
1929
2273
|
*/
|
|
1930
2274
|
emptySchemaType: 'any' | 'unknown' | 'void';
|
|
1931
2275
|
/**
|
|
1932
|
-
* Suffix appended to derived enum names when
|
|
2276
|
+
* Suffix appended to derived enum names when Kubb has to invent one
|
|
2277
|
+
* (typically for inline enums on object properties).
|
|
1933
2278
|
*/
|
|
1934
2279
|
enumSuffix: 'enum' | (string & {});
|
|
1935
2280
|
};
|
|
@@ -1957,7 +2302,7 @@ type SchemaNodeMap<TDateType extends ParserOptions['dateType'] = 'string'> = [[{
|
|
|
1957
2302
|
allOf: ReadonlyArray<unknown>;
|
|
1958
2303
|
properties: object;
|
|
1959
2304
|
}, IntersectionSchemaNode], [{
|
|
1960
|
-
allOf: readonly [unknown, unknown, ...unknown
|
|
2305
|
+
allOf: readonly [unknown, unknown, ...Array<unknown>];
|
|
1961
2306
|
}, IntersectionSchemaNode], [{
|
|
1962
2307
|
allOf: ReadonlyArray<unknown>;
|
|
1963
2308
|
}, SchemaNode], [{
|
|
@@ -2050,10 +2395,13 @@ type InferSchema<TSchema extends object, TDateType extends ParserOptions['dateTy
|
|
|
2050
2395
|
//#endregion
|
|
2051
2396
|
//#region src/factory.d.ts
|
|
2052
2397
|
/**
|
|
2053
|
-
*
|
|
2398
|
+
* Updates a schema's `optional` and `nullish` flags from a parent's `required`
|
|
2399
|
+
* value and the schema's own `nullable`. Mirrors how OpenAPI parameters and
|
|
2400
|
+
* object properties combine "required" and "nullable" into a single AST.
|
|
2054
2401
|
*
|
|
2055
|
-
* -
|
|
2056
|
-
* -
|
|
2402
|
+
* - Non-required + non-nullable → `optional: true`.
|
|
2403
|
+
* - Non-required + nullable → `nullish: true`.
|
|
2404
|
+
* - Required → both flags cleared.
|
|
2057
2405
|
*/
|
|
2058
2406
|
declare function syncOptionality(schema: SchemaNode, required: boolean): SchemaNode;
|
|
2059
2407
|
/**
|
|
@@ -2068,6 +2416,23 @@ declare function syncOptionality(schema: SchemaNode, required: boolean): SchemaN
|
|
|
2068
2416
|
* ```
|
|
2069
2417
|
*/
|
|
2070
2418
|
type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
|
|
2419
|
+
/**
|
|
2420
|
+
* Identity-preserving node update: returns `node` unchanged when every field in
|
|
2421
|
+
* `changes` already equals (by reference) the current value, otherwise a new node
|
|
2422
|
+
* with the changes applied.
|
|
2423
|
+
*
|
|
2424
|
+
* Mirrors the TypeScript compiler's `factory.updateX` contract — pair it with the
|
|
2425
|
+
* structural sharing in {@link transform} so a no-op rewrite doesn't allocate and
|
|
2426
|
+
* downstream passes can detect "nothing changed" by identity. Comparison is
|
|
2427
|
+
* shallow: a structurally-equal but newly-allocated array/object counts as a change.
|
|
2428
|
+
*
|
|
2429
|
+
* @example
|
|
2430
|
+
* ```ts
|
|
2431
|
+
* update(node, { name: node.name }) // -> same `node` reference
|
|
2432
|
+
* update(node, { name: 'renamed' }) // -> new node, `name` replaced
|
|
2433
|
+
* ```
|
|
2434
|
+
*/
|
|
2435
|
+
declare function update<T extends Node>(node: T, changes: Partial<T>): T;
|
|
2071
2436
|
type CreateSchemaObjectInput = Omit<ObjectSchemaNode, 'kind' | 'properties' | 'primitive'> & {
|
|
2072
2437
|
properties?: Array<PropertyNode>;
|
|
2073
2438
|
primitive?: 'object';
|
|
@@ -2092,6 +2457,15 @@ type CreateSchemaOutput<T extends CreateSchemaInput> = InferSchemaNode<T> & {
|
|
|
2092
2457
|
* ```
|
|
2093
2458
|
*/
|
|
2094
2459
|
declare function createInput(overrides?: Partial<Omit<InputNode, 'kind'>>): InputNode;
|
|
2460
|
+
/**
|
|
2461
|
+
* Creates an `InputStreamNode` from pre-built `AsyncIterable` sources.
|
|
2462
|
+
*
|
|
2463
|
+
* @example
|
|
2464
|
+
* ```ts
|
|
2465
|
+
* const node = createStreamInput(schemasIterable, operationsIterable, { title: 'My API' })
|
|
2466
|
+
* ```
|
|
2467
|
+
*/
|
|
2468
|
+
declare function createStreamInput(schemas: AsyncIterable<SchemaNode>, operations: AsyncIterable<OperationNode>, meta?: InputMeta): InputStreamNode;
|
|
2095
2469
|
/**
|
|
2096
2470
|
* Creates an `OutputNode` with a stable default for `files`.
|
|
2097
2471
|
*
|
|
@@ -2130,7 +2504,30 @@ declare function createOutput(overrides?: Partial<Omit<OutputNode, 'kind'>>): Ou
|
|
|
2130
2504
|
* })
|
|
2131
2505
|
* ```
|
|
2132
2506
|
*/
|
|
2133
|
-
|
|
2507
|
+
/**
|
|
2508
|
+
* Loosely-typed content entry accepted by the builders, normalized into a {@link ContentNode}.
|
|
2509
|
+
*/
|
|
2510
|
+
type UserContent = Omit<ContentNode, 'kind'>;
|
|
2511
|
+
/**
|
|
2512
|
+
* Creates a `ContentNode` for a single request-body or response content type.
|
|
2513
|
+
*/
|
|
2514
|
+
declare function createContent(props: UserContent): ContentNode;
|
|
2515
|
+
/**
|
|
2516
|
+
* Loosely-typed request body accepted by `createOperation`, normalized into a {@link RequestBodyNode}.
|
|
2517
|
+
*/
|
|
2518
|
+
type UserRequestBody = Omit<RequestBodyNode, 'kind' | 'content'> & {
|
|
2519
|
+
content?: Array<UserContent>;
|
|
2520
|
+
};
|
|
2521
|
+
/**
|
|
2522
|
+
* Creates a `RequestBodyNode`, normalizing each content entry into a `ContentNode`.
|
|
2523
|
+
*/
|
|
2524
|
+
declare function createRequestBody(props: UserRequestBody): RequestBodyNode;
|
|
2525
|
+
declare function createOperation(props: Pick<HttpOperationNode, 'operationId' | 'method' | 'path'> & Partial<Omit<HttpOperationNode, 'kind' | 'operationId' | 'method' | 'path' | 'requestBody'>> & {
|
|
2526
|
+
requestBody?: UserRequestBody;
|
|
2527
|
+
}): HttpOperationNode;
|
|
2528
|
+
declare function createOperation(props: Pick<GenericOperationNode, 'operationId'> & Partial<Omit<GenericOperationNode, 'kind' | 'operationId' | 'requestBody'>> & {
|
|
2529
|
+
requestBody?: UserRequestBody;
|
|
2530
|
+
}): GenericOperationNode;
|
|
2134
2531
|
/**
|
|
2135
2532
|
* Creates a `SchemaNode`, narrowed to the variant of `props.type`.
|
|
2136
2533
|
* For object schemas, `properties` defaults to an empty array.
|
|
@@ -2222,16 +2619,24 @@ declare function createParameter(props: Pick<ParameterNode, 'name' | 'in' | 'sch
|
|
|
2222
2619
|
/**
|
|
2223
2620
|
* Creates a `ResponseNode`.
|
|
2224
2621
|
*
|
|
2622
|
+
* Response body schemas live inside `content`. For convenience a single legacy `schema`
|
|
2623
|
+
* (with optional `mediaType`/`keysToOmit`) is normalized into one `content` entry, so the same
|
|
2624
|
+
* schema is never stored both at the node root and inside `content`.
|
|
2625
|
+
*
|
|
2225
2626
|
* @example
|
|
2226
2627
|
* ```ts
|
|
2227
2628
|
* const response = createResponse({
|
|
2228
2629
|
* statusCode: '200',
|
|
2229
|
-
*
|
|
2230
|
-
* schema: createSchema({ type: 'object', properties: [] }),
|
|
2630
|
+
* content: [{ contentType: 'application/json', schema: createSchema({ type: 'object', properties: [] }) }],
|
|
2231
2631
|
* })
|
|
2232
2632
|
* ```
|
|
2233
2633
|
*/
|
|
2234
|
-
declare function createResponse(props: Pick<ResponseNode, 'statusCode'
|
|
2634
|
+
declare function createResponse(props: Pick<ResponseNode, 'statusCode'> & Partial<Omit<ResponseNode, 'kind' | 'statusCode' | 'content'>> & {
|
|
2635
|
+
content?: Array<UserContent>;
|
|
2636
|
+
schema?: SchemaNode;
|
|
2637
|
+
mediaType?: string | null;
|
|
2638
|
+
keysToOmit?: Array<string> | null;
|
|
2639
|
+
}): ResponseNode;
|
|
2235
2640
|
/**
|
|
2236
2641
|
* Creates a `FunctionParameterNode`.
|
|
2237
2642
|
*
|
|
@@ -2583,10 +2988,10 @@ declare function createJsx(value: string): JsxNode;
|
|
|
2583
2988
|
* @example
|
|
2584
2989
|
* ```ts
|
|
2585
2990
|
* const schema = createSchema({ type: 'string' })
|
|
2586
|
-
* const stringNode = narrowSchema(schema, 'string') // StringSchemaNode |
|
|
2991
|
+
* const stringNode = narrowSchema(schema, 'string') // StringSchemaNode | null
|
|
2587
2992
|
* ```
|
|
2588
2993
|
*/
|
|
2589
|
-
declare function narrowSchema<T extends SchemaNode['type']>(node: SchemaNode | undefined, type: T): SchemaNodeByType[T] |
|
|
2994
|
+
declare function narrowSchema<T extends SchemaNode['type']>(node: SchemaNode | undefined, type: T): SchemaNodeByType[T] | null;
|
|
2590
2995
|
/**
|
|
2591
2996
|
* Returns `true` when the input is an `InputNode`.
|
|
2592
2997
|
*
|
|
@@ -2620,6 +3025,17 @@ declare const isOutputNode: (node: unknown) => node is OutputNode;
|
|
|
2620
3025
|
* ```
|
|
2621
3026
|
*/
|
|
2622
3027
|
declare const isOperationNode: (node: unknown) => node is OperationNode;
|
|
3028
|
+
/**
|
|
3029
|
+
* Narrows an `OperationNode` to an `HttpOperationNode`, guaranteeing `method` and `path`.
|
|
3030
|
+
*
|
|
3031
|
+
* @example
|
|
3032
|
+
* ```ts
|
|
3033
|
+
* if (isHttpOperationNode(node)) {
|
|
3034
|
+
* console.log(node.method, node.path)
|
|
3035
|
+
* }
|
|
3036
|
+
* ```
|
|
3037
|
+
*/
|
|
3038
|
+
declare function isHttpOperationNode(node: OperationNode): node is HttpOperationNode;
|
|
2623
3039
|
/**
|
|
2624
3040
|
* Returns `true` when the input is a `SchemaNode`.
|
|
2625
3041
|
*
|
|
@@ -2651,7 +3067,7 @@ type PrinterHandlerContext<TOutput, TOptions extends object> = {
|
|
|
2651
3067
|
* Recursively transform a nested `SchemaNode` to `TOutput` using the node-level handlers.
|
|
2652
3068
|
* Use `this.transform` inside `nodes` handlers and inside the `print` override.
|
|
2653
3069
|
*/
|
|
2654
|
-
transform: (node: SchemaNode) => TOutput | null
|
|
3070
|
+
transform: (node: SchemaNode) => TOutput | null;
|
|
2655
3071
|
/**
|
|
2656
3072
|
* Options for this printer instance.
|
|
2657
3073
|
*/
|
|
@@ -2669,7 +3085,7 @@ type PrinterHandlerContext<TOutput, TOptions extends object> = {
|
|
|
2669
3085
|
* }
|
|
2670
3086
|
* ```
|
|
2671
3087
|
*/
|
|
2672
|
-
type PrinterHandler<TOutput, TOptions extends object, T extends SchemaType = SchemaType> = (this: PrinterHandlerContext<TOutput, TOptions>, node: SchemaNodeByType[T]) => TOutput | null
|
|
3088
|
+
type PrinterHandler<TOutput, TOptions extends object, T extends SchemaType = SchemaType> = (this: PrinterHandlerContext<TOutput, TOptions>, node: SchemaNodeByType[T]) => TOutput | null;
|
|
2673
3089
|
/**
|
|
2674
3090
|
* Partial map of per-node-type handler overrides for a printer.
|
|
2675
3091
|
*
|
|
@@ -2732,13 +3148,13 @@ type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {
|
|
|
2732
3148
|
* Always dispatches through the `nodes` map; never calls the `print` override.
|
|
2733
3149
|
* Use this when you need the raw output (e.g. `ts.TypeNode`) without declaration wrapping.
|
|
2734
3150
|
*/
|
|
2735
|
-
transform: (node: SchemaNode) => T['output'] | null
|
|
3151
|
+
transform: (node: SchemaNode) => T['output'] | null;
|
|
2736
3152
|
/**
|
|
2737
3153
|
* Public printer. If the builder provides a root-level `print`, this calls that
|
|
2738
3154
|
* higher-level function (which may produce full declarations).
|
|
2739
3155
|
* Otherwise, falls back to the node-level dispatcher.
|
|
2740
3156
|
*/
|
|
2741
|
-
print: (node: SchemaNode) => T['printOutput'] | null
|
|
3157
|
+
print: (node: SchemaNode) => T['printOutput'] | null;
|
|
2742
3158
|
};
|
|
2743
3159
|
/**
|
|
2744
3160
|
* Builder function passed to `definePrinter`.
|
|
@@ -2769,22 +3185,27 @@ type PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) =
|
|
|
2769
3185
|
print?: (this: PrinterHandlerContext<T['output'], T['options']>, node: SchemaNode) => T['printOutput'] | null;
|
|
2770
3186
|
};
|
|
2771
3187
|
/**
|
|
2772
|
-
*
|
|
2773
|
-
*
|
|
2774
|
-
*
|
|
3188
|
+
* Defines a schema printer: a function that takes a `SchemaNode` and emits
|
|
3189
|
+
* code in your target language. Each plugin that produces code from schemas
|
|
3190
|
+
* (TypeScript types, Zod schemas, Faker factories) ships a printer built
|
|
3191
|
+
* with this helper.
|
|
2775
3192
|
*
|
|
2776
3193
|
* The builder receives resolved options and returns:
|
|
2777
|
-
* - `name` — a unique identifier for the printer
|
|
2778
|
-
* - `options` — options stored on the returned printer instance
|
|
2779
|
-
* - `nodes` — a map of `SchemaType` → handler functions that convert a `SchemaNode` to `TOutput`
|
|
2780
|
-
* - `print` _(optional)_ — top-level override exposed as `printer.print`
|
|
2781
|
-
* - Inside this function, use `this.transform(node)` to dispatch to the `nodes` map
|
|
2782
|
-
* - This keeps recursion safe and avoids self-calls
|
|
2783
3194
|
*
|
|
2784
|
-
*
|
|
3195
|
+
* - `name` — unique identifier for the printer.
|
|
3196
|
+
* - `options` — stored on the returned printer instance.
|
|
3197
|
+
* - `nodes` — map of `SchemaType` → handler. Handlers return the rendered
|
|
3198
|
+
* output (a string, a TypeScript AST node, ...) for that schema type.
|
|
3199
|
+
* - `print` (optional) — top-level override exposed as `printer.print`.
|
|
3200
|
+
* Use `this.transform(node)` inside it to dispatch to `nodes` recursively.
|
|
2785
3201
|
*
|
|
2786
|
-
*
|
|
3202
|
+
* Without a `print` override, `printer.print` falls back to `printer.transform`
|
|
3203
|
+
* (the node-level dispatcher).
|
|
3204
|
+
*
|
|
3205
|
+
* @example Tiny Zod printer
|
|
2787
3206
|
* ```ts
|
|
3207
|
+
* import { definePrinter, type PrinterFactoryOptions } from '@kubb/ast'
|
|
3208
|
+
*
|
|
2788
3209
|
* type PrinterZod = PrinterFactoryOptions<'zod', { strict?: boolean }, string>
|
|
2789
3210
|
*
|
|
2790
3211
|
* export const zodPrinter = definePrinter<PrinterZod>((options) => ({
|
|
@@ -2793,7 +3214,9 @@ type PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) =
|
|
|
2793
3214
|
* nodes: {
|
|
2794
3215
|
* string: () => 'z.string()',
|
|
2795
3216
|
* object(node) {
|
|
2796
|
-
* const props = node.properties
|
|
3217
|
+
* const props = node.properties
|
|
3218
|
+
* .map((p) => `${p.name}: ${this.transform(p.schema)}`)
|
|
3219
|
+
* .join(', ')
|
|
2797
3220
|
* return `z.object({ ${props} })`
|
|
2798
3221
|
* },
|
|
2799
3222
|
* },
|
|
@@ -2811,22 +3234,22 @@ declare function definePrinter<T extends PrinterFactoryOptions = PrinterFactoryO
|
|
|
2811
3234
|
* )
|
|
2812
3235
|
* ```
|
|
2813
3236
|
*/
|
|
2814
|
-
declare function createPrinterFactory<TNode, TKey extends string, TNodeByKey extends Partial<Record<TKey, TNode>>>(getKey: (node: TNode) => TKey |
|
|
3237
|
+
declare function createPrinterFactory<TNode, TKey extends string, TNodeByKey extends Partial<Record<TKey, TNode>>>(getKey: (node: TNode) => TKey | null): <T extends PrinterFactoryOptions>(build: (options: T["options"]) => {
|
|
2815
3238
|
name: T["name"];
|
|
2816
3239
|
options: T["options"];
|
|
2817
3240
|
nodes: Partial<{ [K in TKey]: (this: {
|
|
2818
|
-
transform: (node: TNode) => T["output"] | null
|
|
3241
|
+
transform: (node: TNode) => T["output"] | null;
|
|
2819
3242
|
options: T["options"];
|
|
2820
|
-
}, node: TNodeByKey[K]) => T["output"] | null
|
|
3243
|
+
}, node: TNodeByKey[K]) => T["output"] | null }>;
|
|
2821
3244
|
print?: (this: {
|
|
2822
|
-
transform: (node: TNode) => T["output"] | null
|
|
3245
|
+
transform: (node: TNode) => T["output"] | null;
|
|
2823
3246
|
options: T["options"];
|
|
2824
|
-
}, node: TNode) => T["printOutput"] | null
|
|
3247
|
+
}, node: TNode) => T["printOutput"] | null;
|
|
2825
3248
|
}) => (options?: T["options"]) => {
|
|
2826
3249
|
name: T["name"];
|
|
2827
3250
|
options: T["options"];
|
|
2828
|
-
transform: (node: TNode) => T["output"] | null
|
|
2829
|
-
print: (node: TNode) => T["printOutput"] | null
|
|
3251
|
+
transform: (node: TNode) => T["output"] | null;
|
|
3252
|
+
print: (node: TNode) => T["printOutput"] | null;
|
|
2830
3253
|
};
|
|
2831
3254
|
//#endregion
|
|
2832
3255
|
//#region src/refs.d.ts
|
|
@@ -2860,9 +3283,36 @@ declare function collectImports<TImport>({
|
|
|
2860
3283
|
}: {
|
|
2861
3284
|
node: SchemaNode;
|
|
2862
3285
|
nameMapping: Map<string, string>;
|
|
2863
|
-
resolve: (schemaName: string) => TImport |
|
|
3286
|
+
resolve: (schemaName: string) => TImport | null;
|
|
2864
3287
|
}): Array<TImport>;
|
|
2865
3288
|
//#endregion
|
|
3289
|
+
//#region src/signature.d.ts
|
|
3290
|
+
/**
|
|
3291
|
+
* Computes a deterministic, shape-only signature (a fixed-length content hash) for a schema node.
|
|
3292
|
+
*
|
|
3293
|
+
* Two schemas share a signature when they are structurally identical, ignoring
|
|
3294
|
+
* documentation (`name`, `title`, `description`, `example`, `default`, `deprecated`)
|
|
3295
|
+
* and usage-slot flags (`optional`, `nullish`, `readOnly`, `writeOnly`). `nullable`
|
|
3296
|
+
* is kept because it changes the produced type. `ref` nodes compare by target name,
|
|
3297
|
+
* which also keeps the algorithm terminating on circular shapes.
|
|
3298
|
+
*
|
|
3299
|
+
* @example Two enums with different descriptions share a signature
|
|
3300
|
+
* ```ts
|
|
3301
|
+
* schemaSignature(createSchema({ type: 'enum', primitive: 'string', enumValues: ['a', 'b'], description: 'x' })) ===
|
|
3302
|
+
* schemaSignature(createSchema({ type: 'enum', primitive: 'string', enumValues: ['a', 'b'] }))
|
|
3303
|
+
* ```
|
|
3304
|
+
*/
|
|
3305
|
+
declare function schemaSignature(node: SchemaNode): string;
|
|
3306
|
+
/**
|
|
3307
|
+
* Returns `true` when two schema nodes are structurally identical under shape-only equality.
|
|
3308
|
+
*
|
|
3309
|
+
* @example
|
|
3310
|
+
* ```ts
|
|
3311
|
+
* isSchemaEqual(a, b) // a and b produce the same TypeScript type
|
|
3312
|
+
* ```
|
|
3313
|
+
*/
|
|
3314
|
+
declare function isSchemaEqual(a: SchemaNode, b: SchemaNode): boolean;
|
|
3315
|
+
//#endregion
|
|
2866
3316
|
//#region src/transformers.d.ts
|
|
2867
3317
|
/**
|
|
2868
3318
|
* Replaces a discriminator property's schema with a string enum of allowed values.
|
|
@@ -2901,6 +3351,7 @@ declare function setDiscriminatorEnum({
|
|
|
2901
3351
|
* ])
|
|
2902
3352
|
* ```
|
|
2903
3353
|
*/
|
|
3354
|
+
declare function mergeAdjacentObjectsLazy(members: Iterable<SchemaNode>): Generator<SchemaNode, void, undefined>;
|
|
2904
3355
|
declare function mergeAdjacentObjects(members: Array<SchemaNode>): Array<SchemaNode>;
|
|
2905
3356
|
/**
|
|
2906
3357
|
* Removes enum members that are covered by broader scalar primitives in the same union.
|
|
@@ -2923,7 +3374,7 @@ declare function setEnumName(propNode: SchemaNode, parentName: string | null | u
|
|
|
2923
3374
|
*
|
|
2924
3375
|
* `ParentOf` uses this map to find parent types.
|
|
2925
3376
|
*/
|
|
2926
|
-
type ParentNodeMap = [[InputNode, undefined], [OutputNode, undefined], [OperationNode, InputNode], [SchemaNode, InputNode |
|
|
3377
|
+
type ParentNodeMap = [[InputNode, undefined], [OutputNode, undefined], [OperationNode, InputNode], [RequestBodyNode, OperationNode], [ContentNode, RequestBodyNode | ResponseNode], [SchemaNode, InputNode | ContentNode | SchemaNode | PropertyNode | ParameterNode], [PropertyNode, SchemaNode], [ParameterNode, OperationNode], [ResponseNode, OperationNode]];
|
|
2927
3378
|
/**
|
|
2928
3379
|
* Resolves the parent node type for a given AST node type.
|
|
2929
3380
|
*
|
|
@@ -2970,25 +3421,40 @@ type VisitorContext<T extends Node = Node> = {
|
|
|
2970
3421
|
parent?: ParentOf<T>;
|
|
2971
3422
|
};
|
|
2972
3423
|
/**
|
|
2973
|
-
* Synchronous visitor
|
|
3424
|
+
* Synchronous visitor consumed by `transform`. Each optional callback runs
|
|
3425
|
+
* for the matching node type. Return a new node to replace it, or `undefined`
|
|
3426
|
+
* to leave it untouched.
|
|
2974
3427
|
*
|
|
2975
|
-
*
|
|
3428
|
+
* Plugins typically expose `transformer` so users can supply a `Visitor` that
|
|
3429
|
+
* rewrites operation IDs, drops descriptions, or otherwise tweaks the AST
|
|
3430
|
+
* before printing.
|
|
3431
|
+
*
|
|
3432
|
+
* @example Prefix every operationId
|
|
2976
3433
|
* ```ts
|
|
2977
3434
|
* const visitor: Visitor = {
|
|
2978
3435
|
* operation(node) {
|
|
2979
|
-
* return { ...node, operationId: `
|
|
3436
|
+
* return { ...node, operationId: `api_${node.operationId}` }
|
|
3437
|
+
* },
|
|
3438
|
+
* }
|
|
3439
|
+
* ```
|
|
3440
|
+
*
|
|
3441
|
+
* @example Strip schema descriptions
|
|
3442
|
+
* ```ts
|
|
3443
|
+
* const visitor: Visitor = {
|
|
3444
|
+
* schema(node) {
|
|
3445
|
+
* return { ...node, description: undefined }
|
|
2980
3446
|
* },
|
|
2981
3447
|
* }
|
|
2982
3448
|
* ```
|
|
2983
3449
|
*/
|
|
2984
3450
|
type Visitor = {
|
|
2985
|
-
input?(node: InputNode, context: VisitorContext<InputNode>):
|
|
2986
|
-
output?(node: OutputNode, context: VisitorContext<OutputNode>):
|
|
2987
|
-
operation?(node: OperationNode, context: VisitorContext<OperationNode>):
|
|
2988
|
-
schema?(node: SchemaNode, context: VisitorContext<SchemaNode>):
|
|
2989
|
-
property?(node: PropertyNode, context: VisitorContext<PropertyNode>):
|
|
2990
|
-
parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>):
|
|
2991
|
-
response?(node: ResponseNode, context: VisitorContext<ResponseNode>):
|
|
3451
|
+
input?(node: InputNode, context: VisitorContext<InputNode>): undefined | null | InputNode;
|
|
3452
|
+
output?(node: OutputNode, context: VisitorContext<OutputNode>): undefined | null | OutputNode;
|
|
3453
|
+
operation?(node: OperationNode, context: VisitorContext<OperationNode>): undefined | null | OperationNode;
|
|
3454
|
+
schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): undefined | null | SchemaNode;
|
|
3455
|
+
property?(node: PropertyNode, context: VisitorContext<PropertyNode>): undefined | null | PropertyNode;
|
|
3456
|
+
parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): undefined | null | ParameterNode;
|
|
3457
|
+
response?(node: ResponseNode, context: VisitorContext<ResponseNode>): undefined | null | ResponseNode;
|
|
2992
3458
|
};
|
|
2993
3459
|
/**
|
|
2994
3460
|
* Utility type for values that can be returned directly or asynchronously.
|
|
@@ -3007,13 +3473,13 @@ type MaybePromise<T> = T | Promise<T>;
|
|
|
3007
3473
|
* ```
|
|
3008
3474
|
*/
|
|
3009
3475
|
type AsyncVisitor = {
|
|
3010
|
-
input?(node: InputNode, context: VisitorContext<InputNode>): MaybePromise<
|
|
3011
|
-
output?(node: OutputNode, context: VisitorContext<OutputNode>): MaybePromise<
|
|
3012
|
-
operation?(node: OperationNode, context: VisitorContext<OperationNode>): MaybePromise<
|
|
3013
|
-
schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): MaybePromise<
|
|
3014
|
-
property?(node: PropertyNode, context: VisitorContext<PropertyNode>): MaybePromise<
|
|
3015
|
-
parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): MaybePromise<
|
|
3016
|
-
response?(node: ResponseNode, context: VisitorContext<ResponseNode>): MaybePromise<
|
|
3476
|
+
input?(node: InputNode, context: VisitorContext<InputNode>): MaybePromise<undefined | null | InputNode>;
|
|
3477
|
+
output?(node: OutputNode, context: VisitorContext<OutputNode>): MaybePromise<undefined | null | OutputNode>;
|
|
3478
|
+
operation?(node: OperationNode, context: VisitorContext<OperationNode>): MaybePromise<undefined | null | OperationNode>;
|
|
3479
|
+
schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): MaybePromise<undefined | null | SchemaNode>;
|
|
3480
|
+
property?(node: PropertyNode, context: VisitorContext<PropertyNode>): MaybePromise<undefined | null | PropertyNode>;
|
|
3481
|
+
parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): MaybePromise<undefined | null | ParameterNode>;
|
|
3482
|
+
response?(node: ResponseNode, context: VisitorContext<ResponseNode>): MaybePromise<undefined | null | ResponseNode>;
|
|
3017
3483
|
};
|
|
3018
3484
|
/**
|
|
3019
3485
|
* Visitor used by `collect`.
|
|
@@ -3028,13 +3494,13 @@ type AsyncVisitor = {
|
|
|
3028
3494
|
* ```
|
|
3029
3495
|
*/
|
|
3030
3496
|
type CollectVisitor<T> = {
|
|
3031
|
-
input?(node: InputNode, context: VisitorContext<InputNode>): T | undefined;
|
|
3032
|
-
output?(node: OutputNode, context: VisitorContext<OutputNode>): T | undefined;
|
|
3033
|
-
operation?(node: OperationNode, context: VisitorContext<OperationNode>): T | undefined;
|
|
3034
|
-
schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): T | undefined;
|
|
3035
|
-
property?(node: PropertyNode, context: VisitorContext<PropertyNode>): T | undefined;
|
|
3036
|
-
parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): T | undefined;
|
|
3037
|
-
response?(node: ResponseNode, context: VisitorContext<ResponseNode>): T | undefined;
|
|
3497
|
+
input?(node: InputNode, context: VisitorContext<InputNode>): T | null | undefined;
|
|
3498
|
+
output?(node: OutputNode, context: VisitorContext<OutputNode>): T | null | undefined;
|
|
3499
|
+
operation?(node: OperationNode, context: VisitorContext<OperationNode>): T | null | undefined;
|
|
3500
|
+
schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): T | null | undefined;
|
|
3501
|
+
property?(node: PropertyNode, context: VisitorContext<PropertyNode>): T | null | undefined;
|
|
3502
|
+
parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): T | null | undefined;
|
|
3503
|
+
response?(node: ResponseNode, context: VisitorContext<ResponseNode>): T | null | undefined;
|
|
3038
3504
|
};
|
|
3039
3505
|
/**
|
|
3040
3506
|
* Options for `transform`.
|
|
@@ -3101,11 +3567,14 @@ type CollectOptions<T> = CollectVisitor<T> & {
|
|
|
3101
3567
|
parent?: Node;
|
|
3102
3568
|
};
|
|
3103
3569
|
/**
|
|
3104
|
-
*
|
|
3105
|
-
*
|
|
3106
|
-
* (default: `WALK_CONCURRENCY`).
|
|
3570
|
+
* Async depth-first traversal for side effects. Visitor return values are
|
|
3571
|
+
* ignored. Use `transform` when you want to rewrite nodes.
|
|
3107
3572
|
*
|
|
3108
|
-
*
|
|
3573
|
+
* Sibling nodes at each depth run concurrently up to `options.concurrency`
|
|
3574
|
+
* (defaults to `WALK_CONCURRENCY`). Higher values overlap I/O-bound visitor
|
|
3575
|
+
* work; lower values reduce memory pressure.
|
|
3576
|
+
*
|
|
3577
|
+
* @example Log every operation
|
|
3109
3578
|
* ```ts
|
|
3110
3579
|
* await walk(root, {
|
|
3111
3580
|
* operation(node) {
|
|
@@ -3114,20 +3583,20 @@ type CollectOptions<T> = CollectVisitor<T> & {
|
|
|
3114
3583
|
* })
|
|
3115
3584
|
* ```
|
|
3116
3585
|
*
|
|
3117
|
-
* @example
|
|
3586
|
+
* @example Only visit the root node
|
|
3118
3587
|
* ```ts
|
|
3119
|
-
*
|
|
3120
|
-
* await walk(root, { depth: 'shallow', root: () => {} })
|
|
3588
|
+
* await walk(root, { depth: 'shallow', input: () => {} })
|
|
3121
3589
|
* ```
|
|
3122
3590
|
*/
|
|
3123
3591
|
declare function walk(node: Node, options: WalkOptions): Promise<void>;
|
|
3124
3592
|
/**
|
|
3125
|
-
*
|
|
3593
|
+
* Synchronous depth-first transform. Each visitor callback gets a chance to
|
|
3594
|
+
* return a replacement node; `undefined` keeps the original.
|
|
3126
3595
|
*
|
|
3127
|
-
*
|
|
3128
|
-
*
|
|
3596
|
+
* The transform is immutable. The original tree is not mutated; a new tree
|
|
3597
|
+
* is returned. Use `depth: 'shallow'` to skip recursion into children.
|
|
3129
3598
|
*
|
|
3130
|
-
* @example
|
|
3599
|
+
* @example Prefix every operationId
|
|
3131
3600
|
* ```ts
|
|
3132
3601
|
* const next = transform(root, {
|
|
3133
3602
|
* operation(node) {
|
|
@@ -3136,10 +3605,12 @@ declare function walk(node: Node, options: WalkOptions): Promise<void>;
|
|
|
3136
3605
|
* })
|
|
3137
3606
|
* ```
|
|
3138
3607
|
*
|
|
3139
|
-
* @example
|
|
3608
|
+
* @example Replace only the root node
|
|
3140
3609
|
* ```ts
|
|
3141
|
-
*
|
|
3142
|
-
*
|
|
3610
|
+
* const next = transform(root, {
|
|
3611
|
+
* depth: 'shallow',
|
|
3612
|
+
* input: (node) => ({ ...node, meta: { ...node.meta, title: 'Rewritten' } }),
|
|
3613
|
+
* })
|
|
3143
3614
|
* ```
|
|
3144
3615
|
*/
|
|
3145
3616
|
declare function transform(node: InputNode, options: TransformOptions): InputNode;
|
|
@@ -3151,23 +3622,33 @@ declare function transform(node: ParameterNode, options: TransformOptions): Para
|
|
|
3151
3622
|
declare function transform(node: ResponseNode, options: TransformOptions): ResponseNode;
|
|
3152
3623
|
declare function transform(node: Node, options: TransformOptions): Node;
|
|
3153
3624
|
/**
|
|
3154
|
-
*
|
|
3625
|
+
* Lazy depth-first collection pass. Yields every non-null value returned by
|
|
3626
|
+
* the visitor callbacks. Use `collect` for the eager array form.
|
|
3155
3627
|
*
|
|
3156
|
-
*
|
|
3157
|
-
*
|
|
3158
|
-
* @example
|
|
3628
|
+
* @example Collect every operationId
|
|
3159
3629
|
* ```ts
|
|
3160
|
-
* const ids =
|
|
3630
|
+
* const ids: string[] = []
|
|
3631
|
+
* for (const id of collectLazy<string>(root, {
|
|
3161
3632
|
* operation(node) {
|
|
3162
3633
|
* return node.operationId
|
|
3163
3634
|
* },
|
|
3164
|
-
* })
|
|
3635
|
+
* })) {
|
|
3636
|
+
* ids.push(id)
|
|
3637
|
+
* }
|
|
3165
3638
|
* ```
|
|
3639
|
+
*/
|
|
3640
|
+
declare function collectLazy<T>(node: Node, options: CollectOptions<T>): Generator<T, void, undefined>;
|
|
3641
|
+
/**
|
|
3642
|
+
* Eager depth-first collection pass. Returns an array of every non-null value
|
|
3643
|
+
* the visitor callbacks return.
|
|
3166
3644
|
*
|
|
3167
|
-
* @example
|
|
3645
|
+
* @example Collect every operationId
|
|
3168
3646
|
* ```ts
|
|
3169
|
-
*
|
|
3170
|
-
*
|
|
3647
|
+
* const ids = collect<string>(root, {
|
|
3648
|
+
* operation(node) {
|
|
3649
|
+
* return node.operationId
|
|
3650
|
+
* },
|
|
3651
|
+
* })
|
|
3171
3652
|
* ```
|
|
3172
3653
|
*/
|
|
3173
3654
|
declare function collect<T>(node: Node, options: CollectOptions<T>): Array<T>;
|
|
@@ -3194,13 +3675,6 @@ declare function syncSchemaRef(node: SchemaNode): SchemaNode;
|
|
|
3194
3675
|
* types, returns `true` only when `representation` is `'string'` rather than `'date'`.
|
|
3195
3676
|
*/
|
|
3196
3677
|
declare function isStringType(node: SchemaNode): boolean;
|
|
3197
|
-
/**
|
|
3198
|
-
* Applies casing rules to parameter names and returns a new parameter array.
|
|
3199
|
-
*
|
|
3200
|
-
* Use this before passing parameters to schema builders so output property keys match
|
|
3201
|
-
* the desired casing while preserving `OperationNode.parameters` for other consumers.
|
|
3202
|
-
* The input array is not mutated. When `casing` is not set, the original array is returned unchanged.
|
|
3203
|
-
*/
|
|
3204
3678
|
declare function caseParams(params: Array<ParameterNode>, casing: 'camelcase' | undefined): Array<ParameterNode>;
|
|
3205
3679
|
/**
|
|
3206
3680
|
* Creates a single-property object schema used as a discriminator literal.
|
|
@@ -3361,7 +3835,7 @@ declare function extractStringsFromNodes(nodes: Array<CodeNode> | undefined): st
|
|
|
3361
3835
|
/**
|
|
3362
3836
|
* Resolves the schema name of a ref node, falling back through `ref` → `name` → nested `schema.name`.
|
|
3363
3837
|
*
|
|
3364
|
-
* Returns `
|
|
3838
|
+
* Returns `null` for non-ref nodes or when no name can be resolved. Use this to get a schema's
|
|
3365
3839
|
* identifier for type definitions or error messages.
|
|
3366
3840
|
*
|
|
3367
3841
|
* @example
|
|
@@ -3370,56 +3844,8 @@ declare function extractStringsFromNodes(nodes: Array<CodeNode> | undefined): st
|
|
|
3370
3844
|
* // => 'Pet'
|
|
3371
3845
|
* ```
|
|
3372
3846
|
*/
|
|
3373
|
-
declare function resolveRefName(node: SchemaNode | undefined): string |
|
|
3374
|
-
/**
|
|
3375
|
-
* Collects every named schema referenced (transitively) from a node via ref edges.
|
|
3376
|
-
*
|
|
3377
|
-
* Refs are followed by name only — the resolved `node.schema` is not traversed inline.
|
|
3378
|
-
* Use this to determine schema dependencies, build reference graphs, or detect what schemas need to be emitted.
|
|
3379
|
-
*
|
|
3380
|
-
* @example Collect refs from a single schema
|
|
3381
|
-
* ```ts
|
|
3382
|
-
* const names = collectReferencedSchemaNames(petSchema)
|
|
3383
|
-
* // → Set { 'Category', 'Tag' }
|
|
3384
|
-
* ```
|
|
3385
|
-
*
|
|
3386
|
-
* @example Accumulate refs from multiple schemas into one set
|
|
3387
|
-
* ```ts
|
|
3388
|
-
* const out = new Set<string>()
|
|
3389
|
-
* for (const schema of schemas) {
|
|
3390
|
-
* collectReferencedSchemaNames(schema, out)
|
|
3391
|
-
* }
|
|
3392
|
-
* ```
|
|
3393
|
-
*/
|
|
3847
|
+
declare function resolveRefName(node: SchemaNode | undefined): string | null;
|
|
3394
3848
|
declare function collectReferencedSchemaNames(node: SchemaNode | undefined, out?: Set<string>): Set<string>;
|
|
3395
|
-
/**
|
|
3396
|
-
* Collects the names of all top-level schemas transitively used by a set of operations.
|
|
3397
|
-
*
|
|
3398
|
-
* An operation uses a schema when any of its parameters, request body content, or responses
|
|
3399
|
-
* reference it — directly or indirectly through other named schemas.
|
|
3400
|
-
* The walk is iterative and safe against reference cycles.
|
|
3401
|
-
*
|
|
3402
|
-
* Use this together with `include` filters to determine which schemas from `components/schemas`
|
|
3403
|
-
* are reachable from the allowed operations, so that schemas used only by excluded operations
|
|
3404
|
-
* are not generated.
|
|
3405
|
-
*
|
|
3406
|
-
* @example Only generate schemas referenced by included operations
|
|
3407
|
-
* ```ts
|
|
3408
|
-
* const includedOps = inputNode.operations.filter(op => resolver.resolveOptions(op, { options, include }) !== null)
|
|
3409
|
-
* const allowed = collectUsedSchemaNames(includedOps, inputNode.schemas)
|
|
3410
|
-
*
|
|
3411
|
-
* for (const schema of inputNode.schemas) {
|
|
3412
|
-
* if (schema.name && !allowed.has(schema.name)) continue
|
|
3413
|
-
* // … generate schema
|
|
3414
|
-
* }
|
|
3415
|
-
* ```
|
|
3416
|
-
*
|
|
3417
|
-
* @example Check whether a specific schema is needed
|
|
3418
|
-
* ```ts
|
|
3419
|
-
* const allowed = collectUsedSchemaNames(includedOps, inputNode.schemas)
|
|
3420
|
-
* allowed.has('OrderStatus') // false when no included operation references OrderStatus
|
|
3421
|
-
* ```
|
|
3422
|
-
*/
|
|
3423
3849
|
declare function collectUsedSchemaNames(operations: ReadonlyArray<OperationNode>, schemas: ReadonlyArray<SchemaNode>): Set<string>;
|
|
3424
3850
|
/**
|
|
3425
3851
|
* Identifies all schemas that participate in circular dependency chains, including direct self-loops.
|
|
@@ -3447,5 +3873,5 @@ declare function containsCircularRef(node: SchemaNode | undefined, {
|
|
|
3447
3873
|
excludeName?: string;
|
|
3448
3874
|
}): boolean;
|
|
3449
3875
|
//#endregion
|
|
3450
|
-
export { type ArraySchemaNode, type ArrowFunctionNode, AsyncVisitor, type BaseNode, type BreakNode, type CodeNode, CollectOptions, CollectVisitor, type ComplexSchemaType, type ConstNode, type DateSchemaNode, type DatetimeSchemaNode, DistributiveOmit, type EnumSchemaNode, type EnumValueNode, type ExportNode, type FileNode, type FormatStringSchemaNode, type FunctionNode, type FunctionNodeType, type FunctionParamNode, type FunctionParameterNode, type FunctionParametersNode, type HttpMethod, type HttpStatusCode, type ImportNode, InferSchema, InferSchemaNode, type InputMeta, type InputNode, type IntersectionSchemaNode, type Ipv4SchemaNode, type Ipv6SchemaNode, type JSDocNode, type JsxNode, type MediaType, Node, type NodeKind, type NumberSchemaNode, type ObjectSchemaNode, type OperationNode, OperationParamsResolver, type OutputNode, type ParameterGroupNode, type ParameterLocation, type ParameterNode, type ParamsTypeNode, ParentOf, ParserOptions, type PrimitiveSchemaType, Printer, PrinterFactoryOptions, PrinterPartial, type PropertyNode, RefMap, type RefSchemaNode, type ResponseNode, ScalarPrimitive, type ScalarSchemaNode, type ScalarSchemaType, type SchemaNode, type SchemaNodeByType, type SchemaType, type SourceNode, type SpecialSchemaType, type StatusCode, type StringSchemaNode, type TextNode, type TimeSchemaNode, TransformOptions, type TypeDeclarationNode, type TypeNode, type UnionSchemaNode, type UrlSchemaNode, UserFileNode, Visitor, VisitorContext, VisitorDepth, WalkOptions, caseParams, childName, collect, collectImports, collectReferencedSchemaNames, collectUsedSchemaNames, containsCircularRef, createArrowFunction, createBreak, createConst, createDiscriminantNode, createExport, createFile, createFunction, createFunctionParameter, createFunctionParameters, createImport, createInput, createJsx, createOperation, createOperationParams, createOutput, createParameter, createParameterGroup, createParamsType, createPrinterFactory, createProperty, createResponse, createSchema, createSource, createText, createType, definePrinter, enumPropName, extractRefName, extractStringsFromNodes, findCircularSchemas, findDiscriminator, httpMethods, isInputNode, isOperationNode, isOutputNode, isScalarPrimitive, isSchemaNode, isStringType, mediaTypes, mergeAdjacentObjects, narrowSchema, nodeKinds, resolveRefName, schemaTypes, setDiscriminatorEnum, setEnumName, simplifyUnion, syncOptionality, syncSchemaRef, transform, walk };
|
|
3876
|
+
export { type ArraySchemaNode, type ArrowFunctionNode, AsyncVisitor, type BaseNode, type BreakNode, BuildDedupePlanOptions, type CodeNode, CollectOptions, CollectVisitor, type ComplexSchemaType, type ConstNode, type DateSchemaNode, type DatetimeSchemaNode, DedupeCanonical, DedupePlan, DispatchRule, DistributiveOmit, type EnumSchemaNode, type EnumValueNode, type ExportNode, type FileNode, type FormatStringSchemaNode, type FunctionNode, type FunctionNodeType, type FunctionParamNode, type FunctionParameterNode, type FunctionParametersNode, type GenericOperationNode, type HttpMethod, type HttpOperationNode, type HttpStatusCode, type ImportNode, InferSchema, InferSchemaNode, type InputMeta, type InputNode, type InputStreamNode, type IntersectionSchemaNode, type Ipv4SchemaNode, type Ipv6SchemaNode, type JSDocNode, type JsxNode, type MediaType, Node, type NodeKind, type NumberSchemaNode, type ObjectSchemaNode, type OperationNode, type OperationNodeBase, OperationParamsResolver, type OperationProtocol, type OutputNode, type ParameterGroupNode, type ParameterLocation, type ParameterNode, type ParamsTypeNode, ParentOf, ParserOptions, type PrimitiveSchemaType, Printer, PrinterFactoryOptions, PrinterPartial, type PropertyNode, RefMap, type RefSchemaNode, type ResponseNode, ScalarPrimitive, type ScalarSchemaNode, type ScalarSchemaType, SchemaDialect, type SchemaNode, type SchemaNodeByType, type SchemaType, type SourceNode, type SpecialSchemaType, type StatusCode, type StringSchemaNode, type TextNode, type TimeSchemaNode, TransformOptions, type TypeDeclarationNode, type TypeNode, type UnionSchemaNode, type UrlSchemaNode, UserFileNode, Visitor, VisitorContext, VisitorDepth, WalkOptions, applyDedupe, buildDedupePlan, caseParams, childName, collect, collectImports, collectLazy, collectReferencedSchemaNames, collectUsedSchemaNames, containsCircularRef, createArrowFunction, createBreak, createConst, createContent, createDiscriminantNode, createExport, createFile, createFunction, createFunctionParameter, createFunctionParameters, createImport, createInput, createJsx, createOperation, createOperationParams, createOutput, createParameter, createParameterGroup, createParamsType, createPrinterFactory, createProperty, createRequestBody, createResponse, createSchema, createSource, createStreamInput, createText, createType, definePrinter, defineSchemaDialect, dispatch, enumPropName, extractRefName, extractStringsFromNodes, findCircularSchemas, findDiscriminator, httpMethods, isHttpOperationNode, isInputNode, isOperationNode, isOutputNode, isScalarPrimitive, isSchemaEqual, isSchemaNode, isStringType, mediaTypes, mergeAdjacentObjects, mergeAdjacentObjectsLazy, narrowSchema, nodeKinds, resolveRefName, schemaSignature, schemaTypes, setDiscriminatorEnum, setEnumName, simplifyUnion, syncOptionality, syncSchemaRef, transform, update, walk };
|
|
3451
3877
|
//# sourceMappingURL=index.d.ts.map
|