@kubb/ast 5.0.0-beta.56 → 5.0.0-beta.58

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.
Files changed (59) hide show
  1. package/README.md +13 -9
  2. package/dist/{types-BL7RpQAE.d.ts → ast-ClnJg9BN.d.ts} +1630 -2443
  3. package/dist/chunk-CNktS9qV.js +17 -0
  4. package/dist/extractStringsFromNodes-Bn9cOos9.d.ts +14 -0
  5. package/dist/factory-C5gHvtLU.js +138 -0
  6. package/dist/factory-C5gHvtLU.js.map +1 -0
  7. package/dist/factory-JN-Ylfl6.cjs +155 -0
  8. package/dist/factory-JN-Ylfl6.cjs.map +1 -0
  9. package/dist/factory.cjs +31 -0
  10. package/dist/factory.d.ts +62 -0
  11. package/dist/factory.js +3 -0
  12. package/dist/index.cjs +56 -1751
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.ts +6 -47
  15. package/dist/index.js +7 -1697
  16. package/dist/index.js.map +1 -1
  17. package/dist/types-CB2oY8Dw.d.ts +769 -0
  18. package/dist/types.d.ts +4 -2
  19. package/dist/utils-C8bWAzhv.cjs +2696 -0
  20. package/dist/utils-C8bWAzhv.cjs.map +1 -0
  21. package/dist/utils-DN4XLVqz.js +2099 -0
  22. package/dist/utils-DN4XLVqz.js.map +1 -0
  23. package/dist/utils.cjs +12 -1
  24. package/dist/utils.d.ts +21 -2
  25. package/dist/utils.js +2 -2
  26. package/package.json +5 -1
  27. package/src/dedupe.ts +1 -1
  28. package/src/factory.ts +22 -764
  29. package/src/guards.ts +1 -53
  30. package/src/index.ts +20 -39
  31. package/src/mocks.ts +6 -1
  32. package/src/node.ts +128 -0
  33. package/src/nodes/base.ts +3 -12
  34. package/src/nodes/code.ts +115 -0
  35. package/src/nodes/content.ts +19 -0
  36. package/src/nodes/file.ts +54 -0
  37. package/src/nodes/function.ts +222 -147
  38. package/src/nodes/index.ts +11 -3
  39. package/src/nodes/input.ts +37 -0
  40. package/src/nodes/operation.ts +59 -1
  41. package/src/nodes/output.ts +23 -0
  42. package/src/nodes/parameter.ts +33 -0
  43. package/src/nodes/property.ts +36 -0
  44. package/src/nodes/requestBody.ts +23 -1
  45. package/src/nodes/response.ts +39 -1
  46. package/src/nodes/schema.ts +72 -0
  47. package/src/printer.ts +3 -3
  48. package/src/registry.ts +70 -0
  49. package/src/transformers.ts +2 -2
  50. package/src/types.ts +6 -4
  51. package/src/utils/ast.ts +103 -243
  52. package/src/utils/extractStringsFromNodes.ts +34 -0
  53. package/src/utils/index.ts +44 -0
  54. package/src/visitor.ts +3 -47
  55. package/dist/chunk-C0LytTxp.js +0 -8
  56. package/dist/utils-0p8ZO287.js +0 -570
  57. package/dist/utils-0p8ZO287.js.map +0 -1
  58. package/dist/utils-cdQ6Pzyi.cjs +0 -726
  59. package/dist/utils-cdQ6Pzyi.cjs.map +0 -1
@@ -1,166 +1,125 @@
1
- import { t as __name } from "./chunk-C0LytTxp.js";
1
+ import { n as __name } from "./chunk-CNktS9qV.js";
2
2
 
3
- //#region src/constants.d.ts
3
+ //#region src/nodes/base.d.ts
4
4
  /**
5
- * Traversal depth for AST visitor utilities.
5
+ * `kind` values used by AST nodes.
6
6
  *
7
- * - `'shallow'` visits only the immediate node, skipping children.
8
- * - `'deep'` recursively visits all descendant nodes.
7
+ * @example
8
+ * ```ts
9
+ * const kind: NodeKind = 'Schema'
10
+ * ```
9
11
  */
10
- type VisitorDepth = 'shallow' | 'deep';
12
+ type NodeKind = 'Input' | 'Output' | 'Operation' | 'Schema' | 'Property' | 'Parameter' | 'Response' | 'RequestBody' | 'Content' | 'FunctionParameter' | 'FunctionParameters' | 'TypeLiteral' | 'IndexedAccessType' | 'ObjectBindingPattern' | 'Type' | 'File' | 'Import' | 'Export' | 'Source' | 'Const' | 'Function' | 'ArrowFunction' | 'Text' | 'Break' | 'Jsx';
11
13
  /**
12
- * Schema type discriminators used by all AST schema nodes.
14
+ * Base shape shared by all AST nodes.
13
15
  *
14
- * These values serve as stable discriminators across the AST (e.g., `schema.type === schemaTypes.object`).
15
- * Grouped by category: primitives (`string`, `number`, `boolean`), structural types (`object`, `array`, `union`),
16
- * and format-specific types (`date`, `uuid`, `email`). Use `isScalarPrimitive()` to check for scalar types.
16
+ * @example
17
+ * ```ts
18
+ * const base: BaseNode = { kind: 'Input' }
19
+ * ```
17
20
  */
18
- declare const schemaTypes: {
19
- /**
20
- * Text value.
21
- */
22
- readonly string: "string";
23
- /**
24
- * Floating-point number (`float`, `double`).
25
- */
26
- readonly number: "number";
27
- /**
28
- * Whole number (`int32`). Use `bigint` for `int64`.
29
- */
30
- readonly integer: "integer";
31
- /**
32
- * 64-bit integer (`int64`). Only used when `integerType` is set to `'bigint'`.
33
- */
34
- readonly bigint: "bigint";
35
- /**
36
- * Boolean value
37
- */
38
- readonly boolean: "boolean";
39
- /**
40
- * Explicit null value.
41
- */
42
- readonly null: "null";
43
- /**
44
- * Any value (no type restriction).
45
- */
46
- readonly any: "any";
47
- /**
48
- * Unknown value (must be narrowed before usage).
49
- */
50
- readonly unknown: "unknown";
51
- /**
52
- * No return value (`void`).
53
- */
54
- readonly void: "void";
55
- /**
56
- * Object with named properties.
57
- */
58
- readonly object: "object";
59
- /**
60
- * Sequential list of items.
61
- */
62
- readonly array: "array";
63
- /**
64
- * Fixed-length list with position-specific items.
65
- */
66
- readonly tuple: "tuple";
67
- /**
68
- * "One of" multiple schema members.
69
- */
70
- readonly union: "union";
71
- /**
72
- * "All of" multiple schema members.
73
- */
74
- readonly intersection: "intersection";
75
- /**
76
- * Enum schema.
77
- */
78
- readonly enum: "enum";
79
- /**
80
- * Reference to another schema.
81
- */
82
- readonly ref: "ref";
83
- /**
84
- * Calendar date (for example `2026-03-24`).
85
- */
86
- readonly date: "date";
87
- /**
88
- * Date-time value (for example `2026-03-24T09:00:00Z`).
89
- */
90
- readonly datetime: "datetime";
91
- /**
92
- * Time-only value (for example `09:00:00`).
93
- */
94
- readonly time: "time";
21
+ type BaseNode = {
95
22
  /**
96
- * UUID value.
23
+ * Node discriminator.
97
24
  */
98
- readonly uuid: "uuid";
25
+ kind: NodeKind;
26
+ };
27
+ //#endregion
28
+ //#region src/node.d.ts
29
+ /**
30
+ * Visitor callback names, one per traversable node kind. Kept in sync with the
31
+ * keys of `Visitor` in `visitor.ts`.
32
+ */
33
+ type VisitorKey = 'input' | 'output' | 'operation' | 'schema' | 'property' | 'parameter' | 'response';
34
+ /**
35
+ * Distributive `Omit` that preserves each member of a union.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * type A = { kind: 'a'; keep: string; drop: number }
40
+ * type B = { kind: 'b'; keep: boolean; drop: number }
41
+ * type Result = DistributiveOmit<A | B, 'drop'>
42
+ * // -> { kind: 'a'; keep: string } | { kind: 'b'; keep: boolean }
43
+ * ```
44
+ */
45
+ type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
46
+ /**
47
+ * Updates a schema's `optional` and `nullish` flags from a parent's `required`
48
+ * value and the schema's own `nullable`. Mirrors how OpenAPI parameters and
49
+ * object properties combine "required" and "nullable" into a single AST.
50
+ *
51
+ * - Non-required + non-nullable → `optional: true`.
52
+ * - Non-required + nullable → `nullish: true`.
53
+ * - Required → both flags cleared.
54
+ */
55
+ declare function syncOptionality(schema: SchemaNode, required: boolean): SchemaNode;
56
+ /**
57
+ * The single definition derived from one {@link defineNode} call: the node's
58
+ * `create` builder, its `is` guard, and the traversal metadata the registry
59
+ * collects into the visitor tables.
60
+ */
61
+ type NodeDef<TNode extends BaseNode = BaseNode, TInput = never> = {
99
62
  /**
100
- * Email address value.
63
+ * Node discriminator this definition owns.
101
64
  */
102
- readonly email: "email";
65
+ kind: NodeKind;
103
66
  /**
104
- * URL value.
67
+ * Builds a node from its input, applying `defaults` and the optional `build` hook.
105
68
  */
106
- readonly url: "url";
69
+ create: (input: TInput) => TNode;
107
70
  /**
108
- * IPv4 address value.
71
+ * Type guard matching this node kind.
109
72
  */
110
- readonly ipv4: "ipv4";
73
+ is: (node: unknown) => node is TNode;
111
74
  /**
112
- * IPv6 address value.
75
+ * Child node fields in traversal order. Feeds `VISITOR_KEYS`.
113
76
  */
114
- readonly ipv6: "ipv6";
77
+ children?: ReadonlyArray<string>;
115
78
  /**
116
- * Binary/blob value.
79
+ * Visitor callback name. Feeds `VISITOR_KEY_BY_KIND`.
117
80
  */
118
- readonly blob: "blob";
81
+ visitorKey?: VisitorKey;
119
82
  /**
120
- * Impossible value (`never`).
83
+ * When `true`, `create` is rerun after children are rebuilt so computed fields
84
+ * stay in sync. Feeds `nodeRebuilders`.
121
85
  */
122
- readonly never: "never";
86
+ rebuild?: boolean;
123
87
  };
124
- /**
125
- * HTTP method identifiers used by operation nodes.
126
- *
127
- * Includes all standard HTTP methods (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, TRACE).
128
- */
129
- declare const httpMethods: {
130
- readonly get: "GET";
131
- readonly post: "POST";
132
- readonly put: "PUT";
133
- readonly patch: "PATCH";
134
- readonly delete: "DELETE";
135
- readonly head: "HEAD";
136
- readonly options: "OPTIONS";
137
- readonly trace: "TRACE";
88
+ type DefineNodeConfig<TNode extends BaseNode, TInput, TBuilt extends object> = {
89
+ kind: TNode['kind'];
90
+ defaults?: Partial<TNode>;
91
+ build?: (input: TInput) => TBuilt;
92
+ children?: ReadonlyArray<string>;
93
+ visitorKey?: VisitorKey;
94
+ rebuild?: boolean;
138
95
  };
139
- //#endregion
140
- //#region src/nodes/base.d.ts
141
96
  /**
142
- * `kind` values used by AST nodes.
97
+ * Defines a node once and derives its `create` builder, `is` guard, and traversal
98
+ * metadata. `create` merges `defaults`, the `build` hook (or the raw input), and the
99
+ * `kind`, so node construction lives in one place without scattered `as` casts.
143
100
  *
144
- * @example
101
+ * Set `rebuild: true` when the `build` hook derives fields from children. After a
102
+ * transform rewrites those children, the registry reruns `create` so the derived
103
+ * fields stay correct.
104
+ *
105
+ * @example Simple node
145
106
  * ```ts
146
- * const kind: NodeKind = 'Schema'
107
+ * const importDef = defineNode<ImportNode>({ kind: 'Import' })
108
+ * const createImport = importDef.create
147
109
  * ```
148
- */
149
- 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';
150
- /**
151
- * Base shape shared by all AST nodes.
152
110
  *
153
- * @example
111
+ * @example Node with a build hook that is rerun on transform
154
112
  * ```ts
155
- * const base: BaseNode = { kind: 'Input' }
113
+ * const propertyDef = defineNode<PropertyNode, UserPropertyNode>({
114
+ * kind: 'Property',
115
+ * build: (props) => ({ ...props, required: props.required ?? false }),
116
+ * children: ['schema'],
117
+ * visitorKey: 'property',
118
+ * rebuild: true,
119
+ * })
156
120
  * ```
157
121
  */
158
- type BaseNode = {
159
- /**
160
- * Node discriminator.
161
- */
162
- kind: NodeKind;
163
- };
122
+ declare function defineNode<TNode extends BaseNode, TInput = Omit<TNode, 'kind'>, TBuilt extends object = Omit<TNode, 'kind'>>(config: DefineNodeConfig<TNode, TInput, TBuilt>): NodeDef<TNode, TInput>;
164
123
  //#endregion
165
124
  //#region src/nodes/code.d.ts
166
125
  /**
@@ -451,1877 +410,905 @@ type JsxNode = BaseNode & {
451
410
  * structured children in {@link SourceNode.nodes}.
452
411
  */
453
412
  type CodeNode = ConstNode | TypeNode | FunctionNode | ArrowFunctionNode | TextNode | BreakNode | JsxNode;
454
- //#endregion
455
- //#region src/nodes/property.d.ts
456
413
  /**
457
- * AST node representing one named object property.
414
+ * Definition for the {@link ConstNode}.
415
+ */
416
+ declare const constDef: NodeDef<ConstNode, Omit<ConstNode, "kind">>;
417
+ /**
418
+ * Creates a `ConstNode` representing a TypeScript `const` declaration.
458
419
  *
459
- * @example
420
+ * @example Exported constant with type and `as const`
460
421
  * ```ts
461
- * const property: PropertyNode = {
462
- * kind: 'Property',
463
- * name: 'id',
464
- * schema: createSchema({ type: 'integer' }),
465
- * required: true,
466
- * }
422
+ * createConst({ name: 'pets', export: true, type: 'Pet[]', asConst: true })
423
+ * // export const pets: Pet[] = ... as const
467
424
  * ```
468
425
  */
469
- type PropertyNode = BaseNode & {
470
- /**
471
- * Node kind.
472
- */
473
- kind: 'Property';
474
- /**
475
- * Property key.
476
- */
477
- name: string;
478
- /**
479
- * Property schema.
480
- */
481
- schema: SchemaNode;
482
- /**
483
- * Whether the property is required.
484
- */
485
- required: boolean;
486
- };
487
- //#endregion
488
- //#region src/nodes/schema.d.ts
489
- type PrimitiveSchemaType =
490
- /**
491
- * Text value.
492
- */
493
- 'string'
494
- /**
495
- * Floating-point number.
496
- */
497
- | 'number'
498
- /**
499
- * Integer number.
500
- */
501
- | 'integer'
502
- /**
503
- * Big integer number.
504
- */
505
- | 'bigint'
506
- /**
507
- * Boolean value.
508
- */
509
- | 'boolean'
426
+ declare const createConst: (input: Omit<ConstNode, "kind">) => ConstNode;
510
427
  /**
511
- * Null value.
428
+ * Definition for the {@link TypeNode}.
512
429
  */
513
- | 'null'
430
+ declare const typeDef: NodeDef<TypeNode, Omit<TypeNode, "kind">>;
514
431
  /**
515
- * Any value.
432
+ * Creates a `TypeNode` representing a TypeScript `type` alias declaration.
433
+ *
434
+ * @example
435
+ * ```ts
436
+ * createType({ name: 'Pet', export: true })
437
+ * // export type Pet = ...
438
+ * ```
516
439
  */
517
- | 'any'
440
+ declare const createType: (input: Omit<TypeNode, "kind">) => TypeNode;
518
441
  /**
519
- * Unknown value.
442
+ * Definition for the {@link FunctionNode}.
520
443
  */
521
- | 'unknown'
444
+ declare const functionDef: NodeDef<FunctionNode, Omit<FunctionNode, "kind">>;
522
445
  /**
523
- * No value (`void`).
446
+ * Creates a `FunctionNode` representing a TypeScript `function` declaration.
447
+ *
448
+ * @example
449
+ * ```ts
450
+ * createFunction({ name: 'fetchPet', export: true, async: true, returnType: 'Pet' })
451
+ * // export async function fetchPet(): Promise<Pet> { ... }
452
+ * ```
524
453
  */
525
- | 'void'
454
+ declare const createFunction: (input: Omit<FunctionNode, "kind">) => FunctionNode;
526
455
  /**
527
- * Never value.
456
+ * Definition for the {@link ArrowFunctionNode}.
528
457
  */
529
- | 'never'
458
+ declare const arrowFunctionDef: NodeDef<ArrowFunctionNode, Omit<ArrowFunctionNode, "kind">>;
530
459
  /**
531
- * Object value.
460
+ * Creates an `ArrowFunctionNode` representing a TypeScript arrow function.
461
+ *
462
+ * @example
463
+ * ```ts
464
+ * createArrowFunction({ name: 'double', export: true, params: 'n: number', singleLine: true })
465
+ * // export const double = (n: number) => ...
466
+ * ```
532
467
  */
533
- | 'object'
468
+ declare const createArrowFunction: (input: Omit<ArrowFunctionNode, "kind">) => ArrowFunctionNode;
534
469
  /**
535
- * Array value.
470
+ * Definition for the {@link TextNode}.
536
471
  */
537
- | 'array'
472
+ declare const textDef: NodeDef<TextNode, string>;
538
473
  /**
539
- * Date value.
474
+ * Creates a {@link TextNode} representing a raw string fragment in the source output.
475
+ *
476
+ * @example
477
+ * ```ts
478
+ * createText('return fetch(id)')
479
+ * // { kind: 'Text', value: 'return fetch(id)' }
480
+ * ```
540
481
  */
541
- | 'date';
482
+ declare const createText: (input: string) => TextNode;
542
483
  /**
543
- * Composite schema types.
484
+ * Definition for the {@link BreakNode}.
544
485
  */
545
- type ComplexSchemaType = 'tuple' | 'union' | 'intersection' | 'enum';
486
+ declare const breakDef: NodeDef<BreakNode, void>;
546
487
  /**
547
- * Schema types that need special handling in generators.
488
+ * Creates a {@link BreakNode} representing a line break in the source output.
489
+ *
490
+ * @example
491
+ * ```ts
492
+ * createBreak()
493
+ * // { kind: 'Break' }
494
+ * ```
548
495
  */
549
- type SpecialSchemaType = 'ref' | 'datetime' | 'time' | 'uuid' | 'email' | 'url' | 'ipv4' | 'ipv6' | 'blob';
496
+ declare function createBreak(): BreakNode;
550
497
  /**
551
- * All schema type strings.
498
+ * Definition for the {@link JsxNode}.
552
499
  */
553
- type SchemaType = PrimitiveSchemaType | ComplexSchemaType | SpecialSchemaType;
500
+ declare const jsxDef: NodeDef<JsxNode, string>;
554
501
  /**
555
- * Scalar schema types without extra object/array/ref structure.
502
+ * Creates a {@link JsxNode} representing a raw JSX fragment in the source output.
503
+ *
504
+ * @example
505
+ * ```ts
506
+ * createJsx('<>\n <a href={href}>Open</a>\n</>')
507
+ * // { kind: 'Jsx', value: '<>\n <a href={href}>Open</a>\n</>' }
508
+ * ```
556
509
  */
557
- type ScalarSchemaType = Exclude<SchemaType, 'object' | 'array' | 'tuple' | 'union' | 'intersection' | 'enum' | 'ref' | 'datetime' | 'date' | 'time' | 'string' | 'number' | 'integer' | 'bigint' | 'url' | 'uuid' | 'email'>;
510
+ declare const createJsx: (input: string) => JsxNode;
511
+ //#endregion
512
+ //#region src/infer.d.ts
558
513
  /**
559
- * Fields shared by all schema nodes.
514
+ * Shared parser options used by OAS-to-AST inference and parser flows.
560
515
  */
561
- type SchemaNodeBase = BaseNode & {
516
+ type ParserOptions = {
562
517
  /**
563
- * Node kind.
518
+ * How `format: 'date-time'` schemas are represented downstream.
519
+ * - `false` falls through to a plain `string` (no validation).
520
+ * - `'string'` emits a datetime string node.
521
+ * - `'stringOffset'` emits a datetime node with timezone offset.
522
+ * - `'stringLocal'` emits a local datetime node.
523
+ * - `'date'` emits a `date` node (JavaScript `Date` object).
564
524
  */
565
- kind: 'Schema';
525
+ dateType: false | 'string' | 'stringOffset' | 'stringLocal' | 'date';
566
526
  /**
567
- * Schema name for named definitions (for example, `"Pet"`).
568
- * Inline schemas omit this field.
569
- * `null` means kubb has processed this and determined there is no applicable name.
570
- * `undefined` means the name has not been set yet.
527
+ * How `type: 'integer'` (and `format: 'int64'`) maps to TypeScript.
528
+ * - `'bigint'` is exact for 64-bit IDs, but does not round-trip through JSON.
529
+ * - `'number'` fits most JSON APIs. Loses precision above `Number.MAX_SAFE_INTEGER`.
530
+ *
531
+ * @default 'bigint'
571
532
  */
572
- name?: string | null;
533
+ integerType?: 'number' | 'bigint';
573
534
  /**
574
- * Short schema title.
535
+ * AST type used when a schema's type cannot be inferred from the spec
536
+ * (`additionalProperties: true`, missing `type`, ...).
575
537
  */
576
- title?: string;
577
- /**
578
- * Schema description text.
579
- */
580
- description?: string;
581
- /**
582
- * Whether `null` is allowed.
583
- */
584
- nullable?: boolean;
585
- /**
586
- * Whether the field is optional.
587
- */
588
- optional?: boolean;
589
- /**
590
- * Both optional and nullable (`optional` + `nullable`).
591
- */
592
- nullish?: boolean;
593
- /**
594
- * Whether the schema is deprecated.
595
- */
596
- deprecated?: boolean;
597
- /**
598
- * Whether the schema is read-only.
599
- */
600
- readOnly?: boolean;
601
- /**
602
- * Whether the schema is write-only.
603
- */
604
- writeOnly?: boolean;
605
- /**
606
- * Default value.
607
- */
608
- default?: unknown;
609
- /**
610
- * Example value.
611
- */
612
- example?: unknown;
613
- /**
614
- * Base primitive type.
615
- * For example, this is `'string'` for a `uuid` schema.
616
- */
617
- primitive?: PrimitiveSchemaType;
618
- /**
619
- * Schema `format` value.
620
- */
621
- format?: string;
622
- };
623
- /**
624
- * Object schema with ordered properties.
625
- *
626
- * @example
627
- * ```ts
628
- * const objectSchema: ObjectSchemaNode = {
629
- * kind: 'Schema',
630
- * type: 'object',
631
- * properties: [],
632
- * }
633
- * ```
634
- */
635
- type ObjectSchemaNode = SchemaNodeBase & {
636
- /**
637
- * Schema type discriminator.
638
- */
639
- type: 'object';
640
- /**
641
- * Primitive type, always `'object'` for object schemas.
642
- */
643
- primitive: 'object';
644
- /**
645
- * Ordered object properties.
646
- */
647
- properties: Array<PropertyNode>;
648
- /**
649
- * Additional object properties behavior:
650
- * - `true`: allow any value
651
- * - `false`: reject unknown properties (maps to `.strict()` in Zod)
652
- * - `SchemaNode`: allow values that match that schema
653
- * - `undefined`: no additional properties constraint (open object)
654
- */
655
- additionalProperties?: SchemaNode | boolean;
656
- /**
657
- * Pattern-based property schemas.
658
- */
659
- patternProperties?: Record<string, SchemaNode>;
538
+ unknownType: 'any' | 'unknown' | 'void';
660
539
  /**
661
- * Minimum number of properties allowed.
540
+ * AST type used for completely empty schemas (`{}`).
662
541
  */
663
- minProperties?: number;
542
+ emptySchemaType: 'any' | 'unknown' | 'void';
664
543
  /**
665
- * Maximum number of properties allowed.
544
+ * Suffix appended to derived enum names when Kubb has to invent one
545
+ * (typically for inline enums on object properties).
666
546
  */
667
- maxProperties?: number;
547
+ enumSuffix: 'enum' | (string & {});
668
548
  };
669
549
  /**
670
- * Array-like schema (`array` or `tuple`).
671
- *
672
- * @example
673
- * ```ts
674
- * const arraySchema: ArraySchemaNode = {
675
- * kind: 'Schema',
676
- * type: 'array',
677
- * items: [],
678
- * }
679
- * ```
550
+ * Maps each `dateType` option value to the AST node produced by `format: 'date-time'`.
680
551
  */
681
- type ArraySchemaNode = SchemaNodeBase & {
682
- /**
683
- * Schema type discriminator (`array` or `tuple`).
684
- */
685
- type: 'array' | 'tuple';
686
- /**
687
- * Item schemas.
688
- */
689
- items?: Array<SchemaNode>;
690
- /**
691
- * Tuple rest-item schema for elements beyond positional `items`.
692
- */
693
- rest?: SchemaNode;
694
- /**
695
- * Minimum item count (or tuple length).
696
- */
697
- min?: number;
698
- /**
699
- * Maximum item count (or tuple length).
700
- */
701
- max?: number;
702
- /**
703
- * Whether all items must be unique.
704
- */
705
- unique?: boolean;
552
+ type DateTimeNodeByDateType = {
553
+ date: DateSchemaNode;
554
+ string: DatetimeSchemaNode;
555
+ stringOffset: DatetimeSchemaNode;
556
+ stringLocal: DatetimeSchemaNode;
557
+ false: StringSchemaNode;
706
558
  };
707
559
  /**
708
- * Shared shape for union and intersection schemas.
560
+ * Resolves the AST node produced by `format: 'date-time'` based on the `dateType` option.
709
561
  */
710
- type CompositeSchemaNodeBase = SchemaNodeBase & {
711
- /**
712
- * Member schemas.
713
- */
714
- members?: Array<SchemaNode>;
715
- };
562
+ type ResolveDateTimeNode<TDateType extends ParserOptions['dateType']> = DateTimeNodeByDateType[TDateType extends keyof DateTimeNodeByDateType ? TDateType : 'string'];
716
563
  /**
717
- * Union schema, often from `oneOf` or `anyOf`.
718
- *
719
- * @example
720
- * ```ts
721
- * const unionSchema: UnionSchemaNode = {
722
- * kind: 'Schema',
723
- * type: 'union',
724
- * members: [],
725
- * }
726
- * ```
564
+ * Ordered list of `[schema-shape, SchemaNode]` pairs.
565
+ * `InferSchemaNode` walks this tuple in order and returns the first matching node type.
727
566
  */
728
- type UnionSchemaNode = CompositeSchemaNodeBase & {
729
- /**
730
- * Schema type discriminator.
731
- */
567
+ type SchemaNodeMap<TDateType extends ParserOptions['dateType'] = 'string'> = [[{
568
+ $ref: string;
569
+ }, RefSchemaNode], [{
570
+ allOf: ReadonlyArray<unknown>;
571
+ properties: object;
572
+ }, IntersectionSchemaNode], [{
573
+ allOf: readonly [unknown, unknown, ...Array<unknown>];
574
+ }, IntersectionSchemaNode], [{
575
+ allOf: ReadonlyArray<unknown>;
576
+ }, SchemaNode], [{
577
+ oneOf: ReadonlyArray<unknown>;
578
+ }, UnionSchemaNode], [{
579
+ anyOf: ReadonlyArray<unknown>;
580
+ }, UnionSchemaNode], [{
581
+ const: null;
582
+ }, ScalarSchemaNode], [{
583
+ const: string | number | boolean;
584
+ }, EnumSchemaNode], [{
585
+ type: ReadonlyArray<string>;
586
+ }, UnionSchemaNode], [{
587
+ type: 'array';
588
+ enum: ReadonlyArray<unknown>;
589
+ }, ArraySchemaNode], [{
590
+ enum: ReadonlyArray<unknown>;
591
+ }, EnumSchemaNode], [{
592
+ type: 'enum';
593
+ }, EnumSchemaNode], [{
732
594
  type: 'union';
733
- /**
734
- * Discriminator property name from OpenAPI `discriminator.propertyName`.
735
- */
736
- discriminatorPropertyName?: string;
737
- /**
738
- * Logical strategy applied to union members: 'one' means exactly one member must be valid (from `oneOf`),
739
- * 'any' means any number of members can be valid (from `anyOf`).
740
- */
741
- strategy?: 'one' | 'any';
742
- };
743
- /**
744
- * Intersection schema, often from `allOf`.
745
- *
746
- * @example
747
- * ```ts
748
- * const intersectionSchema: IntersectionSchemaNode = {
749
- * kind: 'Schema',
750
- * type: 'intersection',
751
- * members: [],
752
- * }
753
- * ```
754
- */
755
- type IntersectionSchemaNode = CompositeSchemaNodeBase & {
756
- /**
757
- * Schema type discriminator.
758
- */
595
+ }, UnionSchemaNode], [{
759
596
  type: 'intersection';
760
- };
761
- /**
762
- * One named enum item.
763
- */
764
- type EnumValueNode = {
765
- /**
766
- * Enum item name.
767
- */
768
- name: string;
769
- /**
770
- * Enum item value.
771
- */
772
- value: string | number | boolean;
773
- /**
774
- * Primitive type of the enum value.
775
- */
776
- primitive: Extract<PrimitiveSchemaType, 'string' | 'number' | 'boolean'>;
777
- };
778
- /**
779
- * Enum schema node.
780
- *
781
- * @example
782
- * ```ts
783
- * const enumSchema: EnumSchemaNode = {
784
- * kind: 'Schema',
785
- * type: 'enum',
786
- * enumValues: ['a', 'b'],
787
- * }
788
- * ```
789
- */
790
- type EnumSchemaNode = SchemaNodeBase & {
791
- /**
792
- * Schema type discriminator.
793
- */
794
- type: 'enum';
795
- /**
796
- * Enum values in simple form.
797
- */
798
- enumValues?: Array<string | number | boolean | null>;
799
- /**
800
- * Enum values in named form.
801
- * If present, this is used instead of `enumValues`.
802
- */
803
- namedEnumValues?: Array<EnumValueNode>;
804
- };
805
- /**
806
- * Reference schema that points to another schema definition.
807
- *
808
- * @example
809
- * ```ts
810
- * const refSchema: RefSchemaNode = {
811
- * kind: 'Schema',
812
- * type: 'ref',
813
- * ref: '#/components/schemas/Pet',
814
- * }
815
- * ```
816
- */
817
- type RefSchemaNode = SchemaNodeBase & {
818
- /**
819
- * Schema type discriminator.
820
- */
597
+ }, IntersectionSchemaNode], [{
598
+ type: 'tuple';
599
+ }, ArraySchemaNode], [{
821
600
  type: 'ref';
822
- /**
823
- * Referenced schema name.
824
- * `null` means Kubb has processed this and determined there is no applicable name.
825
- */
826
- name?: string | null;
827
- /**
828
- * Original `$ref` path, for example, `#/components/schemas/Order`.
829
- * Used to resolve names later.
830
- */
831
- ref?: string;
832
- /**
833
- * Pattern copied from a sibling `pattern` field.
834
- */
835
- pattern?: string;
836
- /**
837
- * The fully-parsed schema this ref resolves to, so its structure (`primitive`, `properties`)
838
- * can be read without following the reference. Populated during OAS parsing when the
839
- * definition resolves, `null` when it can't or the ref is circular, and `undefined` when
840
- * resolution has not been attempted.
841
- */
842
- schema?: SchemaNode | null;
843
- };
844
- /**
845
- * Datetime schema.
846
- *
847
- * @example
848
- * ```ts
849
- * const datetimeSchema: DatetimeSchemaNode = { kind: 'Schema', type: 'datetime' }
850
- * ```
851
- */
852
- type DatetimeSchemaNode = SchemaNodeBase & {
853
- /**
854
- * Schema type discriminator.
855
- */
601
+ }, RefSchemaNode], [{
856
602
  type: 'datetime';
857
- /**
858
- * Whether the datetime includes a timezone offset (`dateType: 'stringOffset'`).
859
- */
860
- offset?: boolean;
861
- /**
862
- * Whether the datetime is local (no timezone, `dateType: 'stringLocal'`).
863
- */
864
- local?: boolean;
865
- };
866
- /**
867
- * Shared base for `date` and `time` schemas.
868
- */
869
- type TemporalSchemaNodeBase<T extends 'date' | 'time'> = SchemaNodeBase & {
870
- /**
871
- * Schema type discriminator.
872
- */
873
- type: T;
874
- /**
875
- * Output representation in generated code.
876
- */
877
- representation: 'date' | 'string';
878
- };
879
- /**
880
- * Date schema node.
881
- *
882
- * @example
883
- * ```ts
884
- * const dateSchema: DateSchemaNode = { kind: 'Schema', type: 'date', representation: 'string' }
885
- * ```
886
- */
887
- type DateSchemaNode = TemporalSchemaNodeBase<'date'>;
888
- /**
889
- * Time schema node.
890
- *
891
- * @example
892
- * ```ts
893
- * const timeSchema: TimeSchemaNode = { kind: 'Schema', type: 'time', representation: 'string' }
894
- * ```
895
- */
896
- type TimeSchemaNode = TemporalSchemaNodeBase<'time'>;
897
- /**
898
- * String schema node.
899
- *
900
- * @example
901
- * ```ts
902
- * const stringSchema: StringSchemaNode = { kind: 'Schema', type: 'string' }
903
- * ```
904
- */
905
- type StringSchemaNode = SchemaNodeBase & {
906
- /**
907
- * Schema type discriminator.
908
- */
909
- type: 'string';
910
- /**
911
- * Minimum string length.
912
- */
913
- min?: number;
914
- /**
915
- * Maximum string length.
916
- */
917
- max?: number;
918
- /**
919
- * Regex pattern.
920
- */
921
- pattern?: string;
922
- };
923
- /**
924
- * Numeric schema (`number`, `integer`, or `bigint`).
925
- *
926
- * @example
927
- * ```ts
928
- * const numberSchema: NumberSchemaNode = { kind: 'Schema', type: 'number' }
929
- * ```
930
- */
931
- type NumberSchemaNode = SchemaNodeBase & {
932
- /**
933
- * Schema type discriminator.
934
- */
935
- type: 'number' | 'integer' | 'bigint';
936
- /**
937
- * Minimum value.
938
- */
939
- min?: number;
940
- /**
941
- * Maximum value.
942
- */
943
- max?: number;
944
- /**
945
- * Exclusive minimum value.
946
- */
947
- exclusiveMinimum?: number;
948
- /**
949
- * Exclusive maximum value.
950
- */
951
- exclusiveMaximum?: number;
952
- /**
953
- * The value must be a multiple of this number.
954
- */
955
- multipleOf?: number;
956
- };
957
- /**
958
- * Scalar schema with no extra constraints.
959
- *
960
- * @example
961
- * ```ts
962
- * const anySchema: ScalarSchemaNode = { kind: 'Schema', type: 'any' }
963
- * ```
964
- */
965
- type ScalarSchemaNode = SchemaNodeBase & {
966
- /**
967
- * Schema type discriminator.
968
- */
969
- type: ScalarSchemaType;
970
- };
971
- /**
972
- * URL schema node.
973
- * Can include an OpenAPI-style path template for template literal types.
974
- *
975
- * @example
976
- * ```ts
977
- * const urlSchema: UrlSchemaNode = { kind: 'Schema', type: 'url', path: '/pets/{petId}' }
978
- * ```
979
- */
980
- type UrlSchemaNode = SchemaNodeBase & {
981
- /**
982
- * Schema type discriminator.
983
- */
603
+ }, DatetimeSchemaNode], [{
604
+ type: 'date';
605
+ }, DateSchemaNode], [{
606
+ type: 'time';
607
+ }, TimeSchemaNode], [{
984
608
  type: 'url';
985
- /**
986
- * OpenAPI-style path template, for example, `'/pets/{petId}'`.
987
- */
988
- path?: string;
989
- /**
990
- * Minimum string length.
991
- */
992
- min?: number;
993
- /**
994
- * Maximum string length.
995
- */
996
- max?: number;
997
- };
609
+ }, UrlSchemaNode], [{
610
+ type: 'object';
611
+ }, ObjectSchemaNode], [{
612
+ additionalProperties: boolean | {};
613
+ }, ObjectSchemaNode], [{
614
+ type: 'array';
615
+ }, ArraySchemaNode], [{
616
+ items: object;
617
+ }, ArraySchemaNode], [{
618
+ prefixItems: ReadonlyArray<unknown>;
619
+ }, ArraySchemaNode], [{
620
+ type: string;
621
+ format: 'date-time';
622
+ }, ResolveDateTimeNode<TDateType>], [{
623
+ type: string;
624
+ format: 'date';
625
+ }, DateSchemaNode], [{
626
+ type: string;
627
+ format: 'time';
628
+ }, TimeSchemaNode], [{
629
+ format: 'date-time';
630
+ }, ResolveDateTimeNode<TDateType>], [{
631
+ format: 'date';
632
+ }, DateSchemaNode], [{
633
+ format: 'time';
634
+ }, TimeSchemaNode], [{
635
+ type: 'string';
636
+ }, StringSchemaNode], [{
637
+ type: 'number';
638
+ }, NumberSchemaNode], [{
639
+ type: 'integer';
640
+ }, NumberSchemaNode], [{
641
+ type: 'bigint';
642
+ }, NumberSchemaNode], [{
643
+ type: string;
644
+ }, ScalarSchemaNode], [{
645
+ minLength: number;
646
+ }, StringSchemaNode], [{
647
+ maxLength: number;
648
+ }, StringSchemaNode], [{
649
+ pattern: string;
650
+ }, StringSchemaNode], [{
651
+ minimum: number;
652
+ }, NumberSchemaNode], [{
653
+ maximum: number;
654
+ }, NumberSchemaNode]];
998
655
  /**
999
- * Format-string schema for string-based formats that support length constraints.
1000
- *
1001
- * @example
1002
- * ```ts
1003
- * const uuidSchema: FormatStringSchemaNode = { kind: 'Schema', type: 'uuid', min: 36, max: 36 }
1004
- * ```
1005
- */
1006
- type FormatStringSchemaNode = SchemaNodeBase & {
1007
- /**
1008
- * Schema type discriminator.
1009
- */
1010
- type: 'uuid' | 'email';
1011
- /**
1012
- * Minimum string length.
1013
- */
1014
- min?: number;
1015
- /**
1016
- * Maximum string length.
1017
- */
1018
- max?: number;
1019
- };
1020
- /**
1021
- * IPv4 address schema node.
1022
- *
1023
- * @example
1024
- * ```ts
1025
- * const ipv4Schema: Ipv4SchemaNode = { kind: 'Schema', type: 'ipv4' }
1026
- * ```
1027
- */
1028
- type Ipv4SchemaNode = SchemaNodeBase & {
1029
- /**
1030
- * Schema type discriminator.
1031
- */
1032
- type: 'ipv4';
1033
- };
1034
- /**
1035
- * IPv6 address schema node.
1036
- *
1037
- * @example
1038
- * ```ts
1039
- * const ipv6Schema: Ipv6SchemaNode = { kind: 'Schema', type: 'ipv6' }
1040
- * ```
1041
- */
1042
- type Ipv6SchemaNode = SchemaNodeBase & {
1043
- /**
1044
- * Schema type discriminator.
1045
- */
1046
- type: 'ipv6';
1047
- };
1048
- /**
1049
- * Mapping from schema type literals to concrete schema node types.
1050
- * Used by `narrowSchema`.
1051
- */
1052
- type SchemaNodeByType = {
1053
- object: ObjectSchemaNode;
1054
- array: ArraySchemaNode;
1055
- tuple: ArraySchemaNode;
1056
- union: UnionSchemaNode;
1057
- intersection: IntersectionSchemaNode;
1058
- enum: EnumSchemaNode;
1059
- ref: RefSchemaNode;
1060
- datetime: DatetimeSchemaNode;
1061
- date: DateSchemaNode;
1062
- time: TimeSchemaNode;
1063
- string: StringSchemaNode;
1064
- number: NumberSchemaNode;
1065
- integer: NumberSchemaNode;
1066
- bigint: NumberSchemaNode;
1067
- boolean: ScalarSchemaNode;
1068
- null: ScalarSchemaNode;
1069
- any: ScalarSchemaNode;
1070
- unknown: ScalarSchemaNode;
1071
- void: ScalarSchemaNode;
1072
- never: ScalarSchemaNode;
1073
- uuid: FormatStringSchemaNode;
1074
- email: FormatStringSchemaNode;
1075
- url: UrlSchemaNode;
1076
- ipv4: Ipv4SchemaNode;
1077
- ipv6: Ipv6SchemaNode;
1078
- blob: ScalarSchemaNode;
1079
- };
1080
- /**
1081
- * Union of all schema node types.
1082
- */
1083
- type SchemaNode = ObjectSchemaNode | ArraySchemaNode | UnionSchemaNode | IntersectionSchemaNode | EnumSchemaNode | RefSchemaNode | DatetimeSchemaNode | DateSchemaNode | TimeSchemaNode | StringSchemaNode | NumberSchemaNode | UrlSchemaNode | FormatStringSchemaNode | Ipv4SchemaNode | Ipv6SchemaNode | ScalarSchemaNode;
1084
- //#endregion
1085
- //#region src/nodes/content.d.ts
1086
- /**
1087
- * AST node representing one content-type entry of a request body or response.
1088
- *
1089
- * One entry per content type declared in the spec (e.g. `application/json`,
1090
- * `multipart/form-data`), each carrying its own body schema.
1091
- *
1092
- * @example
1093
- * ```ts
1094
- * const content: ContentNode = {
1095
- * kind: 'Content',
1096
- * contentType: 'application/json',
1097
- * schema: createSchema({ type: 'string' }),
1098
- * }
1099
- * ```
1100
- */
1101
- type ContentNode = BaseNode & {
1102
- /**
1103
- * Node kind.
1104
- */
1105
- kind: 'Content';
1106
- /**
1107
- * The content type for this entry (e.g. `'application/json'`).
1108
- */
1109
- contentType: string;
1110
- /**
1111
- * Body schema for this content type.
1112
- */
1113
- schema?: SchemaNode;
1114
- /**
1115
- * Property keys to exclude from the generated type via `Omit<Type, Keys>`.
1116
- * Set when a referenced schema has `readOnly`/`writeOnly` fields that should be omitted.
1117
- */
1118
- keysToOmit?: Array<string> | null;
1119
- };
1120
- //#endregion
1121
- //#region src/nodes/file.d.ts
1122
- /**
1123
- * Supported file extensions.
1124
- */
1125
- type Extname = '.ts' | '.js' | '.tsx' | '.json' | `.${string}`;
1126
- type ImportName = string | Array<string | {
1127
- propertyName: string;
1128
- name?: string;
1129
- }>;
1130
- /**
1131
- * Represents a language-agnostic import/dependency declaration.
1132
- *
1133
- * @example Named import (TypeScript: `import { useState } from 'react'`)
1134
- * ```ts
1135
- * createImport({ name: ['useState'], path: 'react' })
1136
- * ```
1137
- *
1138
- * @example Default import (TypeScript: `import React from 'react'`)
1139
- * ```ts
1140
- * createImport({ name: 'React', path: 'react' })
1141
- * ```
1142
- *
1143
- * @example Type-only import (TypeScript: `import type { FC } from 'react'`)
1144
- * ```ts
1145
- * createImport({ name: ['FC'], path: 'react', isTypeOnly: true })
1146
- * ```
1147
- *
1148
- * @example Namespace import (TypeScript: `import * as React from 'react'`)
1149
- * ```ts
1150
- * createImport({ name: 'React', path: 'react', isNameSpace: true })
1151
- * ```
1152
- */
1153
- type ImportNode = BaseNode & {
1154
- kind: 'Import';
1155
- /**
1156
- * Import name(s) to be used.
1157
- * @example ['useState']
1158
- * @example 'React'
1159
- */
1160
- name: ImportName;
1161
- /**
1162
- * Path for the import.
1163
- * @example '@kubb/core'
1164
- */
1165
- path: string;
1166
- /**
1167
- * Add type-only import prefix.
1168
- * - `true` generates `import type { Type } from './path'`
1169
- * - `false` generates `import { Type } from './path'`
1170
- * @default false
1171
- */
1172
- isTypeOnly?: boolean | null;
1173
- /**
1174
- * Import entire module as namespace.
1175
- * - `true` generates `import * as Name from './path'`
1176
- * - `false` generates standard import
1177
- * @default false
1178
- */
1179
- isNameSpace?: boolean | null;
1180
- /**
1181
- * When set, the import path is resolved relative to this root.
1182
- */
1183
- root?: string | null;
1184
- };
1185
- /**
1186
- * Represents a language-agnostic export/public API declaration.
1187
- *
1188
- * @example Named export (TypeScript: `export { Pets } from './Pets'`)
1189
- * ```ts
1190
- * createExport({ name: ['Pets'], path: './Pets' })
1191
- * ```
1192
- *
1193
- * @example Type-only export (TypeScript: `export type { Pet } from './Pet'`)
1194
- * ```ts
1195
- * createExport({ name: ['Pet'], path: './Pet', isTypeOnly: true })
1196
- * ```
1197
- *
1198
- * @example Wildcard export (TypeScript: `export * from './utils'`)
1199
- * ```ts
1200
- * createExport({ path: './utils' })
1201
- * ```
1202
- *
1203
- * @example Namespace alias (TypeScript: `export * as utils from './utils'`)
1204
- * ```ts
1205
- * createExport({ name: 'utils', path: './utils', asAlias: true })
1206
- * ```
1207
- */
1208
- type ExportNode = BaseNode & {
1209
- kind: 'Export';
1210
- /**
1211
- * Export name(s) to be used. When omitted, generates a wildcard export.
1212
- * @example ['useState']
1213
- * @example 'React'
1214
- */
1215
- name?: string | Array<string> | null;
1216
- /**
1217
- * Path for the export.
1218
- * @example '@kubb/core'
1219
- */
1220
- path: string;
1221
- /**
1222
- * Add type-only export prefix.
1223
- * - `true` generates `export type { Type } from './path'`
1224
- * - `false` generates `export { Type } from './path'`
1225
- * @default false
1226
- */
1227
- isTypeOnly?: boolean | null;
1228
- /**
1229
- * Export as an aliased namespace.
1230
- * - `true` generates `export * as aliasName from './path'`
1231
- * - `false` generates a standard export
1232
- * @default false
1233
- */
1234
- asAlias?: boolean | null;
1235
- };
1236
- /**
1237
- * Represents a fragment of source code within a file.
1238
- *
1239
- * @example Named exportable source
1240
- * ```ts
1241
- * createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true, isIndexable: true })
1242
- * ```
1243
- *
1244
- * @example Inline unnamed code block
1245
- * ```ts
1246
- * createSource({ nodes: [createText('const x = 1')] })
1247
- * ```
1248
- */
1249
- type SourceNode = BaseNode & {
1250
- kind: 'Source';
1251
- /**
1252
- * Optional name identifying this source (used for deduplication and barrel generation).
1253
- */
1254
- name?: string | null;
1255
- /**
1256
- * Mark this source as a type-only export.
1257
- * @default false
1258
- */
1259
- isTypeOnly?: boolean | null;
1260
- /**
1261
- * Include `export` keyword in the generated source.
1262
- * @default false
1263
- */
1264
- isExportable?: boolean | null;
1265
- /**
1266
- * Include this source in barrel/index file generation.
1267
- * @default false
1268
- */
1269
- isIndexable?: boolean | null;
1270
- /**
1271
- * Structured child nodes representing the content of this source fragment, in DOM order.
1272
- * Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
1273
- */
1274
- nodes?: Array<CodeNode>;
1275
- };
656
+ * Infers the matching AST `SchemaNode` type from an input schema shape.
657
+ */
658
+ type InferSchemaNode<TSchema extends object, TDateType extends ParserOptions['dateType'] = 'string', TEntries extends ReadonlyArray<[object, SchemaNode]> = SchemaNodeMap<TDateType>> = TEntries extends [infer TEntry extends [object, SchemaNode], ...infer TRest extends ReadonlyArray<[object, SchemaNode]>] ? TSchema extends TEntry[0] ? TEntry[1] : InferSchemaNode<TSchema, TDateType, TRest> : SchemaNode;
659
+ //#endregion
660
+ //#region src/nodes/property.d.ts
1276
661
  /**
1277
- * Represents a fully resolved file in the AST.
1278
- *
1279
- * Created via `createFile()`, which computes the `id`, `name`, and `extname` from the input
1280
- * and deduplicates `imports`, `exports`, and `sources`.
662
+ * AST node representing one named object property.
1281
663
  *
1282
664
  * @example
1283
665
  * ```ts
1284
- * const file = createFile({
1285
- * baseName: 'petStore.ts',
1286
- * path: 'src/models/petStore.ts',
1287
- * sources: [createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true })],
1288
- * imports: [createImport({ name: ['z'], path: 'zod' })],
1289
- * exports: [createExport({ name: ['Pet'], path: './petStore' })],
1290
- * })
1291
- * // file.id = SHA256 hash of the path
1292
- * // file.name = 'petStore'
1293
- * // file.extname = '.ts'
666
+ * const property: PropertyNode = {
667
+ * kind: 'Property',
668
+ * name: 'id',
669
+ * schema: createSchema({ type: 'integer' }),
670
+ * required: true,
671
+ * }
1294
672
  * ```
1295
673
  */
1296
- type FileNode<TMeta extends object = object> = BaseNode & {
1297
- kind: 'File';
674
+ type PropertyNode = BaseNode & {
1298
675
  /**
1299
- * Unique identifier derived from a SHA256 hash of the file path. Computed
1300
- * by `createFile`; callers do not need to provide it.
676
+ * Node kind.
1301
677
  */
1302
- id: string;
678
+ kind: 'Property';
1303
679
  /**
1304
- * File name without extension, derived from `baseName`.
1305
- * @link https://nodejs.org/api/path.html#pathformatpathobject
680
+ * Property key.
1306
681
  */
1307
682
  name: string;
1308
683
  /**
1309
- * File base name, including extension.
1310
- * Based on UNIX basename: `${name}${extname}`
1311
- * @link https://nodejs.org/api/path.html#pathbasenamepath-suffix
1312
- */
1313
- baseName: `${string}.${string}`;
1314
- /**
1315
- * Full qualified path to the file.
1316
- */
1317
- path: string;
1318
- /**
1319
- * File extension extracted from `baseName`.
1320
- */
1321
- extname: Extname;
1322
- /**
1323
- * Deduplicated list of source code fragments.
1324
- */
1325
- sources: Array<SourceNode>;
1326
- /**
1327
- * Deduplicated list of import declarations.
1328
- */
1329
- imports: Array<ImportNode>;
1330
- /**
1331
- * Deduplicated list of export declarations.
1332
- */
1333
- exports: Array<ExportNode>;
1334
- /**
1335
- * Optional metadata attached to this file (used by plugins for barrel generation etc.).
1336
- */
1337
- meta?: TMeta;
1338
- /**
1339
- * Optional banner prepended to the generated file content.
1340
- * Accepts `null` so `resolver.resolveBanner()` results can be passed directly.
684
+ * Property schema.
1341
685
  */
1342
- banner?: string | null;
686
+ schema: SchemaNode;
1343
687
  /**
1344
- * Optional footer appended to the generated file content.
1345
- * Accepts `null` so `resolver.resolveFooter()` results can be passed directly.
688
+ * Whether the property is required.
1346
689
  */
1347
- footer?: string | null;
690
+ required: boolean;
1348
691
  };
1349
- //#endregion
1350
- //#region src/nodes/function.d.ts
1351
692
  /**
1352
- * AST node representing a language-agnostic type expression used as a function parameter
1353
- * type annotation. Each language printer renders the variant into its own syntax.
1354
- *
1355
- * - `struct` an inline anonymous type grouping named fields.
1356
- * TypeScript renders as `{ petId: string; name?: string }`.
1357
- * - `member` a single named field accessed from a named group type.
1358
- * TypeScript renders as `PathParams['petId']`.
1359
- *
1360
- * @example Reference variant
1361
- * ```ts
1362
- * createParamsType({ variant: 'reference', name: 'QueryParams' })
1363
- * // QueryParams
1364
- * ```
1365
- *
1366
- * @example Struct variant
1367
- * ```ts
1368
- * createParamsType({ variant: 'struct', properties: [{ name: 'petId', optional: false, type: createParamsType({ variant: 'reference', name: 'string' }) }] })
1369
- * // { petId: string }
1370
- * ```
693
+ * Loosely-typed property accepted by `createProperty`, with `required` optional.
694
+ */
695
+ type UserPropertyNode = Pick<PropertyNode, 'name' | 'schema'> & Partial<Omit<PropertyNode, 'kind' | 'name' | 'schema'>>;
696
+ /**
697
+ * Definition for the {@link PropertyNode}. `required` defaults to `false` and the
698
+ * schema's `optional`/`nullish` flags are kept in sync with it.
699
+ */
700
+ declare const propertyDef: NodeDef<PropertyNode, UserPropertyNode>;
701
+ /**
702
+ * Creates a `PropertyNode`.
1371
703
  *
1372
- * @example Member variant
704
+ * @example
1373
705
  * ```ts
1374
- * createParamsType({ variant: 'member', base: 'PathParams', key: 'petId' })
1375
- * // PathParams['petId']
706
+ * const property = createProperty({
707
+ * name: 'status',
708
+ * required: true,
709
+ * schema: createSchema({ type: 'string', nullable: true }),
710
+ * })
711
+ * // required=true, no optional/nullish
1376
712
  * ```
1377
713
  */
1378
- type ParamsTypeNode = BaseNode & {
714
+ declare const createProperty: (input: UserPropertyNode) => PropertyNode;
715
+ //#endregion
716
+ //#region src/nodes/schema.d.ts
717
+ type PrimitiveSchemaType =
718
+ /**
719
+ * Text value.
720
+ */
721
+ 'string'
722
+ /**
723
+ * Floating-point number.
724
+ */
725
+ | 'number'
726
+ /**
727
+ * Integer number.
728
+ */
729
+ | 'integer'
730
+ /**
731
+ * Big integer number.
732
+ */
733
+ | 'bigint'
734
+ /**
735
+ * Boolean value.
736
+ */
737
+ | 'boolean'
738
+ /**
739
+ * Null value.
740
+ */
741
+ | 'null'
742
+ /**
743
+ * Any value.
744
+ */
745
+ | 'any'
746
+ /**
747
+ * Unknown value.
748
+ */
749
+ | 'unknown'
750
+ /**
751
+ * No value (`void`).
752
+ */
753
+ | 'void'
754
+ /**
755
+ * Never value.
756
+ */
757
+ | 'never'
758
+ /**
759
+ * Object value.
760
+ */
761
+ | 'object'
762
+ /**
763
+ * Array value.
764
+ */
765
+ | 'array'
766
+ /**
767
+ * Date value.
768
+ */
769
+ | 'date';
770
+ /**
771
+ * Composite schema types.
772
+ */
773
+ type ComplexSchemaType = 'tuple' | 'union' | 'intersection' | 'enum';
774
+ /**
775
+ * Schema types that need special handling in generators.
776
+ */
777
+ type SpecialSchemaType = 'ref' | 'datetime' | 'time' | 'uuid' | 'email' | 'url' | 'ipv4' | 'ipv6' | 'blob';
778
+ /**
779
+ * All schema type strings.
780
+ */
781
+ type SchemaType = PrimitiveSchemaType | ComplexSchemaType | SpecialSchemaType;
782
+ /**
783
+ * Scalar schema types without extra object/array/ref structure.
784
+ */
785
+ type ScalarSchemaType = Exclude<SchemaType, 'object' | 'array' | 'tuple' | 'union' | 'intersection' | 'enum' | 'ref' | 'datetime' | 'date' | 'time' | 'string' | 'number' | 'integer' | 'bigint' | 'url' | 'uuid' | 'email'>;
786
+ /**
787
+ * Fields shared by all schema nodes.
788
+ */
789
+ type SchemaNodeBase = BaseNode & {
1379
790
  /**
1380
791
  * Node kind.
1381
792
  */
1382
- kind: 'ParamsType';
1383
- } & ({
793
+ kind: 'Schema';
1384
794
  /**
1385
- * Reference variant, a plain type name or identifier.
1386
- * TypeScript renders as-is, e.g. `string`, `QueryParams`, `Partial<Config>`.
795
+ * Schema name for named definitions (for example, `"Pet"`).
796
+ * Inline schemas omit this field.
797
+ * `null` means kubb has processed this and determined there is no applicable name.
798
+ * `undefined` means the name has not been set yet.
1387
799
  */
1388
- variant: 'reference';
800
+ name?: string | null;
1389
801
  /**
1390
- * The full type name string, e.g. `'string'`, `'QueryParams'`, `'Partial<Config>'`.
802
+ * Short schema title.
1391
803
  */
1392
- name: string;
1393
- } | {
804
+ title?: string;
1394
805
  /**
1395
- * Struct variant, an inline anonymous type grouping named fields.
1396
- * TypeScript renders as `{ key: Type; other?: OtherType }`.
806
+ * Schema description text.
1397
807
  */
1398
- variant: 'struct';
808
+ description?: string;
1399
809
  /**
1400
- * Properties of the struct type.
810
+ * Whether `null` is allowed.
1401
811
  */
1402
- properties: Array<{
1403
- name: string;
1404
- optional: boolean;
1405
- type: ParamsTypeNode;
1406
- }>;
1407
- } | {
812
+ nullable?: boolean;
813
+ /**
814
+ * Whether the field is optional.
815
+ */
816
+ optional?: boolean;
1408
817
  /**
1409
- * Member variant, a single named field accessed from a group type.
1410
- * TypeScript renders as `Base['key']`.
818
+ * Both optional and nullable (`optional` + `nullable`).
1411
819
  */
1412
- variant: 'member';
820
+ nullish?: boolean;
1413
821
  /**
1414
- * Base type name, e.g. `'DeletePetPathParams'`.
822
+ * Whether the schema is deprecated.
1415
823
  */
1416
- base: string;
824
+ deprecated?: boolean;
1417
825
  /**
1418
- * The field name to access, e.g. `'petId'`.
826
+ * Whether the schema is read-only.
1419
827
  */
1420
- key: string;
1421
- });
1422
- /**
1423
- * AST node for one function parameter.
1424
- *
1425
- * @example Required parameter
1426
- * `name: Type`
1427
- *
1428
- * @example Optional parameter
1429
- * `name?: Type`
1430
- *
1431
- * @example Parameter with default value
1432
- * `name: Type = defaultValue`
1433
- *
1434
- * @example Rest parameter
1435
- * `...name: Type[]`
1436
- */
1437
- type FunctionParameterNode = BaseNode & {
828
+ readOnly?: boolean;
1438
829
  /**
1439
- * Node kind.
830
+ * Whether the schema is write-only.
1440
831
  */
1441
- kind: 'FunctionParameter';
832
+ writeOnly?: boolean;
1442
833
  /**
1443
- * Parameter name in the generated signature.
834
+ * Default value.
1444
835
  */
1445
- name: string;
836
+ default?: unknown;
1446
837
  /**
1447
- * Type annotation as a structured {@link ParamsTypeNode}.
1448
- * Omit for untyped output.
1449
- *
1450
- * @example Reference type node
1451
- * `{ kind: 'ParamsType', variant: 'reference', name: 'string' }` → `petId: string`
1452
- *
1453
- * @example Struct type node
1454
- * `{ kind: 'ParamsType', variant: 'struct', properties: [...] }` → `{ key: Type; other?: OtherType }`
1455
- *
1456
- * @example Member type node
1457
- * `{ kind: 'ParamsType', variant: 'member', base: 'PathParams', key: 'petId' }` → `PathParams['petId']`
838
+ * Example value.
1458
839
  */
1459
- type?: ParamsTypeNode;
840
+ example?: unknown;
1460
841
  /**
1461
- * When `true` the parameter is emitted as a rest parameter.
1462
- *
1463
- * @example Rest parameter
1464
- * `...name: Type[]`
842
+ * Base primitive type.
843
+ * For example, this is `'string'` for a `uuid` schema.
1465
844
  */
1466
- rest?: boolean;
1467
- }
1468
- /**
1469
- * Optional parameter, rendered with `?` and may be omitted by the caller.
1470
- * Cannot be combined with `default` because a defaulted parameter is already optional.
1471
- */
1472
- & ({
1473
- optional: true;
1474
- default?: never;
1475
- }
1476
- /**
1477
- * Required parameter, or a parameter with a default value.
1478
- *
1479
- * @example Required
1480
- * `name: Type`
1481
- *
1482
- * @example With default
1483
- * `name: Type = default`
1484
- */
1485
- | {
1486
- optional?: false;
1487
- default?: string;
1488
- });
845
+ primitive?: PrimitiveSchemaType;
846
+ /**
847
+ * Schema `format` value.
848
+ */
849
+ format?: string;
850
+ };
1489
851
  /**
1490
- * AST node for a group of related function parameters treated as a single unit.
1491
- *
1492
- * Each language printer decides how to render this group:
1493
- * - TypeScript/JS: destructured object `{ key1, key2 }: { key1: Type1; key2: Type2 } = {}`
1494
- * - Python: keyword-only args or a typed dict parameter
1495
- * - C# / Kotlin: named record / data-class parameter
1496
- *
1497
- * When `inline` is `true`, the group is spread as individual top-level parameters
1498
- * rather than wrapped in a single grouped construct.
1499
- *
1500
- * @example Grouped destructuring
1501
- * `{ id, name }: { id: string; name: string } = {}`
852
+ * Object schema with ordered properties.
1502
853
  *
1503
- * @example Inline (spread as individual parameters)
1504
- * `id: string, name: string`
854
+ * @example
855
+ * ```ts
856
+ * const objectSchema: ObjectSchemaNode = {
857
+ * kind: 'Schema',
858
+ * type: 'object',
859
+ * properties: [],
860
+ * }
861
+ * ```
1505
862
  */
1506
- type ParameterGroupNode = BaseNode & {
1507
- /**
1508
- * Node kind.
1509
- */
1510
- kind: 'ParameterGroup';
863
+ type ObjectSchemaNode = SchemaNodeBase & {
1511
864
  /**
1512
- * The individual parameters that form the group.
1513
- * Rendered as a destructured object or spread inline when `inline` is `true`.
865
+ * Schema type discriminator.
1514
866
  */
1515
- properties: Array<FunctionParameterNode>;
867
+ type: 'object';
1516
868
  /**
1517
- * Optional explicit type annotation for the whole group.
1518
- * When absent, printers auto-compute it from `properties`.
869
+ * Primitive type, always `'object'` for object schemas.
1519
870
  */
1520
- type?: ParamsTypeNode;
871
+ primitive: 'object';
1521
872
  /**
1522
- * When `true`, `properties` are emitted as individual top-level parameters instead of
1523
- * being wrapped in a single grouped construct.
1524
- *
1525
- * @default false
873
+ * Ordered object properties.
1526
874
  */
1527
- inline?: boolean;
875
+ properties: Array<PropertyNode>;
1528
876
  /**
1529
- * Whether the group as a whole is optional.
1530
- * If omitted, printers infer this from child properties.
877
+ * Additional object properties behavior:
878
+ * - `true`: allow any value
879
+ * - `false`: reject unknown properties (maps to `.strict()` in Zod)
880
+ * - `SchemaNode`: allow values that match that schema
881
+ * - `undefined`: no additional properties constraint (open object)
1531
882
  */
1532
- optional?: boolean;
883
+ additionalProperties?: SchemaNode | boolean;
1533
884
  /**
1534
- * Default value for the group, written verbatim after `=`.
1535
- * Commonly `'{}'` to allow omitting the argument entirely.
885
+ * Pattern-based property schemas.
1536
886
  */
1537
- default?: string;
1538
- };
1539
- /**
1540
- * AST node for a complete function parameter list.
1541
- *
1542
- * Printers are responsible for sorting (`required` → `optional` → `defaulted`).
1543
- * Nodes are plain immutable data.
1544
- *
1545
- * Renders differently depending on the output mode:
1546
- * - `declaration` → `(id: string, config: Config = {})` function declaration parameters
1547
- * - `call` → `(id, { method, url })` function call arguments
1548
- * - `keys` → `{ id, config }` key names only (for destructuring)
1549
- * - `values` → `{ id: id, config: config }` key → value pairs
1550
- */
1551
- type FunctionParametersNode = BaseNode & {
887
+ patternProperties?: Record<string, SchemaNode>;
1552
888
  /**
1553
- * Node kind.
889
+ * Minimum number of properties allowed.
1554
890
  */
1555
- kind: 'FunctionParameters';
891
+ minProperties?: number;
1556
892
  /**
1557
- * Ordered parameter nodes.
893
+ * Maximum number of properties allowed.
1558
894
  */
1559
- params: ReadonlyArray<FunctionParameterNode | ParameterGroupNode>;
895
+ maxProperties?: number;
1560
896
  };
1561
897
  /**
1562
- * Union of all function-parameter AST node variants used by the function-parameter printer.
1563
- */
1564
- type FunctionParamNode = FunctionParameterNode | ParameterGroupNode | FunctionParametersNode | ParamsTypeNode;
1565
- /**
1566
- * Handler map keys, one per `FunctionParamNode` kind.
1567
- */
1568
- type FunctionNodeType = 'functionParameter' | 'parameterGroup' | 'functionParameters' | 'paramsType';
1569
- //#endregion
1570
- //#region ../../internals/utils/src/promise.d.ts
1571
- /**
1572
- * Container that switches between an eager `Array<T>` and a lazy `AsyncIterable<T>`.
1573
- *
1574
- * `Array<T>` by default. With `Stream` set to `true` it becomes `AsyncIterable<T>`, so large
1575
- * collections can be produced lazily without holding every item in memory. Pairs with
1576
- * {@link arrayToAsyncIterable}, which lifts a plain array into the streaming form.
1577
- *
1578
- * @example
1579
- * ```ts
1580
- * type Eager = Streamable<number> // Array<number>
1581
- * type Lazy = Streamable<number, true> // AsyncIterable<number>
1582
- * ```
1583
- */
1584
- type Streamable<T, Stream extends boolean = false> = Stream extends true ? AsyncIterable<T> : Array<T>;
1585
- //#endregion
1586
- //#region src/nodes/parameter.d.ts
1587
- type ParameterLocation = 'path' | 'query' | 'header' | 'cookie';
1588
- /**
1589
- * AST node representing one operation parameter.
898
+ * Array-like schema (`array` or `tuple`).
1590
899
  *
1591
900
  * @example
1592
901
  * ```ts
1593
- * const param: ParameterNode = {
1594
- * kind: 'Parameter',
1595
- * name: 'petId',
1596
- * in: 'path',
1597
- * schema: createSchema({ type: 'string' }),
1598
- * required: true,
902
+ * const arraySchema: ArraySchemaNode = {
903
+ * kind: 'Schema',
904
+ * type: 'array',
905
+ * items: [],
1599
906
  * }
1600
907
  * ```
1601
908
  */
1602
- type ParameterNode = BaseNode & {
909
+ type ArraySchemaNode = SchemaNodeBase & {
1603
910
  /**
1604
- * Node kind.
911
+ * Schema type discriminator (`array` or `tuple`).
1605
912
  */
1606
- kind: 'Parameter';
913
+ type: 'array' | 'tuple';
1607
914
  /**
1608
- * Parameter name.
915
+ * Item schemas.
1609
916
  */
1610
- name: string;
917
+ items?: Array<SchemaNode>;
1611
918
  /**
1612
- * Parameter location (`path`, `query`, `header`, or `cookie`).
919
+ * Tuple rest-item schema for elements beyond positional `items`.
1613
920
  */
1614
- in: ParameterLocation;
921
+ rest?: SchemaNode;
1615
922
  /**
1616
- * Parameter schema.
923
+ * Minimum item count (or tuple length).
1617
924
  */
1618
- schema: SchemaNode;
925
+ min?: number;
1619
926
  /**
1620
- * Whether the parameter is required.
927
+ * Maximum item count (or tuple length).
1621
928
  */
1622
- required: boolean;
929
+ max?: number;
930
+ /**
931
+ * Whether all items must be unique.
932
+ */
933
+ unique?: boolean;
1623
934
  };
1624
- //#endregion
1625
- //#region src/nodes/requestBody.d.ts
1626
935
  /**
1627
- * AST node representing an operation request body.
1628
- *
1629
- * Body schemas live exclusively inside the `content` array (one entry per content type),
1630
- * mirroring {@link ResponseNode}.
936
+ * Shared shape for union and intersection schemas.
937
+ */
938
+ type CompositeSchemaNodeBase = SchemaNodeBase & {
939
+ /**
940
+ * Member schemas.
941
+ */
942
+ members?: Array<SchemaNode>;
943
+ };
944
+ /**
945
+ * Union schema, often from `oneOf` or `anyOf`.
1631
946
  *
1632
947
  * @example
1633
948
  * ```ts
1634
- * const requestBody: RequestBodyNode = {
1635
- * kind: 'RequestBody',
1636
- * required: true,
1637
- * content: [{ kind: 'Content', contentType: 'application/json', schema: createSchema({ type: 'string' }) }],
949
+ * const unionSchema: UnionSchemaNode = {
950
+ * kind: 'Schema',
951
+ * type: 'union',
952
+ * members: [],
1638
953
  * }
1639
954
  * ```
1640
955
  */
1641
- type RequestBodyNode = BaseNode & {
1642
- /**
1643
- * Node kind.
1644
- */
1645
- kind: 'RequestBody';
956
+ type UnionSchemaNode = CompositeSchemaNodeBase & {
1646
957
  /**
1647
- * Human-readable request body description.
958
+ * Schema type discriminator.
1648
959
  */
1649
- description?: string;
960
+ type: 'union';
1650
961
  /**
1651
- * Whether the request body is required (`requestBody.required: true` in the spec).
1652
- * When `false` or absent, the generated `data` parameter should be optional.
962
+ * Discriminator property name from OpenAPI `discriminator.propertyName`.
1653
963
  */
1654
- required?: boolean;
964
+ discriminatorPropertyName?: string;
1655
965
  /**
1656
- * All available content type entries for this request body.
1657
- *
1658
- * When the adapter `contentType` option is set, this array contains exactly one entry for
1659
- * that content type. Otherwise it contains one entry per content type declared in the spec,
1660
- * so that plugins can generate code for every variant (e.g. separate hooks for
1661
- * `application/json` and `multipart/form-data`).
966
+ * Logical strategy applied to union members: 'one' means exactly one member must be valid (from `oneOf`),
967
+ * 'any' means any number of members can be valid (from `anyOf`).
1662
968
  */
1663
- content?: Array<ContentNode>;
969
+ strategy?: 'one' | 'any';
1664
970
  };
1665
- //#endregion
1666
- //#region src/nodes/http.d.ts
1667
- /**
1668
- * All supported HTTP status code literals as strings, as used in API specs
1669
- * (for example, `"200"` and `"404"`).
1670
- */
1671
- type HttpStatusCode = '100' | '101' | '102' | '103' | '200' | '201' | '202' | '203' | '204' | '205' | '206' | '207' | '208' | '226' | '300' | '301' | '302' | '303' | '304' | '305' | '307' | '308' | '400' | '401' | '402' | '403' | '404' | '405' | '406' | '407' | '408' | '409' | '410' | '411' | '412' | '413' | '414' | '415' | '416' | '417' | '418' | '421' | '422' | '423' | '424' | '425' | '426' | '428' | '429' | '431' | '451' | '500' | '501' | '502' | '503' | '504' | '505' | '506' | '507' | '508' | '510' | '511';
1672
- /**
1673
- * Response status code literal used by operations.
1674
- *
1675
- * Includes specific HTTP status code strings and `"default"` for catch-all responses.
1676
- *
1677
- * @example
1678
- * ```ts
1679
- * const status: StatusCode = '200'
1680
- * const fallback: StatusCode = 'default'
1681
- * ```
1682
- */
1683
- type StatusCode = HttpStatusCode | 'default';
1684
- //#endregion
1685
- //#region src/nodes/response.d.ts
1686
971
  /**
1687
- * AST node representing one operation response variant.
1688
- *
1689
- * Mirrors {@link OperationNode.requestBody}: the response body schemas live exclusively inside
1690
- * the `content` array (one entry per content type), so the same schema is never duplicated at the
1691
- * node root and inside `content`.
972
+ * Intersection schema, often from `allOf`.
1692
973
  *
1693
974
  * @example
1694
975
  * ```ts
1695
- * const response: ResponseNode = {
1696
- * kind: 'Response',
1697
- * statusCode: '200',
1698
- * content: [{ contentType: 'application/json', schema: createSchema({ type: 'string' }) }],
976
+ * const intersectionSchema: IntersectionSchemaNode = {
977
+ * kind: 'Schema',
978
+ * type: 'intersection',
979
+ * members: [],
1699
980
  * }
1700
981
  * ```
1701
982
  */
1702
- type ResponseNode = BaseNode & {
1703
- /**
1704
- * Node kind.
1705
- */
1706
- kind: 'Response';
1707
- /**
1708
- * HTTP status code or `'default'` for a fallback response.
1709
- */
1710
- statusCode: StatusCode;
1711
- /**
1712
- * Optional response description.
1713
- */
1714
- description?: string;
983
+ type IntersectionSchemaNode = CompositeSchemaNodeBase & {
1715
984
  /**
1716
- * All available content type entries for this response.
1717
- *
1718
- * When the adapter `contentType` option is set, this array contains exactly one entry for that
1719
- * content type. Otherwise it contains one entry per content type declared in the spec, so that
1720
- * plugins can generate a union of response types (e.g. `application/json` and `application/xml`).
1721
- * Body-less responses keep a single entry whose `schema` is the empty/`void` placeholder.
1722
- *
1723
- * @example
1724
- * ```ts
1725
- * // spec response declares both application/json and application/xml
1726
- * response.content[0].contentType // 'application/json'
1727
- * response.content[1].contentType // 'application/xml'
1728
- * ```
985
+ * Schema type discriminator.
1729
986
  */
1730
- content?: Array<ContentNode>;
987
+ type: 'intersection';
1731
988
  };
1732
- //#endregion
1733
- //#region src/nodes/operation.d.ts
1734
- type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'TRACE';
1735
989
  /**
1736
- * Transport an operation belongs to.
1737
- */
1738
- type OperationProtocol = 'http';
1739
- /**
1740
- * Fields shared by every operation, regardless of transport.
990
+ * One named enum item.
1741
991
  */
1742
- type OperationNodeBase = BaseNode & {
1743
- /**
1744
- * Node kind.
1745
- */
1746
- kind: 'Operation';
1747
- /**
1748
- * Operation identifier, usually from OpenAPI `operationId`.
1749
- */
1750
- operationId: string;
1751
- /**
1752
- * Group labels for the operation.
1753
- * Usually copied from OpenAPI `tags`.
1754
- */
1755
- tags: Array<string>;
1756
- /**
1757
- * Short one-line operation summary.
1758
- */
1759
- summary?: string;
1760
- /**
1761
- * Full operation description.
1762
- */
1763
- description?: string;
1764
- /**
1765
- * Marks the operation as deprecated.
1766
- */
1767
- deprecated?: boolean;
992
+ type EnumValueNode = {
1768
993
  /**
1769
- * Parameters that could be used, we have QueryParams, PathParams, HeaderParams and CookieParams
994
+ * Enum item name.
1770
995
  */
1771
- parameters: Array<ParameterNode>;
996
+ name: string;
1772
997
  /**
1773
- * Request body for the operation.
998
+ * Enum item value.
1774
999
  */
1775
- requestBody?: RequestBodyNode;
1000
+ value: string | number | boolean;
1776
1001
  /**
1777
- * Operation responses.
1002
+ * Primitive type of the enum value.
1778
1003
  */
1779
- responses: Array<ResponseNode>;
1004
+ primitive: Extract<PrimitiveSchemaType, 'string' | 'number' | 'boolean'>;
1780
1005
  };
1781
1006
  /**
1782
- * Operation served over HTTP/REST (OpenAPI). `method` and `path` are guaranteed.
1007
+ * Enum schema node.
1783
1008
  *
1784
1009
  * @example
1785
1010
  * ```ts
1786
- * const operation: HttpOperationNode = {
1787
- * kind: 'Operation',
1788
- * operationId: 'listPets',
1789
- * protocol: 'http',
1790
- * method: 'GET',
1791
- * path: '/pets',
1792
- * tags: [],
1793
- * parameters: [],
1794
- * responses: [],
1011
+ * const enumSchema: EnumSchemaNode = {
1012
+ * kind: 'Schema',
1013
+ * type: 'enum',
1014
+ * enumValues: ['a', 'b'],
1795
1015
  * }
1796
1016
  * ```
1797
1017
  */
1798
- type HttpOperationNode = OperationNodeBase & {
1799
- /**
1800
- * Transport the operation belongs to.
1801
- */
1802
- protocol?: 'http';
1018
+ type EnumSchemaNode = SchemaNodeBase & {
1803
1019
  /**
1804
- * HTTP method like `'GET'`.
1020
+ * Schema type discriminator.
1805
1021
  */
1806
- method: HttpMethod;
1022
+ type: 'enum';
1807
1023
  /**
1808
- * OpenAPI-style path string, for example `/pets/{petId}`, with `{param}` notation preserved.
1024
+ * Enum values in simple form.
1809
1025
  */
1810
- path: string;
1811
- };
1812
- /**
1813
- * Operation for a non-HTTP transport. HTTP-only fields are forbidden.
1814
- */
1815
- type GenericOperationNode = OperationNodeBase & {
1026
+ enumValues?: Array<string | number | boolean | null>;
1816
1027
  /**
1817
- * Transport the operation belongs to.
1028
+ * Enum values in named form.
1029
+ * If present, this is used instead of `enumValues`.
1818
1030
  */
1819
- protocol?: Exclude<OperationProtocol, 'http'>;
1820
- method?: never;
1821
- path?: never;
1031
+ namedEnumValues?: Array<EnumValueNode>;
1822
1032
  };
1823
1033
  /**
1824
- * AST node representing one API operation.
1825
- *
1826
- * Discriminated on `protocol`: an {@link HttpOperationNode} (`protocol: 'http'`) guarantees
1827
- * `method` and `path`, while a {@link GenericOperationNode} omits them. Narrow with
1828
- * `isHttpOperationNode(node)` or `node.protocol === 'http'` before reading `method`/`path`.
1829
- */
1830
- type OperationNode = HttpOperationNode | GenericOperationNode;
1831
- //#endregion
1832
- //#region src/nodes/input.d.ts
1833
- /**
1834
- * Metadata for an API document, populated by the adapter and available to every generator.
1835
- *
1836
- * All fields are plain JSON-serializable values, no `Set`, no `Map`, no class instances.
1837
- * Computed fields (`circularNames`, `enumNames`) are pre-calculated once during the adapter
1838
- * pre-scan so generators never need to iterate the full schema list themselves.
1034
+ * Reference schema that points to another schema definition.
1839
1035
  *
1840
1036
  * @example
1841
1037
  * ```ts
1842
- * const meta: InputMeta = { title: 'Pet Store', version: '1.0.0', baseURL: 'https://petstore.swagger.io/v2', circularNames: [], enumNames: [] }
1038
+ * const refSchema: RefSchemaNode = {
1039
+ * kind: 'Schema',
1040
+ * type: 'ref',
1041
+ * ref: '#/components/schemas/Pet',
1042
+ * }
1843
1043
  * ```
1844
1044
  */
1845
- type InputMeta = {
1846
- /**
1847
- * API title from `info.title` in the source document.
1848
- */
1849
- title?: string;
1045
+ type RefSchemaNode = SchemaNodeBase & {
1850
1046
  /**
1851
- * API description from `info.description` in the source document.
1047
+ * Schema type discriminator.
1852
1048
  */
1853
- description?: string;
1049
+ type: 'ref';
1854
1050
  /**
1855
- * API version string from `info.version` in the source document.
1051
+ * Referenced schema name.
1052
+ * `null` means Kubb has processed this and determined there is no applicable name.
1856
1053
  */
1857
- version?: string;
1054
+ name?: string | null;
1858
1055
  /**
1859
- * Resolved base URL from the first matching server entry in the source document.
1056
+ * Original `$ref` path, for example, `#/components/schemas/Order`.
1057
+ * Used to resolve names later.
1860
1058
  */
1861
- baseURL?: string | null;
1059
+ ref?: string;
1862
1060
  /**
1863
- * Names of schemas that participate in a circular reference chain.
1864
- * Computed once during the adapter pre-scan, use this instead of calling
1865
- * `findCircularSchemas` per generator call.
1866
- *
1867
- * Convert to a `Set` once at the start of a generator, not per-schema,
1868
- * to keep lookup O(1) without repeated allocations.
1869
- *
1870
- * @example Wrap a circular schema in z.lazy()
1871
- * ```ts
1872
- * const circular = new Set(meta.circularNames)
1873
- * if (circular.has(schema.name)) { ... }
1874
- * ```
1061
+ * Pattern copied from a sibling `pattern` field.
1875
1062
  */
1876
- circularNames: ReadonlyArray<string>;
1063
+ pattern?: string;
1877
1064
  /**
1878
- * Names of schemas whose type is `enum`.
1879
- * Computed once during the adapter pre-scan, use this instead of filtering
1880
- * schemas per generator call.
1881
- *
1882
- * Convert to a `Set` once at the start of a generator when you need repeated
1883
- * membership checks, rather than calling `.includes()` per schema.
1884
- *
1885
- * @example Check if a referenced schema is an enum
1886
- * `const enums = new Set(meta.enumNames)`
1887
- * `const isEnum = enums.has(schemaName)`
1065
+ * The fully-parsed schema this ref resolves to, so its structure (`primitive`, `properties`)
1066
+ * can be read without following the reference. Populated during OAS parsing when the
1067
+ * definition resolves, `null` when it can't or the ref is circular, and `undefined` when
1068
+ * resolution has not been attempted.
1888
1069
  */
1889
- enumNames: ReadonlyArray<string>;
1070
+ schema?: SchemaNode | null;
1890
1071
  };
1891
1072
  /**
1892
- * Input AST node that contains all schemas and operations for one API document.
1893
- * Produced by the adapter and consumed by all Kubb plugins.
1894
- *
1895
- * `Stream` switches `schemas` and `operations` between eager `Array`s (the default) and lazy
1896
- * `AsyncIterable`s. The streaming variant `InputNode<true>` yields nodes one at a time and makes
1897
- * `meta` optional, since the adapter can emit metadata before the first node is parsed.
1073
+ * Datetime schema.
1898
1074
  *
1899
1075
  * @example
1900
1076
  * ```ts
1901
- * const input: InputNode = {
1902
- * kind: 'Input',
1903
- * schemas: [],
1904
- * operations: [],
1905
- * meta: { circularNames: [], enumNames: [] },
1906
- * }
1907
- * ```
1908
- *
1909
- * @example Streaming variant for large specs
1910
- * ```ts
1911
- * for await (const schema of inputNode.schemas) {
1912
- * // only this one SchemaNode is live here. Previous ones are GC-eligible
1913
- * }
1077
+ * const datetimeSchema: DatetimeSchemaNode = { kind: 'Schema', type: 'datetime' }
1914
1078
  * ```
1915
1079
  */
1916
- type InputNode<Stream extends boolean = false> = BaseNode & {
1080
+ type DatetimeSchemaNode = SchemaNodeBase & {
1917
1081
  /**
1918
- * Node kind.
1082
+ * Schema type discriminator.
1919
1083
  */
1920
- kind: 'Input';
1084
+ type: 'datetime';
1921
1085
  /**
1922
- * All schema nodes in the document.
1086
+ * Whether the datetime includes a timezone offset (`dateType: 'stringOffset'`).
1923
1087
  */
1924
- schemas: Streamable<SchemaNode, Stream>;
1088
+ offset?: boolean;
1925
1089
  /**
1926
- * All operation nodes in the document.
1090
+ * Whether the datetime is local (no timezone, `dateType: 'stringLocal'`).
1927
1091
  */
1928
- operations: Streamable<OperationNode, Stream>;
1929
- } & (Stream extends true ? {
1930
- meta?: InputMeta;
1931
- } : {
1932
- meta: InputMeta;
1933
- });
1934
- //#endregion
1935
- //#region src/nodes/output.d.ts
1092
+ local?: boolean;
1093
+ };
1936
1094
  /**
1937
- * Output AST node that groups all generated file output for one API document.
1938
- *
1939
- * Produced by generators and consumed by the build pipeline to write files.
1940
- *
1941
- * @example
1942
- * ```ts
1943
- * const output: OutputNode = {
1944
- * kind: 'Output',
1945
- * files: [],
1946
- * }
1947
- * ```
1095
+ * Shared base for `date` and `time` schemas.
1948
1096
  */
1949
- type OutputNode = BaseNode & {
1097
+ type TemporalSchemaNodeBase<T extends 'date' | 'time'> = SchemaNodeBase & {
1950
1098
  /**
1951
- * Node kind.
1099
+ * Schema type discriminator.
1952
1100
  */
1953
- kind: 'Output';
1101
+ type: T;
1954
1102
  /**
1955
- * Generated file nodes.
1103
+ * Output representation in generated code.
1956
1104
  */
1957
- files: Array<FileNode>;
1105
+ representation: 'date' | 'string';
1958
1106
  };
1959
- //#endregion
1960
- //#region src/nodes/index.d.ts
1961
1107
  /**
1962
- * Union of all AST node types.
1108
+ * Date schema node.
1963
1109
  *
1964
- * This lets TypeScript narrow types in `switch (node.kind)` blocks.
1110
+ * @example
1111
+ * ```ts
1112
+ * const dateSchema: DateSchemaNode = { kind: 'Schema', type: 'date', representation: 'string' }
1113
+ * ```
1114
+ */
1115
+ type DateSchemaNode = TemporalSchemaNodeBase<'date'>;
1116
+ /**
1117
+ * Time schema node.
1965
1118
  *
1966
1119
  * @example
1967
1120
  * ```ts
1968
- * function getKind(node: Node): string {
1969
- * switch (node.kind) {
1970
- * case 'Input':
1971
- * return 'input'
1972
- * case 'Output':
1973
- * return 'output'
1974
- * default:
1975
- * return 'other'
1976
- * }
1977
- * }
1121
+ * const timeSchema: TimeSchemaNode = { kind: 'Schema', type: 'time', representation: 'string' }
1978
1122
  * ```
1979
1123
  */
1980
- type Node = InputNode | OutputNode | OperationNode | SchemaNode | PropertyNode | ParameterNode | ResponseNode | RequestBodyNode | ContentNode | FunctionParamNode | FileNode | ImportNode | ExportNode | SourceNode | ConstNode | TypeNode | ParamsTypeNode | FunctionNode | ArrowFunctionNode;
1981
- //#endregion
1982
- //#region src/dedupe.d.ts
1124
+ type TimeSchemaNode = TemporalSchemaNodeBase<'time'>;
1983
1125
  /**
1984
- * A canonical destination for a deduplicated shape: the shared schema name and
1985
- * the synthetic `$ref` path that points at it.
1126
+ * String schema node.
1127
+ *
1128
+ * @example
1129
+ * ```ts
1130
+ * const stringSchema: StringSchemaNode = { kind: 'Schema', type: 'string' }
1131
+ * ```
1986
1132
  */
1987
- type DedupeCanonical = {
1988
- /**
1989
- * Canonical schema name every duplicate occurrence refers to.
1990
- */
1991
- name: string;
1133
+ type StringSchemaNode = SchemaNodeBase & {
1992
1134
  /**
1993
- * `$ref` path stored on the generated `ref` nodes (for example `#/components/schemas/Status`).
1135
+ * Schema type discriminator.
1994
1136
  */
1995
- ref: string;
1996
- };
1997
- /**
1998
- * The result of {@link buildDedupePlan}: a lookup from structural signature to its
1999
- * canonical target, plus the freshly hoisted definitions that must be added to
2000
- * the schema list.
2001
- */
2002
- type DedupePlan = {
1137
+ type: 'string';
2003
1138
  /**
2004
- * Maps a structural signature to the canonical schema that represents it.
1139
+ * Minimum string length.
2005
1140
  */
2006
- canonicalBySignature: Map<string, DedupeCanonical>;
1141
+ min?: number;
2007
1142
  /**
2008
- * Maps the name of a top-level schema that duplicates a canonical one to that canonical, so
2009
- * references to the duplicate can be repointed at the first schema with the same content.
1143
+ * Maximum string length.
2010
1144
  */
2011
- aliasNames: Map<string, DedupeCanonical>;
1145
+ max?: number;
2012
1146
  /**
2013
- * New top-level schema definitions created for inline shapes that had no existing
2014
- * named component. Nested duplicates inside each definition are already collapsed.
1147
+ * Regex pattern.
2015
1148
  */
2016
- hoisted: Array<SchemaNode>;
1149
+ pattern?: string;
2017
1150
  };
2018
1151
  /**
2019
- * The lookups {@link applyDedupe} needs from a {@link DedupePlan}.
2020
- */
2021
- type DedupeLookups = Pick<DedupePlan, 'canonicalBySignature' | 'aliasNames'>;
2022
- /**
2023
- * Options that inject the naming and candidate policy into {@link buildDedupePlan}.
2024
- * The mechanics (grouping, counting, rewriting) live here. The policy lives in the caller.
1152
+ * Numeric schema (`number`, `integer`, or `bigint`).
1153
+ *
1154
+ * @example
1155
+ * ```ts
1156
+ * const numberSchema: NumberSchemaNode = { kind: 'Schema', type: 'number' }
1157
+ * ```
2025
1158
  */
2026
- type BuildDedupePlanOptions = {
1159
+ type NumberSchemaNode = SchemaNodeBase & {
1160
+ /**
1161
+ * Schema type discriminator.
1162
+ */
1163
+ type: 'number' | 'integer' | 'bigint';
1164
+ /**
1165
+ * Minimum value.
1166
+ */
1167
+ min?: number;
2027
1168
  /**
2028
- * Returns `true` when a node should be deduplicated. This is the only gate, so it must
2029
- * reject both ineligible kinds (return `false` for anything other than, say, enums and
2030
- * objects) and unsafe shapes (e.g. nodes that reference a circular schema).
1169
+ * Maximum value.
2031
1170
  */
2032
- isCandidate: (node: SchemaNode) => boolean;
1171
+ max?: number;
2033
1172
  /**
2034
- * Produces the canonical name for an inline shape with no existing named component.
2035
- * Return `null` to leave the shape inline (for example when no contextual name exists).
1173
+ * Exclusive minimum value.
2036
1174
  */
2037
- nameFor: (node: SchemaNode, signature: string) => string | null;
1175
+ exclusiveMinimum?: number;
2038
1176
  /**
2039
- * Builds the `$ref` path for a canonical name.
1177
+ * Exclusive maximum value.
2040
1178
  */
2041
- refFor: (name: string) => string;
1179
+ exclusiveMaximum?: number;
2042
1180
  /**
2043
- * Minimum number of occurrences before a shape is deduplicated.
2044
- *
2045
- * @default 2
1181
+ * The value must be a multiple of this number.
2046
1182
  */
2047
- minOccurrences?: number;
1183
+ multipleOf?: number;
2048
1184
  };
2049
1185
  /**
2050
- * Rewrites a node, replacing every candidate sub-schema whose signature has a canonical
2051
- * target with a `ref` to that target. Replacing a node with a `ref` prunes its subtree,
2052
- * so nested duplicates inside a replaced shape are not visited again. A `ref` that points
2053
- * at a duplicate top-level schema (see `aliasNames`) is repointed at the first schema with
2054
- * the same content.
2055
- *
2056
- * Pass `skipRootMatch` when rewriting a canonical definition so its own root is not
2057
- * turned into a reference to itself. Nested duplicates are still collapsed.
1186
+ * Scalar schema with no extra constraints.
2058
1187
  *
2059
1188
  * @example
2060
1189
  * ```ts
2061
- * const next = applyDedupe(operationNode, plan)
1190
+ * const anySchema: ScalarSchemaNode = { kind: 'Schema', type: 'any' }
2062
1191
  * ```
2063
1192
  */
2064
- declare function applyDedupe(node: SchemaNode, plan: DedupeLookups, skipRootMatch?: boolean): SchemaNode;
2065
- declare function applyDedupe(node: OperationNode, plan: DedupeLookups, skipRootMatch?: boolean): OperationNode;
1193
+ type ScalarSchemaNode = SchemaNodeBase & {
1194
+ /**
1195
+ * Schema type discriminator.
1196
+ */
1197
+ type: ScalarSchemaType;
1198
+ };
2066
1199
  /**
2067
- * Scans a forest of schema and operation nodes and produces a {@link DedupePlan}.
2068
- *
2069
- * A shape that occurs at least `minOccurrences` times is deduplicated: if any occurrence
2070
- * is a named top-level schema, the first one becomes the canonical (so other top-level
2071
- * duplicates and inline copies turn into references to it). Every other top-level name with
2072
- * the same content is recorded in `aliasNames`, so refs to it can be repointed at the
2073
- * canonical. Otherwise a new definition is hoisted using `nameFor`. The plan is then applied
2074
- * per node with {@link applyDedupe}.
1200
+ * URL schema node.
1201
+ * Can include an OpenAPI-style path template for template literal types.
2075
1202
  *
2076
1203
  * @example
2077
1204
  * ```ts
2078
- * const plan = buildDedupePlan([...schemaNodes, ...operationNodes], {
2079
- * isCandidate: (node) => node.type === 'enum' || node.type === 'object',
2080
- * nameFor: (node) => node.name ?? null,
2081
- * refFor: (name) => `#/components/schemas/${name}`,
2082
- * })
1205
+ * const urlSchema: UrlSchemaNode = { kind: 'Schema', type: 'url', path: '/pets/{petId}' }
2083
1206
  * ```
2084
1207
  */
2085
- declare function buildDedupePlan(roots: ReadonlyArray<Node>, options: BuildDedupePlanOptions): DedupePlan;
2086
- //#endregion
2087
- //#region src/dialect.d.ts
2088
- /**
2089
- * The spec-specific questions a schema parser answers while turning a source document into Kubb
2090
- * AST nodes. The rest of the pipeline is generic JSON Schema, so this is the one seam where
2091
- * OpenAPI, AsyncAPI, and plain JSON Schema differ.
2092
- */
2093
- type SchemaDialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown> = {
2094
- /**
2095
- * Identifies the dialect in logs and diagnostics.
2096
- */
2097
- name: string;
2098
- /**
2099
- * Whether the schema is nullable.
2100
- */
2101
- isNullable: (schema?: TSchema) => boolean;
1208
+ type UrlSchemaNode = SchemaNodeBase & {
2102
1209
  /**
2103
- * Whether the value is a `$ref` pointer.
1210
+ * Schema type discriminator.
2104
1211
  */
2105
- isReference: (value?: unknown) => value is TRef;
1212
+ type: 'url';
2106
1213
  /**
2107
- * Whether the schema carries a discriminator for polymorphism.
1214
+ * OpenAPI-style path template, for example, `'/pets/{petId}'`.
2108
1215
  */
2109
- isDiscriminator: (value?: unknown) => value is TDiscriminated;
1216
+ path?: string;
2110
1217
  /**
2111
- * Whether the schema is binary data, converted to a `blob` node.
1218
+ * Minimum string length.
2112
1219
  */
2113
- isBinary: (schema: TSchema) => boolean;
1220
+ min?: number;
2114
1221
  /**
2115
- * Resolves a local `$ref` against the document, or nullish when it cannot.
1222
+ * Maximum string length.
2116
1223
  */
2117
- resolveRef: <TResolved>(document: TDocument, ref: string) => TResolved | null | undefined;
1224
+ max?: number;
2118
1225
  };
2119
1226
  /**
2120
- * Types a {@link SchemaDialect} for an adapter. Adds no runtime behavior and only pins the
2121
- * dialect's type for inference.
1227
+ * Format-string schema for string-based formats that support length constraints.
2122
1228
  *
2123
1229
  * @example
2124
1230
  * ```ts
2125
- * export const oasDialect = defineSchemaDialect({
2126
- * name: 'oas',
2127
- * isNullable,
2128
- * isReference,
2129
- * isDiscriminator,
2130
- * isBinary: (schema) => schema.type === 'string' && schema.contentMediaType === 'application/octet-stream',
2131
- * resolveRef,
2132
- * })
1231
+ * const uuidSchema: FormatStringSchemaNode = { kind: 'Schema', type: 'uuid', min: 36, max: 36 }
2133
1232
  * ```
2134
1233
  */
2135
- declare function defineSchemaDialect<TSchema, TRef, TDiscriminated, TDocument>(dialect: SchemaDialect<TSchema, TRef, TDiscriminated, TDocument>): SchemaDialect<TSchema, TRef, TDiscriminated, TDocument>;
2136
- //#endregion
2137
- //#region src/infer.d.ts
2138
- /**
2139
- * Shared parser options used by OAS-to-AST inference and parser flows.
2140
- */
2141
- type ParserOptions = {
2142
- /**
2143
- * How `format: 'date-time'` schemas are represented downstream.
2144
- * - `false` falls through to a plain `string` (no validation).
2145
- * - `'string'` emits a datetime string node.
2146
- * - `'stringOffset'` emits a datetime node with timezone offset.
2147
- * - `'stringLocal'` emits a local datetime node.
2148
- * - `'date'` emits a `date` node (JavaScript `Date` object).
2149
- */
2150
- dateType: false | 'string' | 'stringOffset' | 'stringLocal' | 'date';
2151
- /**
2152
- * How `type: 'integer'` (and `format: 'int64'`) maps to TypeScript.
2153
- * - `'bigint'` is exact for 64-bit IDs, but does not round-trip through JSON.
2154
- * - `'number'` fits most JSON APIs. Loses precision above `Number.MAX_SAFE_INTEGER`.
2155
- *
2156
- * @default 'bigint'
2157
- */
2158
- integerType?: 'number' | 'bigint';
1234
+ type FormatStringSchemaNode = SchemaNodeBase & {
2159
1235
  /**
2160
- * AST type used when a schema's type cannot be inferred from the spec
2161
- * (`additionalProperties: true`, missing `type`, ...).
1236
+ * Schema type discriminator.
2162
1237
  */
2163
- unknownType: 'any' | 'unknown' | 'void';
1238
+ type: 'uuid' | 'email';
2164
1239
  /**
2165
- * AST type used for completely empty schemas (`{}`).
1240
+ * Minimum string length.
2166
1241
  */
2167
- emptySchemaType: 'any' | 'unknown' | 'void';
1242
+ min?: number;
2168
1243
  /**
2169
- * Suffix appended to derived enum names when Kubb has to invent one
2170
- * (typically for inline enums on object properties).
1244
+ * Maximum string length.
2171
1245
  */
2172
- enumSuffix: 'enum' | (string & {});
2173
- };
2174
- /**
2175
- * Maps each `dateType` option value to the AST node produced by `format: 'date-time'`.
2176
- */
2177
- type DateTimeNodeByDateType = {
2178
- date: DateSchemaNode;
2179
- string: DatetimeSchemaNode;
2180
- stringOffset: DatetimeSchemaNode;
2181
- stringLocal: DatetimeSchemaNode;
2182
- false: StringSchemaNode;
1246
+ max?: number;
2183
1247
  };
2184
1248
  /**
2185
- * Resolves the AST node produced by `format: 'date-time'` based on the `dateType` option.
2186
- */
2187
- type ResolveDateTimeNode<TDateType extends ParserOptions['dateType']> = DateTimeNodeByDateType[TDateType extends keyof DateTimeNodeByDateType ? TDateType : 'string'];
2188
- /**
2189
- * Ordered list of `[schema-shape, SchemaNode]` pairs.
2190
- * `InferSchemaNode` walks this tuple in order and returns the first matching node type.
2191
- */
2192
- type SchemaNodeMap<TDateType extends ParserOptions['dateType'] = 'string'> = [[{
2193
- $ref: string;
2194
- }, RefSchemaNode], [{
2195
- allOf: ReadonlyArray<unknown>;
2196
- properties: object;
2197
- }, IntersectionSchemaNode], [{
2198
- allOf: readonly [unknown, unknown, ...Array<unknown>];
2199
- }, IntersectionSchemaNode], [{
2200
- allOf: ReadonlyArray<unknown>;
2201
- }, SchemaNode], [{
2202
- oneOf: ReadonlyArray<unknown>;
2203
- }, UnionSchemaNode], [{
2204
- anyOf: ReadonlyArray<unknown>;
2205
- }, UnionSchemaNode], [{
2206
- const: null;
2207
- }, ScalarSchemaNode], [{
2208
- const: string | number | boolean;
2209
- }, EnumSchemaNode], [{
2210
- type: ReadonlyArray<string>;
2211
- }, UnionSchemaNode], [{
2212
- type: 'array';
2213
- enum: ReadonlyArray<unknown>;
2214
- }, ArraySchemaNode], [{
2215
- enum: ReadonlyArray<unknown>;
2216
- }, EnumSchemaNode], [{
2217
- type: 'enum';
2218
- }, EnumSchemaNode], [{
2219
- type: 'union';
2220
- }, UnionSchemaNode], [{
2221
- type: 'intersection';
2222
- }, IntersectionSchemaNode], [{
2223
- type: 'tuple';
2224
- }, ArraySchemaNode], [{
2225
- type: 'ref';
2226
- }, RefSchemaNode], [{
2227
- type: 'datetime';
2228
- }, DatetimeSchemaNode], [{
2229
- type: 'date';
2230
- }, DateSchemaNode], [{
2231
- type: 'time';
2232
- }, TimeSchemaNode], [{
2233
- type: 'url';
2234
- }, UrlSchemaNode], [{
2235
- type: 'object';
2236
- }, ObjectSchemaNode], [{
2237
- additionalProperties: boolean | {};
2238
- }, ObjectSchemaNode], [{
2239
- type: 'array';
2240
- }, ArraySchemaNode], [{
2241
- items: object;
2242
- }, ArraySchemaNode], [{
2243
- prefixItems: ReadonlyArray<unknown>;
2244
- }, ArraySchemaNode], [{
2245
- type: string;
2246
- format: 'date-time';
2247
- }, ResolveDateTimeNode<TDateType>], [{
2248
- type: string;
2249
- format: 'date';
2250
- }, DateSchemaNode], [{
2251
- type: string;
2252
- format: 'time';
2253
- }, TimeSchemaNode], [{
2254
- format: 'date-time';
2255
- }, ResolveDateTimeNode<TDateType>], [{
2256
- format: 'date';
2257
- }, DateSchemaNode], [{
2258
- format: 'time';
2259
- }, TimeSchemaNode], [{
2260
- type: 'string';
2261
- }, StringSchemaNode], [{
2262
- type: 'number';
2263
- }, NumberSchemaNode], [{
2264
- type: 'integer';
2265
- }, NumberSchemaNode], [{
2266
- type: 'bigint';
2267
- }, NumberSchemaNode], [{
2268
- type: string;
2269
- }, ScalarSchemaNode], [{
2270
- minLength: number;
2271
- }, StringSchemaNode], [{
2272
- maxLength: number;
2273
- }, StringSchemaNode], [{
2274
- pattern: string;
2275
- }, StringSchemaNode], [{
2276
- minimum: number;
2277
- }, NumberSchemaNode], [{
2278
- maximum: number;
2279
- }, NumberSchemaNode]];
2280
- /**
2281
- * Infers the matching AST `SchemaNode` type from an input schema shape.
2282
- */
2283
- type InferSchemaNode<TSchema extends object, TDateType extends ParserOptions['dateType'] = 'string', TEntries extends ReadonlyArray<[object, SchemaNode]> = SchemaNodeMap<TDateType>> = TEntries extends [infer TEntry extends [object, SchemaNode], ...infer TRest extends ReadonlyArray<[object, SchemaNode]>] ? TSchema extends TEntry[0] ? TEntry[1] : InferSchemaNode<TSchema, TDateType, TRest> : SchemaNode;
2284
- //#endregion
2285
- //#region src/factory.d.ts
2286
- /**
2287
- * Updates a schema's `optional` and `nullish` flags from a parent's `required`
2288
- * value and the schema's own `nullable`. Mirrors how OpenAPI parameters and
2289
- * object properties combine "required" and "nullable" into a single AST.
2290
- *
2291
- * - Non-required + non-nullable → `optional: true`.
2292
- * - Non-required + nullable → `nullish: true`.
2293
- * - Required → both flags cleared.
2294
- */
2295
- declare function syncOptionality(schema: SchemaNode, required: boolean): SchemaNode;
2296
- /**
2297
- * Distributive `Omit` that preserves each member of a union.
1249
+ * IPv4 address schema node.
2298
1250
  *
2299
1251
  * @example
2300
1252
  * ```ts
2301
- * type A = { kind: 'a'; keep: string; drop: number }
2302
- * type B = { kind: 'b'; keep: boolean; drop: number }
2303
- * type Result = DistributiveOmit<A | B, 'drop'>
2304
- * // -> { kind: 'a'; keep: string } | { kind: 'b'; keep: boolean }
1253
+ * const ipv4Schema: Ipv4SchemaNode = { kind: 'Schema', type: 'ipv4' }
2305
1254
  * ```
2306
1255
  */
2307
- type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
1256
+ type Ipv4SchemaNode = SchemaNodeBase & {
1257
+ /**
1258
+ * Schema type discriminator.
1259
+ */
1260
+ type: 'ipv4';
1261
+ };
2308
1262
  /**
2309
- * Identity-preserving node update: returns `node` unchanged when every field in
2310
- * `changes` already equals (by reference) the current value, otherwise a new node
2311
- * with the changes applied.
2312
- *
2313
- * Mirrors the TypeScript compiler's `factory.updateX` contract, pair it with the
2314
- * structural sharing in {@link transform} so a no-op rewrite doesn't allocate and
2315
- * downstream passes can detect "nothing changed" by identity. Comparison is
2316
- * shallow: a structurally-equal but newly-allocated array/object counts as a change.
1263
+ * IPv6 address schema node.
2317
1264
  *
2318
1265
  * @example
2319
1266
  * ```ts
2320
- * update(node, { name: node.name }) // -> same `node` reference
2321
- * update(node, { name: 'renamed' }) // -> new node, `name` replaced
1267
+ * const ipv6Schema: Ipv6SchemaNode = { kind: 'Schema', type: 'ipv6' }
2322
1268
  * ```
2323
1269
  */
2324
- declare function update<T extends Node>(node: T, changes: Partial<T>): T;
1270
+ type Ipv6SchemaNode = SchemaNodeBase & {
1271
+ /**
1272
+ * Schema type discriminator.
1273
+ */
1274
+ type: 'ipv6';
1275
+ };
1276
+ /**
1277
+ * Mapping from schema type literals to concrete schema node types.
1278
+ * Used by `narrowSchema`.
1279
+ */
1280
+ type SchemaNodeByType = {
1281
+ object: ObjectSchemaNode;
1282
+ array: ArraySchemaNode;
1283
+ tuple: ArraySchemaNode;
1284
+ union: UnionSchemaNode;
1285
+ intersection: IntersectionSchemaNode;
1286
+ enum: EnumSchemaNode;
1287
+ ref: RefSchemaNode;
1288
+ datetime: DatetimeSchemaNode;
1289
+ date: DateSchemaNode;
1290
+ time: TimeSchemaNode;
1291
+ string: StringSchemaNode;
1292
+ number: NumberSchemaNode;
1293
+ integer: NumberSchemaNode;
1294
+ bigint: NumberSchemaNode;
1295
+ boolean: ScalarSchemaNode;
1296
+ null: ScalarSchemaNode;
1297
+ any: ScalarSchemaNode;
1298
+ unknown: ScalarSchemaNode;
1299
+ void: ScalarSchemaNode;
1300
+ never: ScalarSchemaNode;
1301
+ uuid: FormatStringSchemaNode;
1302
+ email: FormatStringSchemaNode;
1303
+ url: UrlSchemaNode;
1304
+ ipv4: Ipv4SchemaNode;
1305
+ ipv6: Ipv6SchemaNode;
1306
+ blob: ScalarSchemaNode;
1307
+ };
1308
+ /**
1309
+ * Union of all schema node types.
1310
+ */
1311
+ type SchemaNode = ObjectSchemaNode | ArraySchemaNode | UnionSchemaNode | IntersectionSchemaNode | EnumSchemaNode | RefSchemaNode | DatetimeSchemaNode | DateSchemaNode | TimeSchemaNode | StringSchemaNode | NumberSchemaNode | UrlSchemaNode | FormatStringSchemaNode | Ipv4SchemaNode | Ipv6SchemaNode | ScalarSchemaNode;
2325
1312
  type CreateSchemaObjectInput = Omit<ObjectSchemaNode, 'kind' | 'properties' | 'primitive'> & {
2326
1313
  properties?: Array<PropertyNode>;
2327
1314
  primitive?: 'object';
@@ -2331,88 +1318,12 @@ type CreateSchemaOutput<T extends CreateSchemaInput> = InferSchemaNode<T> & {
2331
1318
  kind: 'Schema';
2332
1319
  };
2333
1320
  /**
2334
- * Creates an `InputNode` with stable defaults for `schemas` and `operations`.
2335
- *
2336
- * @example
2337
- * ```ts
2338
- * const input = createInput()
2339
- * // { kind: 'Input', schemas: [], operations: [] }
2340
- * ```
2341
- *
2342
- * @example
2343
- * ```ts
2344
- * const input = createInput({ schemas: [petSchema] })
2345
- * // keeps default operations: []
2346
- * ```
2347
- */
2348
- declare function createInput(overrides?: Partial<Omit<InputNode, 'kind'>>): InputNode;
2349
- /**
2350
- * Creates a streaming `InputNode<true>` from pre-built `AsyncIterable` sources.
2351
- *
2352
- * @example
2353
- * ```ts
2354
- * const node = createStreamInput(schemasIterable, operationsIterable, { title: 'My API' })
2355
- * ```
2356
- */
2357
- declare function createStreamInput(schemas: AsyncIterable<SchemaNode>, operations: AsyncIterable<OperationNode>, meta?: InputMeta): InputNode<true>;
2358
- /**
2359
- * Creates an `OutputNode` with a stable default for `files`.
2360
- *
2361
- * @example
2362
- * ```ts
2363
- * const output = createOutput()
2364
- * // { kind: 'Output', files: [] }
2365
- * ```
2366
- *
2367
- * @example
2368
- * ```ts
2369
- * const output = createOutput({ files: [petFile] })
2370
- * ```
2371
- */
2372
- declare function createOutput(overrides?: Partial<Omit<OutputNode, 'kind'>>): OutputNode;
2373
- /**
2374
- * Creates an `OperationNode` with default empty arrays for `tags`, `parameters`, and `responses`.
2375
- *
2376
- * @example
2377
- * ```ts
2378
- * const operation = createOperation({
2379
- * operationId: 'getPetById',
2380
- * method: 'GET',
2381
- * path: '/pet/{petId}',
2382
- * })
2383
- * // tags, parameters, and responses are []
2384
- * ```
2385
- *
2386
- * @example
2387
- * ```ts
2388
- * const operation = createOperation({
2389
- * operationId: 'findPets',
2390
- * method: 'GET',
2391
- * path: '/pet/findByStatus',
2392
- * tags: ['pet'],
2393
- * })
2394
- * ```
2395
- */
2396
- /**
2397
- * Loosely-typed content entry accepted by the builders, normalized into a {@link ContentNode}.
2398
- */
2399
- type UserContent = Omit<ContentNode, 'kind'>;
2400
- /**
2401
- * Loosely-typed request body accepted by `createOperation`, normalized into a {@link RequestBodyNode}.
1321
+ * Definition for the {@link SchemaNode}. Object schemas default `properties` to an
1322
+ * empty array, and `primitive` is inferred from `type` when not explicitly provided.
2402
1323
  */
2403
- type UserRequestBody = Omit<RequestBodyNode, 'kind' | 'content'> & {
2404
- content?: Array<UserContent>;
2405
- };
2406
- declare function createOperation(props: Pick<HttpOperationNode, 'operationId' | 'method' | 'path'> & Partial<Omit<HttpOperationNode, 'kind' | 'operationId' | 'method' | 'path' | 'requestBody'>> & {
2407
- requestBody?: UserRequestBody;
2408
- }): HttpOperationNode;
2409
- declare function createOperation(props: Pick<GenericOperationNode, 'operationId'> & Partial<Omit<GenericOperationNode, 'kind' | 'operationId' | 'requestBody'>> & {
2410
- requestBody?: UserRequestBody;
2411
- }): GenericOperationNode;
1324
+ declare const schemaDef: NodeDef<SchemaNode, CreateSchemaInput>;
2412
1325
  /**
2413
1326
  * Creates a `SchemaNode`, narrowed to the variant of `props.type`.
2414
- * For object schemas, `properties` defaults to an empty array.
2415
- * `primitive` is automatically inferred from `type` when not explicitly provided.
2416
1327
  *
2417
1328
  * @example
2418
1329
  * ```ts
@@ -2422,220 +1333,293 @@ declare function createOperation(props: Pick<GenericOperationNode, 'operationId'
2422
1333
  *
2423
1334
  * @example
2424
1335
  * ```ts
2425
- * const uuid = createSchema({ type: 'uuid' })
2426
- * // { kind: 'Schema', type: 'uuid', primitive: 'string' }
2427
- * ```
2428
- *
2429
- * @example
2430
- * ```ts
2431
1336
  * const object = createSchema({ type: 'object' })
2432
1337
  * // { kind: 'Schema', type: 'object', primitive: 'object', properties: [] }
2433
1338
  * ```
2434
- *
2435
- * @example
2436
- * ```ts
2437
- * const enumSchema = createSchema({
2438
- * type: 'enum',
2439
- * primitive: 'string',
2440
- * enumValues: ['available', 'pending'],
2441
- * })
2442
- * ```
2443
1339
  */
2444
1340
  declare function createSchema<T extends CreateSchemaInput>(props: T): CreateSchemaOutput<T>;
2445
1341
  declare function createSchema(props: CreateSchemaInput): SchemaNode;
2446
- type UserPropertyNode = Pick<PropertyNode, 'name' | 'schema'> & Partial<Omit<PropertyNode, 'kind' | 'name' | 'schema'>>;
1342
+ //#endregion
1343
+ //#region src/nodes/content.d.ts
2447
1344
  /**
2448
- * Creates a `PropertyNode`.
1345
+ * AST node representing one content-type entry of a request body or response.
2449
1346
  *
2450
- * `required` defaults to `false`.
2451
- * `schema.optional` and `schema.nullish` are derived from `required` and `schema.nullable`.
1347
+ * One entry per content type declared in the spec (e.g. `application/json`,
1348
+ * `multipart/form-data`), each carrying its own body schema.
2452
1349
  *
2453
1350
  * @example
2454
1351
  * ```ts
2455
- * const property = createProperty({
2456
- * name: 'status',
1352
+ * const content: ContentNode = {
1353
+ * kind: 'Content',
1354
+ * contentType: 'application/json',
2457
1355
  * schema: createSchema({ type: 'string' }),
2458
- * })
2459
- * // required=false, schema.optional=true
2460
- * ```
2461
- *
2462
- * @example
2463
- * ```ts
2464
- * const property = createProperty({
2465
- * name: 'status',
2466
- * required: true,
2467
- * schema: createSchema({ type: 'string', nullable: true }),
2468
- * })
2469
- * // required=true, no optional/nullish
1356
+ * }
2470
1357
  * ```
2471
1358
  */
2472
- declare function createProperty(props: UserPropertyNode): PropertyNode;
1359
+ type ContentNode = BaseNode & {
1360
+ /**
1361
+ * Node kind.
1362
+ */
1363
+ kind: 'Content';
1364
+ /**
1365
+ * The content type for this entry (e.g. `'application/json'`).
1366
+ */
1367
+ contentType: string;
1368
+ /**
1369
+ * Body schema for this content type.
1370
+ */
1371
+ schema?: SchemaNode;
1372
+ /**
1373
+ * Property keys to exclude from the generated type via `Omit<Type, Keys>`.
1374
+ * Set when a referenced schema has `readOnly`/`writeOnly` fields that should be omitted.
1375
+ */
1376
+ keysToOmit?: Array<string> | null;
1377
+ };
2473
1378
  /**
2474
- * Creates a `ParameterNode`.
2475
- *
2476
- * `required` defaults to `false`.
2477
- * Nested schema flags are set from `required` and `schema.nullable`.
2478
- *
2479
- * @example
2480
- * ```ts
2481
- * const param = createParameter({
2482
- * name: 'petId',
2483
- * in: 'path',
2484
- * required: true,
2485
- * schema: createSchema({ type: 'string' }),
2486
- * })
2487
- * ```
2488
- *
2489
- * @example
2490
- * ```ts
2491
- * const param = createParameter({
2492
- * name: 'status',
2493
- * in: 'query',
2494
- * schema: createSchema({ type: 'string', nullable: true }),
2495
- * })
2496
- * // required=false, schema.nullish=true
2497
- * ```
1379
+ * Loosely-typed content entry accepted by the builders, normalized into a {@link ContentNode}.
2498
1380
  */
2499
- declare function createParameter(props: Pick<ParameterNode, 'name' | 'in' | 'schema'> & Partial<Omit<ParameterNode, 'kind' | 'name' | 'in' | 'schema'>>): ParameterNode;
1381
+ type UserContent = Omit<ContentNode, 'kind'>;
2500
1382
  /**
2501
- * Creates a `ResponseNode`.
2502
- *
2503
- * Response body schemas live inside `content`. For convenience a single legacy `schema`
2504
- * (with optional `mediaType`/`keysToOmit`) is normalized into one `content` entry, so the same
2505
- * schema is never stored both at the node root and inside `content`.
2506
- *
2507
- * @example
2508
- * ```ts
2509
- * const response = createResponse({
2510
- * statusCode: '200',
2511
- * content: [{ contentType: 'application/json', schema: createSchema({ type: 'object', properties: [] }) }],
2512
- * })
2513
- * ```
1383
+ * Definition for the {@link ContentNode}.
2514
1384
  */
2515
- declare function createResponse(props: Pick<ResponseNode, 'statusCode'> & Partial<Omit<ResponseNode, 'kind' | 'statusCode' | 'content'>> & {
2516
- content?: Array<UserContent>;
2517
- schema?: SchemaNode;
2518
- mediaType?: string | null;
2519
- keysToOmit?: Array<string> | null;
2520
- }): ResponseNode;
1385
+ declare const contentDef: NodeDef<ContentNode, UserContent>;
1386
+ /**
1387
+ * Creates a `ContentNode` for a single request-body or response content type.
1388
+ */
1389
+ declare const createContent: (input: UserContent) => ContentNode;
1390
+ //#endregion
1391
+ //#region src/nodes/file.d.ts
2521
1392
  /**
2522
- * Creates a `FunctionParameterNode`.
1393
+ * Supported file extensions.
1394
+ */
1395
+ type Extname = '.ts' | '.js' | '.tsx' | '.json' | `.${string}`;
1396
+ type ImportName = string | Array<string | {
1397
+ propertyName: string;
1398
+ name?: string;
1399
+ }>;
1400
+ /**
1401
+ * Represents a language-agnostic import/dependency declaration.
2523
1402
  *
2524
- * `optional` defaults to `false`.
1403
+ * @example Named import (TypeScript: `import { useState } from 'react'`)
1404
+ * ```ts
1405
+ * createImport({ name: ['useState'], path: 'react' })
1406
+ * ```
2525
1407
  *
2526
- * @example Required typed param
1408
+ * @example Default import (TypeScript: `import React from 'react'`)
2527
1409
  * ```ts
2528
- * createFunctionParameter({ name: 'petId', type: createParamsType({ variant: 'reference', name: 'string' }) })
2529
- * // → petId: string
1410
+ * createImport({ name: 'React', path: 'react' })
2530
1411
  * ```
2531
1412
  *
2532
- * @example Optional param
1413
+ * @example Type-only import (TypeScript: `import type { FC } from 'react'`)
2533
1414
  * ```ts
2534
- * createFunctionParameter({ name: 'params', type: createParamsType({ variant: 'reference', name: 'QueryParams' }), optional: true })
2535
- * // → params?: QueryParams
1415
+ * createImport({ name: ['FC'], path: 'react', isTypeOnly: true })
2536
1416
  * ```
2537
1417
  *
2538
- * @example Param with default (implicitly optional. Cannot combine with `optional: true`)
1418
+ * @example Namespace import (TypeScript: `import * as React from 'react'`)
2539
1419
  * ```ts
2540
- * createFunctionParameter({ name: 'config', type: createParamsType({ variant: 'reference', name: 'RequestConfig' }), default: '{}' })
2541
- * // → config: RequestConfig = {}
1420
+ * createImport({ name: 'React', path: 'react', isNameSpace: true })
2542
1421
  * ```
2543
1422
  */
2544
- declare function createFunctionParameter(props: {
2545
- name: string;
2546
- type?: ParamsTypeNode;
2547
- rest?: boolean;
2548
- } & ({
2549
- optional: true;
2550
- default?: never;
2551
- } | {
2552
- optional?: false;
2553
- default?: string;
2554
- })): FunctionParameterNode;
1423
+ type ImportNode = BaseNode & {
1424
+ kind: 'Import';
1425
+ /**
1426
+ * Import name(s) to be used.
1427
+ * @example ['useState']
1428
+ * @example 'React'
1429
+ */
1430
+ name: ImportName;
1431
+ /**
1432
+ * Path for the import.
1433
+ * @example '@kubb/core'
1434
+ */
1435
+ path: string;
1436
+ /**
1437
+ * Add type-only import prefix.
1438
+ * - `true` generates `import type { Type } from './path'`
1439
+ * - `false` generates `import { Type } from './path'`
1440
+ * @default false
1441
+ */
1442
+ isTypeOnly?: boolean | null;
1443
+ /**
1444
+ * Import entire module as namespace.
1445
+ * - `true` generates `import * as Name from './path'`
1446
+ * - `false` generates standard import
1447
+ * @default false
1448
+ */
1449
+ isNameSpace?: boolean | null;
1450
+ /**
1451
+ * When set, the import path is resolved relative to this root.
1452
+ */
1453
+ root?: string | null;
1454
+ };
2555
1455
  /**
2556
- * Creates a {@link TypeNode} representing a language-agnostic structured type expression.
1456
+ * Represents a language-agnostic export/public API declaration.
2557
1457
  *
2558
- * Use `variant: 'struct'` for inline anonymous types and `variant: 'member'` for a single
2559
- * named field accessed from a group type. Each language's printer renders the variant
2560
- * into its own syntax (TypeScript, Python, C#, Kotlin, …).
1458
+ * @example Named export (TypeScript: `export { Pets } from './Pets'`)
1459
+ * ```ts
1460
+ * createExport({ name: ['Pets'], path: './Pets' })
1461
+ * ```
2561
1462
  *
2562
- * @example Reference type (TypeScript: `QueryParams`)
1463
+ * @example Type-only export (TypeScript: `export type { Pet } from './Pet'`)
2563
1464
  * ```ts
2564
- * createParamsType({ variant: 'reference', name: 'QueryParams' })
1465
+ * createExport({ name: ['Pet'], path: './Pet', isTypeOnly: true })
2565
1466
  * ```
2566
1467
  *
2567
- * @example Struct type (TypeScript: `{ petId: string }`)
1468
+ * @example Wildcard export (TypeScript: `export * from './utils'`)
2568
1469
  * ```ts
2569
- * createParamsType({ variant: 'struct', properties: [{ name: 'petId', optional: false, type: createParamsType({ variant: 'reference', name: 'string' }) }] })
1470
+ * createExport({ path: './utils' })
2570
1471
  * ```
2571
1472
  *
2572
- * @example Member type (TypeScript: `DeletePetPathParams['petId']`)
1473
+ * @example Namespace alias (TypeScript: `export * as utils from './utils'`)
2573
1474
  * ```ts
2574
- * createParamsType({ variant: 'member', base: 'DeletePetPathParams', key: 'petId' })
1475
+ * createExport({ name: 'utils', path: './utils', asAlias: true })
2575
1476
  * ```
2576
1477
  */
2577
- declare function createParamsType(props: {
2578
- variant: 'reference';
2579
- name: string;
2580
- } | {
2581
- variant: 'struct';
2582
- properties: Array<{
2583
- name: string;
2584
- optional: boolean;
2585
- type: ParamsTypeNode;
2586
- }>;
2587
- } | {
2588
- variant: 'member';
2589
- base: string;
2590
- key: string;
2591
- }): ParamsTypeNode;
1478
+ type ExportNode = BaseNode & {
1479
+ kind: 'Export';
1480
+ /**
1481
+ * Export name(s) to be used. When omitted, generates a wildcard export.
1482
+ * @example ['useState']
1483
+ * @example 'React'
1484
+ */
1485
+ name?: string | Array<string> | null;
1486
+ /**
1487
+ * Path for the export.
1488
+ * @example '@kubb/core'
1489
+ */
1490
+ path: string;
1491
+ /**
1492
+ * Add type-only export prefix.
1493
+ * - `true` generates `export type { Type } from './path'`
1494
+ * - `false` generates `export { Type } from './path'`
1495
+ * @default false
1496
+ */
1497
+ isTypeOnly?: boolean | null;
1498
+ /**
1499
+ * Export as an aliased namespace.
1500
+ * - `true` generates `export * as aliasName from './path'`
1501
+ * - `false` generates a standard export
1502
+ * @default false
1503
+ */
1504
+ asAlias?: boolean | null;
1505
+ };
2592
1506
  /**
2593
- * Creates a `ParameterGroupNode` representing a group of related parameters treated as a unit.
1507
+ * Represents a fragment of source code within a file.
2594
1508
  *
2595
- * @example Grouped param (TypeScript declaration)
1509
+ * @example Named exportable source
2596
1510
  * ```ts
2597
- * createParameterGroup({
2598
- * properties: [
2599
- * createFunctionParameter({ name: 'id', type: createParamsType({ variant: 'reference', name: 'string' }), optional: false }),
2600
- * createFunctionParameter({ name: 'name', type: createParamsType({ variant: 'reference', name: 'string' }), optional: true }),
2601
- * ],
2602
- * default: '{}',
2603
- * })
2604
- * // declaration → { id, name? }: { id: string; name?: string } = {}
2605
- * // call → { id, name }
1511
+ * createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true, isIndexable: true })
2606
1512
  * ```
2607
1513
  *
2608
- * @example Inline (spread), children emitted as individual top-level parameters
1514
+ * @example Inline unnamed code block
2609
1515
  * ```ts
2610
- * createParameterGroup({
2611
- * properties: [createFunctionParameter({ name: 'petId', type: createParamsType({ variant: 'reference', name: 'string' }), optional: false })],
2612
- * inline: true,
2613
- * })
2614
- * // declaration → petId: string
2615
- * // call → petId
1516
+ * createSource({ nodes: [createText('const x = 1')] })
2616
1517
  * ```
2617
1518
  */
2618
- declare function createParameterGroup(props: Pick<ParameterGroupNode, 'properties'> & Partial<Omit<ParameterGroupNode, 'kind' | 'properties'>>): ParameterGroupNode;
1519
+ type SourceNode = BaseNode & {
1520
+ kind: 'Source';
1521
+ /**
1522
+ * Optional name identifying this source (used for deduplication and barrel generation).
1523
+ */
1524
+ name?: string | null;
1525
+ /**
1526
+ * Mark this source as a type-only export.
1527
+ * @default false
1528
+ */
1529
+ isTypeOnly?: boolean | null;
1530
+ /**
1531
+ * Include `export` keyword in the generated source.
1532
+ * @default false
1533
+ */
1534
+ isExportable?: boolean | null;
1535
+ /**
1536
+ * Include this source in barrel/index file generation.
1537
+ * @default false
1538
+ */
1539
+ isIndexable?: boolean | null;
1540
+ /**
1541
+ * Structured child nodes representing the content of this source fragment, in DOM order.
1542
+ * Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
1543
+ */
1544
+ nodes?: Array<CodeNode>;
1545
+ };
2619
1546
  /**
2620
- * Creates a `FunctionParametersNode` from an ordered list of parameters.
1547
+ * Represents a fully resolved file in the AST.
2621
1548
  *
2622
- * @example
2623
- * ```ts
2624
- * createFunctionParameters({
2625
- * params: [
2626
- * createFunctionParameter({ name: 'petId', type: createParamsType({ variant: 'reference', name: 'string' }), optional: false }),
2627
- * createFunctionParameter({ name: 'config', type: createParamsType({ variant: 'reference', name: 'RequestConfig' }), optional: false, default: '{}' }),
2628
- * ],
2629
- * })
2630
- * ```
1549
+ * Created via `createFile()`, which computes the `id`, `name`, and `extname` from the input
1550
+ * and deduplicates `imports`, `exports`, and `sources`.
2631
1551
  *
2632
1552
  * @example
2633
1553
  * ```ts
2634
- * const empty = createFunctionParameters()
2635
- * // { kind: 'FunctionParameters', params: [] }
1554
+ * const file = createFile({
1555
+ * baseName: 'petStore.ts',
1556
+ * path: 'src/models/petStore.ts',
1557
+ * sources: [createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true })],
1558
+ * imports: [createImport({ name: ['z'], path: 'zod' })],
1559
+ * exports: [createExport({ name: ['Pet'], path: './petStore' })],
1560
+ * })
1561
+ * // file.id = SHA256 hash of the path
1562
+ * // file.name = 'petStore'
1563
+ * // file.extname = '.ts'
2636
1564
  * ```
2637
1565
  */
2638
- declare function createFunctionParameters(props?: Partial<Omit<FunctionParametersNode, 'kind'>>): FunctionParametersNode;
1566
+ type FileNode<TMeta extends object = object> = BaseNode & {
1567
+ kind: 'File';
1568
+ /**
1569
+ * Unique identifier derived from a SHA256 hash of the file path. Computed
1570
+ * by `createFile`; callers do not need to provide it.
1571
+ */
1572
+ id: string;
1573
+ /**
1574
+ * File name without extension, derived from `baseName`.
1575
+ * @link https://nodejs.org/api/path.html#pathformatpathobject
1576
+ */
1577
+ name: string;
1578
+ /**
1579
+ * File base name, including extension.
1580
+ * Based on UNIX basename: `${name}${extname}`
1581
+ * @link https://nodejs.org/api/path.html#pathbasenamepath-suffix
1582
+ */
1583
+ baseName: `${string}.${string}`;
1584
+ /**
1585
+ * Full qualified path to the file.
1586
+ */
1587
+ path: string;
1588
+ /**
1589
+ * File extension extracted from `baseName`.
1590
+ */
1591
+ extname: Extname;
1592
+ /**
1593
+ * Deduplicated list of source code fragments.
1594
+ */
1595
+ sources: Array<SourceNode>;
1596
+ /**
1597
+ * Deduplicated list of import declarations.
1598
+ */
1599
+ imports: Array<ImportNode>;
1600
+ /**
1601
+ * Deduplicated list of export declarations.
1602
+ */
1603
+ exports: Array<ExportNode>;
1604
+ /**
1605
+ * Optional metadata attached to this file (used by plugins for barrel generation etc.).
1606
+ */
1607
+ meta?: TMeta;
1608
+ /**
1609
+ * Optional banner prepended to the generated file content.
1610
+ * Accepts `null` so `resolver.resolveBanner()` results can be passed directly.
1611
+ */
1612
+ banner?: string | null;
1613
+ /**
1614
+ * Optional footer appended to the generated file content.
1615
+ * Accepts `null` so `resolver.resolveFooter()` results can be passed directly.
1616
+ */
1617
+ footer?: string | null;
1618
+ };
1619
+ /**
1620
+ * Definition for the {@link ImportNode}.
1621
+ */
1622
+ declare const importDef: NodeDef<ImportNode, Omit<ImportNode, "kind">>;
2639
1623
  /**
2640
1624
  * Creates an `ImportNode` representing a language-agnostic import/dependency declaration.
2641
1625
  *
@@ -2644,14 +1628,12 @@ declare function createFunctionParameters(props?: Partial<Omit<FunctionParameter
2644
1628
  * createImport({ name: ['useState'], path: 'react' })
2645
1629
  * // import { useState } from 'react'
2646
1630
  * ```
2647
- *
2648
- * @example Type-only import
2649
- * ```ts
2650
- * createImport({ name: ['FC'], path: 'react', isTypeOnly: true })
2651
- * // import type { FC } from 'react'
2652
- * ```
2653
1631
  */
2654
- declare function createImport(props: Omit<ImportNode, 'kind'>): ImportNode;
1632
+ declare const createImport: (input: Omit<ImportNode, "kind">) => ImportNode;
1633
+ /**
1634
+ * Definition for the {@link ExportNode}.
1635
+ */
1636
+ declare const exportDef: NodeDef<ExportNode, Omit<ExportNode, "kind">>;
2655
1637
  /**
2656
1638
  * Creates an `ExportNode` representing a language-agnostic export/public API declaration.
2657
1639
  *
@@ -2660,14 +1642,12 @@ declare function createImport(props: Omit<ImportNode, 'kind'>): ImportNode;
2660
1642
  * createExport({ name: ['Pet'], path: './Pet' })
2661
1643
  * // export { Pet } from './Pet'
2662
1644
  * ```
2663
- *
2664
- * @example Wildcard export
2665
- * ```ts
2666
- * createExport({ path: './utils' })
2667
- * // export * from './utils'
2668
- * ```
2669
1645
  */
2670
- declare function createExport(props: Omit<ExportNode, 'kind'>): ExportNode;
1646
+ declare const createExport: (input: Omit<ExportNode, "kind">) => ExportNode;
1647
+ /**
1648
+ * Definition for the {@link SourceNode}.
1649
+ */
1650
+ declare const sourceDef: NodeDef<SourceNode, Omit<SourceNode, "kind">>;
2671
1651
  /**
2672
1652
  * Creates a `SourceNode` representing a fragment of source code within a file.
2673
1653
  *
@@ -2676,663 +1656,814 @@ declare function createExport(props: Omit<ExportNode, 'kind'>): ExportNode;
2676
1656
  * createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true })
2677
1657
  * ```
2678
1658
  */
2679
- declare function createSource(props: Omit<SourceNode, 'kind'>): SourceNode;
2680
- type UserFileNode<TMeta extends object = object> = Omit<FileNode<TMeta>, 'kind' | 'id' | 'name' | 'extname' | 'imports' | 'exports' | 'sources'> & Pick<Partial<FileNode<TMeta>>, 'imports' | 'exports' | 'sources'>;
1659
+ declare const createSource: (input: Omit<SourceNode, "kind">) => SourceNode;
2681
1660
  /**
2682
- * Creates a fully resolved `FileNode` from a file input descriptor.
2683
- *
2684
- * Computes:
2685
- * - `id` SHA256 hash of the file path
2686
- * - `name` `baseName` without extension
2687
- * - `extname` extension extracted from `baseName`
2688
- *
2689
- * Deduplicates:
2690
- * - `sources` via `combineSources`
2691
- * - `exports` via `combineExports`
2692
- * - `imports` via `combineImports` (also filters unused imports)
1661
+ * Definition for the {@link FileNode}. The fully resolved builder lives in
1662
+ * `createFile`, so this definition only supplies the guard.
1663
+ */
1664
+ declare const fileDef: NodeDef<FileNode<object>, Omit<FileNode<object>, "kind">>;
1665
+ //#endregion
1666
+ //#region src/nodes/function.d.ts
1667
+ /**
1668
+ * A language-agnostic type expression used as a function parameter type annotation.
2693
1669
  *
2694
- * @throws {Error} when `baseName` has no extension.
1670
+ * - a plain `string` is a type reference rendered as-is, e.g. `'string'`, `'QueryParams'`, `'Partial<Config>'`
1671
+ * - a {@link TypeLiteralNode} is an inline anonymous type, e.g. `{ petId: string; name?: string }`
1672
+ * - an {@link IndexedAccessTypeNode} is a single field accessed from a named type, e.g. `PathParams['petId']`
1673
+ */
1674
+ type TypeExpression = string | TypeLiteralNode | IndexedAccessTypeNode;
1675
+ /**
1676
+ * AST node for an inline anonymous object type grouping named fields.
1677
+ * TypeScript renders as `{ key: Type; other?: OtherType }`.
2695
1678
  *
2696
1679
  * @example
2697
1680
  * ```ts
2698
- * const file = createFile({
2699
- * baseName: 'petStore.ts',
2700
- * path: 'src/models/petStore.ts',
2701
- * sources: [createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')] })],
2702
- * imports: [createImport({ name: ['z'], path: 'zod' })],
2703
- * exports: [createExport({ name: ['Pet'], path: './petStore' })],
2704
- * })
2705
- * // file.id = SHA256 hash of 'src/models/petStore.ts'
2706
- * // file.name = 'petStore'
2707
- * // file.extname = '.ts'
1681
+ * createTypeLiteral({ members: [{ name: 'petId', type: 'string', optional: false }] })
1682
+ * // { petId: string }
2708
1683
  * ```
2709
1684
  */
2710
- declare function createFile<TMeta extends object = object>(input: UserFileNode<TMeta>): FileNode<TMeta>;
1685
+ type TypeLiteralNode = BaseNode & {
1686
+ /**
1687
+ * Node kind.
1688
+ */
1689
+ kind: 'TypeLiteral';
1690
+ /**
1691
+ * Members of the object type, rendered in order.
1692
+ */
1693
+ members: Array<{
1694
+ /**
1695
+ * Member key.
1696
+ */
1697
+ name: string;
1698
+ /**
1699
+ * Member type expression.
1700
+ */
1701
+ type: TypeExpression;
1702
+ /**
1703
+ * Whether the member is optional, rendered with `?`.
1704
+ */
1705
+ optional?: boolean;
1706
+ }>;
1707
+ };
2711
1708
  /**
2712
- * Creates a `ConstNode` representing a TypeScript `const` declaration.
2713
- *
2714
- * Mirrors the `Const` component from `@kubb/renderer-jsx`.
2715
- * The component's `children` are represented as `nodes`.
2716
- *
2717
- * @example Simple constant
2718
- * ```ts
2719
- * createConst({ name: 'pet' })
2720
- * // const pet = ...
2721
- * ```
1709
+ * AST node for a single field accessed from a named group type.
1710
+ * TypeScript renders as `objectType['indexType']`.
2722
1711
  *
2723
- * @example Exported constant with type and `as const`
1712
+ * @example
2724
1713
  * ```ts
2725
- * createConst({ name: 'pets', export: true, type: 'Pet[]', asConst: true })
2726
- * // export const pets: Pet[] = ... as const
1714
+ * createIndexedAccessType({ objectType: 'GetPetPathParams', indexType: 'petId' })
1715
+ * // GetPetPathParams['petId']
2727
1716
  * ```
1717
+ */
1718
+ type IndexedAccessTypeNode = BaseNode & {
1719
+ /**
1720
+ * Node kind.
1721
+ */
1722
+ kind: 'IndexedAccessType';
1723
+ /**
1724
+ * Name of the type being indexed, e.g. `'GetPetPathParams'`.
1725
+ */
1726
+ objectType: string;
1727
+ /**
1728
+ * Field key to access, e.g. `'petId'`.
1729
+ */
1730
+ indexType: string;
1731
+ };
1732
+ /**
1733
+ * AST node for an object destructuring binding, used as the name of a grouped function parameter.
1734
+ * TypeScript renders as `{ id, name }` or `{ id: renamed }` when `propertyName` differs.
2728
1735
  *
2729
- * @example With JSDoc and child nodes
1736
+ * @example
2730
1737
  * ```ts
2731
- * createConst({
2732
- * name: 'config',
2733
- * export: true,
2734
- * JSDoc: { comments: ['@description App configuration'] },
2735
- * nodes: [],
2736
- * })
1738
+ * createObjectBindingPattern({ elements: [{ name: 'id' }, { name: 'name' }] })
1739
+ * // { id, name }
2737
1740
  * ```
2738
1741
  */
2739
- declare function createConst(props: Omit<ConstNode, 'kind'>): ConstNode;
1742
+ type ObjectBindingPatternNode = BaseNode & {
1743
+ /**
1744
+ * Node kind.
1745
+ */
1746
+ kind: 'ObjectBindingPattern';
1747
+ /**
1748
+ * Bound elements, rendered in order.
1749
+ */
1750
+ elements: Array<{
1751
+ /**
1752
+ * Local binding name.
1753
+ */
1754
+ name: string;
1755
+ /**
1756
+ * Source key when it differs from the binding name, rendered as `propertyName: name`.
1757
+ */
1758
+ propertyName?: string;
1759
+ }>;
1760
+ };
2740
1761
  /**
2741
- * Creates a `TypeNode` representing a TypeScript `type` alias declaration.
1762
+ * AST node for one function parameter.
2742
1763
  *
2743
- * Mirrors the `Type` component from `@kubb/renderer-jsx`.
2744
- * The component's `children` are represented as `nodes`.
1764
+ * A simple parameter has a `string` name. A destructured group has an
1765
+ * {@link ObjectBindingPatternNode} name paired with a {@link TypeLiteralNode} type.
2745
1766
  *
2746
- * @example Simple type alias
2747
- * ```ts
2748
- * createType({ name: 'Pet' })
2749
- * // type Pet = ...
2750
- * ```
1767
+ * @example Required parameter
1768
+ * `name: Type`
2751
1769
  *
2752
- * @example Exported type with JSDoc
2753
- * ```ts
2754
- * createType({
2755
- * name: 'PetStatus',
2756
- * export: true,
2757
- * JSDoc: { comments: ['@description Status of a pet'] },
2758
- * })
2759
- * // export type PetStatus = ...
2760
- * ```
1770
+ * @example Optional parameter
1771
+ * `name?: Type`
1772
+ *
1773
+ * @example Parameter with default value
1774
+ * `name: Type = defaultValue`
1775
+ *
1776
+ * @example Rest parameter
1777
+ * `...name: Type[]`
1778
+ *
1779
+ * @example Destructured group
1780
+ * `{ id, name? }: { id: string; name?: string } = {}`
2761
1781
  */
2762
- declare function createType(props: Omit<TypeNode, 'kind'>): TypeNode;
1782
+ type FunctionParameterNode = BaseNode & {
1783
+ /**
1784
+ * Node kind.
1785
+ */
1786
+ kind: 'FunctionParameter';
1787
+ /**
1788
+ * Parameter name, or an {@link ObjectBindingPatternNode} for a destructured group.
1789
+ */
1790
+ name: string | ObjectBindingPatternNode;
1791
+ /**
1792
+ * Type annotation as a {@link TypeExpression}. Omit for untyped output.
1793
+ */
1794
+ type?: TypeExpression;
1795
+ /**
1796
+ * Whether the parameter is optional, rendered with `?`.
1797
+ */
1798
+ optional?: boolean;
1799
+ /**
1800
+ * Default value, written verbatim after `=`. Commonly `'{}'` for a destructured group.
1801
+ */
1802
+ default?: string;
1803
+ /**
1804
+ * When `true` the parameter is emitted as a rest parameter, e.g. `...name: Type[]`.
1805
+ */
1806
+ rest?: boolean;
1807
+ };
2763
1808
  /**
2764
- * Creates a `FunctionNode` representing a TypeScript `function` declaration.
1809
+ * AST node for a complete function parameter list.
1810
+ *
1811
+ * Printers are responsible for sorting (`required` → `optional` → `defaulted`).
1812
+ * Nodes are plain immutable data.
2765
1813
  *
2766
- * Mirrors the `Function` component from `@kubb/renderer-jsx`.
2767
- * The component's `children` are represented as `nodes`.
1814
+ * Renders differently depending on the output mode:
1815
+ * - `declaration` `(id: string, config: Config = {})` function declaration parameters
1816
+ * - `call` → `(id, { method, url })` function call arguments
1817
+ */
1818
+ type FunctionParametersNode = BaseNode & {
1819
+ /**
1820
+ * Node kind.
1821
+ */
1822
+ kind: 'FunctionParameters';
1823
+ /**
1824
+ * Ordered parameter nodes.
1825
+ */
1826
+ params: ReadonlyArray<FunctionParameterNode>;
1827
+ };
1828
+ /**
1829
+ * Union of all function-parameter AST node variants used by the function-parameter printer.
1830
+ */
1831
+ type FunctionParamNode = FunctionParameterNode | FunctionParametersNode | TypeLiteralNode | IndexedAccessTypeNode | ObjectBindingPatternNode;
1832
+ /**
1833
+ * Handler-map keys for the function-parameter printer, one per {@link FunctionParamNode} kind.
1834
+ */
1835
+ type FunctionParamKind = FunctionParamNode['kind'];
1836
+ /**
1837
+ * Definition for the {@link TypeLiteralNode}.
1838
+ */
1839
+ declare const typeLiteralDef: NodeDef<TypeLiteralNode, Pick<TypeLiteralNode, "members">>;
1840
+ /**
1841
+ * Creates a {@link TypeLiteralNode} representing an inline anonymous object type.
2768
1842
  *
2769
- * @example Simple function
1843
+ * @example
2770
1844
  * ```ts
2771
- * createFunction({ name: 'getPet' })
2772
- * // function getPet() { ... }
1845
+ * createTypeLiteral({ members: [{ name: 'petId', type: 'string', optional: false }] })
1846
+ * // { petId: string }
2773
1847
  * ```
1848
+ */
1849
+ declare const createTypeLiteral: (input: Pick<TypeLiteralNode, "members">) => TypeLiteralNode;
1850
+ /**
1851
+ * Definition for the {@link IndexedAccessTypeNode}.
1852
+ */
1853
+ declare const indexedAccessTypeDef: NodeDef<IndexedAccessTypeNode, Omit<IndexedAccessTypeNode, "kind">>;
1854
+ /**
1855
+ * Creates an {@link IndexedAccessTypeNode} representing a single field accessed from a named type.
2774
1856
  *
2775
- * @example Exported async function with return type
1857
+ * @example
2776
1858
  * ```ts
2777
- * createFunction({ name: 'fetchPet', export: true, async: true, returnType: 'Pet' })
2778
- * // export async function fetchPet(): Promise<Pet> { ... }
1859
+ * createIndexedAccessType({ objectType: 'DeletePetPathParams', indexType: 'petId' })
1860
+ * // DeletePetPathParams['petId']
2779
1861
  * ```
1862
+ */
1863
+ declare const createIndexedAccessType: (input: Omit<IndexedAccessTypeNode, "kind">) => IndexedAccessTypeNode;
1864
+ /**
1865
+ * Definition for the {@link ObjectBindingPatternNode}.
1866
+ */
1867
+ declare const objectBindingPatternDef: NodeDef<ObjectBindingPatternNode, Pick<ObjectBindingPatternNode, "elements">>;
1868
+ /**
1869
+ * Creates an {@link ObjectBindingPatternNode} for a destructured parameter binding.
2780
1870
  *
2781
- * @example Function with generics and params
1871
+ * @example
2782
1872
  * ```ts
2783
- * createFunction({
2784
- * name: 'identity',
2785
- * export: true,
2786
- * generics: ['T'],
2787
- * params: 'value: T',
2788
- * returnType: 'T',
2789
- * })
2790
- * // export function identity<T>(value: T): T { ... }
1873
+ * createObjectBindingPattern({ elements: [{ name: 'id' }, { name: 'name' }] })
1874
+ * // { id, name }
2791
1875
  * ```
2792
1876
  */
2793
- declare function createFunction(props: Omit<FunctionNode, 'kind'>): FunctionNode;
1877
+ declare const createObjectBindingPattern: (input: Pick<ObjectBindingPatternNode, "elements">) => ObjectBindingPatternNode;
2794
1878
  /**
2795
- * Creates an `ArrowFunctionNode` representing a TypeScript arrow function.
2796
- *
2797
- * Mirrors the `Function.Arrow` component from `@kubb/renderer-jsx`.
2798
- * The component's `children` are represented as `nodes`.
1879
+ * Plain property descriptor for a destructured group built by {@link createFunctionParameter}.
1880
+ */
1881
+ type FunctionParameterProperty = {
1882
+ name: string;
1883
+ type: TypeExpression;
1884
+ optional?: boolean;
1885
+ };
1886
+ type FunctionParameterInput = {
1887
+ name: string;
1888
+ type?: TypeExpression;
1889
+ optional?: boolean;
1890
+ default?: string;
1891
+ rest?: boolean;
1892
+ } | {
1893
+ properties: Array<FunctionParameterProperty>;
1894
+ optional?: boolean;
1895
+ default?: string;
1896
+ };
1897
+ /**
1898
+ * Definition for the {@link FunctionParameterNode}. `optional` defaults to `false`.
1899
+ * Passing `properties` builds a destructured group: an {@link ObjectBindingPatternNode} name
1900
+ * paired with a {@link TypeLiteralNode} type.
1901
+ */
1902
+ declare const functionParameterDef: NodeDef<FunctionParameterNode, FunctionParameterInput>;
1903
+ /**
1904
+ * Creates a `FunctionParameterNode`. `optional` defaults to `false`.
2799
1905
  *
2800
- * @example Simple arrow function
1906
+ * @example Optional param
2801
1907
  * ```ts
2802
- * createArrowFunction({ name: 'getPet' })
2803
- * // const getPet = () => { ... }
1908
+ * createFunctionParameter({ name: 'params', type: 'QueryParams', optional: true })
1909
+ * // params?: QueryParams
2804
1910
  * ```
2805
1911
  *
2806
- * @example Single-line exported arrow function
1912
+ * @example Destructured group
2807
1913
  * ```ts
2808
- * createArrowFunction({ name: 'double', export: true, params: 'n: number', singleLine: true })
2809
- * // export const double = (n: number) => ...
1914
+ * createFunctionParameter({ properties: [{ name: 'id', type: 'string' }, { name: 'name', type: 'string', optional: true }], default: '{}' })
1915
+ * // { id, name }: { id: string; name?: string } = {}
2810
1916
  * ```
1917
+ */
1918
+ declare const createFunctionParameter: (input: FunctionParameterInput) => FunctionParameterNode;
1919
+ /**
1920
+ * Definition for the {@link FunctionParametersNode}.
1921
+ */
1922
+ declare const functionParametersDef: NodeDef<FunctionParametersNode, Partial<Omit<FunctionParametersNode, "kind">>>;
1923
+ /**
1924
+ * Creates a `FunctionParametersNode` from an ordered list of parameters.
2811
1925
  *
2812
- * @example Async arrow function with generics
1926
+ * @example
2813
1927
  * ```ts
2814
- * createArrowFunction({
2815
- * name: 'fetchPet',
2816
- * export: true,
2817
- * async: true,
2818
- * generics: ['T'],
2819
- * params: 'id: string',
2820
- * returnType: 'T',
2821
- * })
2822
- * // export const fetchPet = async <T>(id: string): Promise<T> => { ... }
1928
+ * const empty = createFunctionParameters()
1929
+ * // { kind: 'FunctionParameters', params: [] }
2823
1930
  * ```
2824
1931
  */
2825
- declare function createArrowFunction(props: Omit<ArrowFunctionNode, 'kind'>): ArrowFunctionNode;
1932
+ declare function createFunctionParameters(props?: Partial<Omit<FunctionParametersNode, 'kind'>>): FunctionParametersNode;
1933
+ //#endregion
1934
+ //#region ../../internals/utils/src/promise.d.ts
2826
1935
  /**
2827
- * Creates a {@link TextNode} representing a raw string fragment in the source output.
1936
+ * Container that switches between an eager `Array<T>` and a lazy `AsyncIterable<T>`.
2828
1937
  *
2829
- * Use this instead of bare strings when building `nodes` arrays so that every
2830
- * entry in the array is a typed {@link CodeNode}.
1938
+ * `Array<T>` by default. With `Stream` set to `true` it becomes `AsyncIterable<T>`, so large
1939
+ * collections can be produced lazily without holding every item in memory. Pairs with
1940
+ * {@link arrayToAsyncIterable}, which lifts a plain array into the streaming form.
2831
1941
  *
2832
1942
  * @example
2833
1943
  * ```ts
2834
- * createText('return fetch(id)')
2835
- * // { kind: 'Text', value: 'return fetch(id)' }
1944
+ * type Eager = Streamable<number> // Array<number>
1945
+ * type Lazy = Streamable<number, true> // AsyncIterable<number>
2836
1946
  * ```
2837
1947
  */
2838
- declare function createText(value: string): TextNode;
1948
+ type Streamable<T, Stream extends boolean = false> = Stream extends true ? AsyncIterable<T> : Array<T>;
1949
+ //#endregion
1950
+ //#region src/nodes/parameter.d.ts
1951
+ type ParameterLocation = 'path' | 'query' | 'header' | 'cookie';
2839
1952
  /**
2840
- * Creates a {@link BreakNode} representing a line break in the source output.
2841
- *
2842
- * Corresponds to `<br/>` in JSX components. Prints as an empty string which,
2843
- * when joined with `\n` by `printNodes`, produces a blank line.
1953
+ * AST node representing one operation parameter.
2844
1954
  *
2845
1955
  * @example
2846
1956
  * ```ts
2847
- * createBreak()
2848
- * // { kind: 'Break' }
1957
+ * const param: ParameterNode = {
1958
+ * kind: 'Parameter',
1959
+ * name: 'petId',
1960
+ * in: 'path',
1961
+ * schema: createSchema({ type: 'string' }),
1962
+ * required: true,
1963
+ * }
2849
1964
  * ```
2850
1965
  */
2851
- declare function createBreak(): BreakNode;
1966
+ type ParameterNode = BaseNode & {
1967
+ /**
1968
+ * Node kind.
1969
+ */
1970
+ kind: 'Parameter';
1971
+ /**
1972
+ * Parameter name.
1973
+ */
1974
+ name: string;
1975
+ /**
1976
+ * Parameter location (`path`, `query`, `header`, or `cookie`).
1977
+ */
1978
+ in: ParameterLocation;
1979
+ /**
1980
+ * Parameter schema.
1981
+ */
1982
+ schema: SchemaNode;
1983
+ /**
1984
+ * Whether the parameter is required.
1985
+ */
1986
+ required: boolean;
1987
+ };
1988
+ type UserParameterNode = Pick<ParameterNode, 'name' | 'in' | 'schema'> & Partial<Omit<ParameterNode, 'kind' | 'name' | 'in' | 'schema'>>;
2852
1989
  /**
2853
- * Creates a {@link JsxNode} representing a raw JSX fragment in the source output.
2854
- *
2855
- * Use this to embed JSX markup (including fragments `<>…</>`) directly in generated code.
1990
+ * Definition for the {@link ParameterNode}. `required` defaults to `false` and the
1991
+ * schema's `optional`/`nullish` flags are kept in sync with it.
1992
+ */
1993
+ declare const parameterDef: NodeDef<ParameterNode, UserParameterNode>;
1994
+ /**
1995
+ * Creates a `ParameterNode`.
2856
1996
  *
2857
1997
  * @example
2858
1998
  * ```ts
2859
- * createJsx('<>\n <a href={href}>Open</a>\n</>')
2860
- * // { kind: 'Jsx', value: '<>\n <a href={href}>Open</a>\n</>' }
1999
+ * const param = createParameter({
2000
+ * name: 'petId',
2001
+ * in: 'path',
2002
+ * required: true,
2003
+ * schema: createSchema({ type: 'string' }),
2004
+ * })
2861
2005
  * ```
2862
2006
  */
2863
- declare function createJsx(value: string): JsxNode;
2007
+ declare const createParameter: (input: UserParameterNode) => ParameterNode;
2864
2008
  //#endregion
2865
- //#region src/printer.d.ts
2009
+ //#region src/nodes/requestBody.d.ts
2866
2010
  /**
2867
- * Runtime context passed as `this` to printer handlers.
2011
+ * AST node representing an operation request body.
2868
2012
  *
2869
- * `this.transform` dispatches to node-level handlers from `nodes`.
2013
+ * Body schemas live exclusively inside the `content` array (one entry per content type),
2014
+ * mirroring {@link ResponseNode}.
2870
2015
  *
2871
2016
  * @example
2872
2017
  * ```ts
2873
- * const context: PrinterHandlerContext<string, {}> = {
2874
- * options: {},
2875
- * transform: () => 'value',
2018
+ * const requestBody: RequestBodyNode = {
2019
+ * kind: 'RequestBody',
2020
+ * required: true,
2021
+ * content: [{ kind: 'Content', contentType: 'application/json', schema: createSchema({ type: 'string' }) }],
2876
2022
  * }
2877
2023
  * ```
2878
2024
  */
2879
- type PrinterHandlerContext<TOutput, TOptions extends object> = {
2025
+ type RequestBodyNode = BaseNode & {
2026
+ /**
2027
+ * Node kind.
2028
+ */
2029
+ kind: 'RequestBody';
2030
+ /**
2031
+ * Human-readable request body description.
2032
+ */
2033
+ description?: string;
2880
2034
  /**
2881
- * Recursively transform a nested `SchemaNode` to `TOutput` using the node-level handlers.
2882
- * Use `this.transform` inside `nodes` handlers and inside the `print` override.
2035
+ * Whether the request body is required (`requestBody.required: true` in the spec).
2036
+ * When `false` or absent, the generated `data` parameter should be optional.
2883
2037
  */
2884
- transform: (node: SchemaNode) => TOutput | null;
2038
+ required?: boolean;
2885
2039
  /**
2886
- * Options for this printer instance.
2040
+ * All available content type entries for this request body.
2041
+ *
2042
+ * When the adapter `contentType` option is set, this array contains exactly one entry for
2043
+ * that content type. Otherwise it contains one entry per content type declared in the spec,
2044
+ * so that plugins can generate code for every variant (e.g. separate hooks for
2045
+ * `application/json` and `multipart/form-data`).
2887
2046
  */
2888
- options: TOptions;
2047
+ content?: Array<ContentNode>;
2048
+ };
2049
+ /**
2050
+ * Loosely-typed request body accepted by `createOperation`, normalized into a {@link RequestBodyNode}.
2051
+ */
2052
+ type UserRequestBody = Omit<RequestBodyNode, 'kind' | 'content'> & {
2053
+ content?: Array<UserContent>;
2889
2054
  };
2890
2055
  /**
2891
- * Handler for one schema node type.
2056
+ * Definition for the {@link RequestBodyNode}, normalizing each content entry into a `ContentNode`.
2057
+ */
2058
+ declare const requestBodyDef: NodeDef<RequestBodyNode, UserRequestBody>;
2059
+ /**
2060
+ * Creates a `RequestBodyNode`, normalizing each content entry into a `ContentNode`.
2061
+ */
2062
+ declare const createRequestBody: (input: UserRequestBody) => RequestBodyNode;
2063
+ //#endregion
2064
+ //#region src/nodes/http.d.ts
2065
+ /**
2066
+ * All supported HTTP status code literals as strings, as used in API specs
2067
+ * (for example, `"200"` and `"404"`).
2068
+ */
2069
+ type HttpStatusCode = '100' | '101' | '102' | '103' | '200' | '201' | '202' | '203' | '204' | '205' | '206' | '207' | '208' | '226' | '300' | '301' | '302' | '303' | '304' | '305' | '307' | '308' | '400' | '401' | '402' | '403' | '404' | '405' | '406' | '407' | '408' | '409' | '410' | '411' | '412' | '413' | '414' | '415' | '416' | '417' | '418' | '421' | '422' | '423' | '424' | '425' | '426' | '428' | '429' | '431' | '451' | '500' | '501' | '502' | '503' | '504' | '505' | '506' | '507' | '508' | '510' | '511';
2070
+ /**
2071
+ * Response status code literal used by operations.
2892
2072
  *
2893
- * Use a regular function (not an arrow function) if you need `this`.
2073
+ * Includes specific HTTP status code strings and `"default"` for catch-all responses.
2894
2074
  *
2895
2075
  * @example
2896
2076
  * ```ts
2897
- * const handler: PrinterHandler<string, {}, 'string'> = function () {
2898
- * return 'string'
2899
- * }
2077
+ * const status: StatusCode = '200'
2078
+ * const fallback: StatusCode = 'default'
2900
2079
  * ```
2901
2080
  */
2902
- type PrinterHandler<TOutput, TOptions extends object, T extends SchemaType = SchemaType> = (this: PrinterHandlerContext<TOutput, TOptions>, node: SchemaNodeByType[T]) => TOutput | null;
2081
+ type StatusCode = HttpStatusCode | 'default';
2082
+ //#endregion
2083
+ //#region src/nodes/response.d.ts
2903
2084
  /**
2904
- * Partial map of per-node-type handler overrides for a printer.
2085
+ * AST node representing one operation response variant.
2905
2086
  *
2906
- * Each key is a `SchemaType` string (e.g. `'date'`, `'string'`).
2907
- * Supply only the handlers you want to replace. The printer's built-in
2908
- * defaults fill in the rest.
2087
+ * Mirrors {@link OperationNode.requestBody}: the response body schemas live exclusively inside
2088
+ * the `content` array (one entry per content type), so the same schema is never duplicated at the
2089
+ * node root and inside `content`.
2909
2090
  *
2910
2091
  * @example
2911
2092
  * ```ts
2912
- * pluginZod({
2913
- * printer: {
2914
- * nodes: {
2915
- * date(): string {
2916
- * return 'z.string().date()'
2917
- * },
2918
- * } satisfies PrinterPartial<string, PrinterZodOptions>,
2919
- * },
2920
- * })
2093
+ * const response: ResponseNode = {
2094
+ * kind: 'Response',
2095
+ * statusCode: '200',
2096
+ * content: [{ contentType: 'application/json', schema: createSchema({ type: 'string' }) }],
2097
+ * }
2921
2098
  * ```
2922
2099
  */
2923
- type PrinterPartial<TOutput, TOptions extends object> = Partial<{ [K in SchemaType]: PrinterHandler<TOutput, TOptions, K> }>;
2100
+ type ResponseNode = BaseNode & {
2101
+ /**
2102
+ * Node kind.
2103
+ */
2104
+ kind: 'Response';
2105
+ /**
2106
+ * HTTP status code or `'default'` for a fallback response.
2107
+ */
2108
+ statusCode: StatusCode;
2109
+ /**
2110
+ * Optional response description.
2111
+ */
2112
+ description?: string;
2113
+ /**
2114
+ * All available content type entries for this response.
2115
+ *
2116
+ * When the adapter `contentType` option is set, this array contains exactly one entry for that
2117
+ * content type. Otherwise it contains one entry per content type declared in the spec, so that
2118
+ * plugins can generate a union of response types (e.g. `application/json` and `application/xml`).
2119
+ * Body-less responses keep a single entry whose `schema` is the empty/`void` placeholder.
2120
+ *
2121
+ * @example
2122
+ * ```ts
2123
+ * // spec response declares both application/json and application/xml
2124
+ * response.content[0].contentType // 'application/json'
2125
+ * response.content[1].contentType // 'application/xml'
2126
+ * ```
2127
+ */
2128
+ content?: Array<ContentNode>;
2129
+ };
2130
+ type ResponseInput = Pick<ResponseNode, 'statusCode'> & Partial<Omit<ResponseNode, 'kind' | 'statusCode' | 'content'>> & {
2131
+ content?: Array<UserContent>;
2132
+ schema?: SchemaNode;
2133
+ mediaType?: string | null;
2134
+ keysToOmit?: Array<string> | null;
2135
+ };
2136
+ /**
2137
+ * Definition for the {@link ResponseNode}. A single legacy `schema` (with optional
2138
+ * `mediaType`/`keysToOmit`) is normalized into one `content` entry.
2139
+ */
2140
+ declare const responseDef: NodeDef<ResponseNode, ResponseInput>;
2924
2141
  /**
2925
- * Generic shape used by `definePrinter`.
2926
- *
2927
- * - `TName` unique string identifier (e.g. `'zod'`, `'ts'`)
2928
- * - `TOptions` options passed to and stored on the printer instance
2929
- * - `TOutput` the type emitted by node handlers
2930
- * - `TPrintOutput` type returned by public `print` (defaults to `TOutput`)
2142
+ * Creates a `ResponseNode`.
2931
2143
  *
2932
2144
  * @example
2933
2145
  * ```ts
2934
- * type MyPrinter = PrinterFactoryOptions<'my', { strict: boolean }, string>
2146
+ * const response = createResponse({
2147
+ * statusCode: '200',
2148
+ * content: [{ contentType: 'application/json', schema: createSchema({ type: 'object', properties: [] }) }],
2149
+ * })
2935
2150
  * ```
2936
2151
  */
2937
- type PrinterFactoryOptions<TName extends string = string, TOptions extends object = object, TOutput = unknown, TPrintOutput = TOutput> = {
2938
- name: TName;
2939
- options: TOptions;
2940
- output: TOutput;
2941
- printOutput: TPrintOutput;
2152
+ declare const createResponse: (input: ResponseInput) => ResponseNode;
2153
+ //#endregion
2154
+ //#region src/nodes/operation.d.ts
2155
+ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'TRACE';
2156
+ /**
2157
+ * Transport an operation belongs to.
2158
+ */
2159
+ type OperationProtocol = 'http';
2160
+ /**
2161
+ * Fields shared by every operation, regardless of transport.
2162
+ */
2163
+ type OperationNodeBase = BaseNode & {
2164
+ /**
2165
+ * Node kind.
2166
+ */
2167
+ kind: 'Operation';
2168
+ /**
2169
+ * Operation identifier, usually from OpenAPI `operationId`.
2170
+ */
2171
+ operationId: string;
2172
+ /**
2173
+ * Group labels for the operation.
2174
+ * Usually copied from OpenAPI `tags`.
2175
+ */
2176
+ tags: Array<string>;
2177
+ /**
2178
+ * Short one-line operation summary.
2179
+ */
2180
+ summary?: string;
2181
+ /**
2182
+ * Full operation description.
2183
+ */
2184
+ description?: string;
2185
+ /**
2186
+ * Marks the operation as deprecated.
2187
+ */
2188
+ deprecated?: boolean;
2189
+ /**
2190
+ * Parameters that could be used, we have QueryParams, PathParams, HeaderParams and CookieParams
2191
+ */
2192
+ parameters: Array<ParameterNode>;
2193
+ /**
2194
+ * Request body for the operation.
2195
+ */
2196
+ requestBody?: RequestBodyNode;
2197
+ /**
2198
+ * Operation responses.
2199
+ */
2200
+ responses: Array<ResponseNode>;
2942
2201
  };
2943
2202
  /**
2944
- * Printer instance returned by a printer factory.
2203
+ * Operation served over HTTP/REST (OpenAPI). `method` and `path` are guaranteed.
2945
2204
  *
2946
2205
  * @example
2947
2206
  * ```ts
2948
- * const printer = definePrinter((options: {}) => ({ name: 'x', options, nodes: {} }))({})
2207
+ * const operation: HttpOperationNode = {
2208
+ * kind: 'Operation',
2209
+ * operationId: 'listPets',
2210
+ * protocol: 'http',
2211
+ * method: 'GET',
2212
+ * path: '/pets',
2213
+ * tags: [],
2214
+ * parameters: [],
2215
+ * responses: [],
2216
+ * }
2949
2217
  * ```
2950
2218
  */
2951
- type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {
2952
- /**
2953
- * Unique identifier supplied at creation time.
2954
- */
2955
- name: T['name'];
2219
+ type HttpOperationNode = OperationNodeBase & {
2956
2220
  /**
2957
- * Options for this printer instance.
2221
+ * Transport the operation belongs to.
2958
2222
  */
2959
- options: T['options'];
2223
+ protocol?: 'http';
2960
2224
  /**
2961
- * Node-level dispatcher, converts a `SchemaNode` directly to `TOutput` using the `nodes` handlers.
2962
- * Always dispatches through the `nodes` map. Never calls the `print` override.
2963
- * Use this when you need the raw output (e.g. `ts.TypeNode`) without declaration wrapping.
2225
+ * HTTP method like `'GET'`.
2964
2226
  */
2965
- transform: (node: SchemaNode) => T['output'] | null;
2227
+ method: HttpMethod;
2966
2228
  /**
2967
- * Public printer. If the builder provides a root-level `print`, this calls that
2968
- * higher-level function (which may produce full declarations).
2969
- * Otherwise, falls back to the node-level dispatcher.
2229
+ * OpenAPI-style path string, for example `/pets/{petId}`, with `{param}` notation preserved.
2970
2230
  */
2971
- print: (node: SchemaNode) => T['printOutput'] | null;
2231
+ path: string;
2972
2232
  };
2973
2233
  /**
2974
- * Builder function passed to `definePrinter`.
2975
- *
2976
- * It receives resolved options and returns:
2977
- * - `name`
2978
- * - `options`
2979
- * - `nodes` handlers
2980
- * - optional top-level `print` override
2981
- *
2982
- * @example
2983
- * ```ts
2984
- * const build = (options: {}) => ({ name: 'x' as const, options, nodes: {} })
2985
- * ```
2234
+ * Operation for a non-HTTP transport. HTTP-only fields are forbidden.
2986
2235
  */
2987
- type PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) => {
2988
- name: T['name'];
2989
- /**
2990
- * Options to store on the printer.
2991
- */
2992
- options: T['options'];
2993
- nodes: Partial<{ [K in SchemaType]: PrinterHandler<T['output'], T['options'], K> }>;
2236
+ type GenericOperationNode = OperationNodeBase & {
2994
2237
  /**
2995
- * Optional root-level print override. When provided, becomes the public `printer.print`.
2996
- * Use `this.transform(node)` inside this function to dispatch to the node-level handlers (`nodes`),
2997
- * not the override itself, so recursion is safe.
2238
+ * Transport the operation belongs to.
2998
2239
  */
2999
- print?: (this: PrinterHandlerContext<T['output'], T['options']>, node: SchemaNode) => T['printOutput'] | null;
2240
+ protocol?: Exclude<OperationProtocol, 'http'>;
2241
+ method?: never;
2242
+ path?: never;
3000
2243
  };
3001
2244
  /**
3002
- * Defines a schema printer: a function that takes a `SchemaNode` and emits
3003
- * code in your target language. Each plugin that produces code from schemas
3004
- * (TypeScript types, Zod schemas, Faker factories) ships a printer built
3005
- * with this helper.
3006
- *
3007
- * The builder receives resolved options and returns:
3008
- *
3009
- * - `name` unique identifier for the printer.
3010
- * - `options` stored on the returned printer instance.
3011
- * - `nodes` map of `SchemaType` → handler. Handlers return the rendered
3012
- * output (a string, a TypeScript AST node, ...) for that schema type.
3013
- * - `print` (optional), top-level override exposed as `printer.print`.
3014
- * Use `this.transform(node)` inside it to dispatch to `nodes` recursively.
3015
- *
3016
- * Without a `print` override, `printer.print` falls back to `printer.transform`
3017
- * (the node-level dispatcher).
3018
- *
3019
- * @example Tiny Zod printer
3020
- * ```ts
3021
- * import { definePrinter, type PrinterFactoryOptions } from '@kubb/ast'
3022
- *
3023
- * type PrinterZod = PrinterFactoryOptions<'zod', { strict?: boolean }, string>
2245
+ * AST node representing one API operation.
3024
2246
  *
3025
- * export const zodPrinter = definePrinter<PrinterZod>((options) => ({
3026
- * name: 'zod',
3027
- * options: { strict: options.strict ?? true },
3028
- * nodes: {
3029
- * string: () => 'z.string()',
3030
- * object(node) {
3031
- * const props = node.properties
3032
- * .map((p) => `${p.name}: ${this.transform(p.schema)}`)
3033
- * .join(', ')
3034
- * return `z.object({ ${props} })`
3035
- * },
3036
- * },
3037
- * }))
3038
- * ```
2247
+ * Discriminated on `protocol`: an {@link HttpOperationNode} (`protocol: 'http'`) guarantees
2248
+ * `method` and `path`, while a {@link GenericOperationNode} omits them. Narrow with
2249
+ * `isHttpOperationNode(node)` or `node.protocol === 'http'` before reading `method`/`path`.
3039
2250
  */
3040
- declare function definePrinter<T extends PrinterFactoryOptions = PrinterFactoryOptions>(build: PrinterBuilder<T>): (options?: T['options']) => Printer<T>;
3041
- /**
3042
- * Generic printer-factory function used by `definePrinter` and `defineFunctionPrinter`.
3043
- **
3044
- * @example
3045
- * ```ts
3046
- * export const defineFunctionPrinter = createPrinterFactory<FunctionNode, FunctionNodeType, FunctionNodeByType>(
3047
- * (node) => kindToHandlerKey[node.kind],
3048
- * )
3049
- * ```
3050
- */
3051
- 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"]) => {
3052
- name: T["name"];
3053
- options: T["options"];
3054
- nodes: Partial<{ [K in TKey]: (this: {
3055
- transform: (node: TNode) => T["output"] | null;
3056
- options: T["options"];
3057
- }, node: TNodeByKey[K]) => T["output"] | null }>;
3058
- print?: (this: {
3059
- transform: (node: TNode) => T["output"] | null;
3060
- options: T["options"];
3061
- }, node: TNode) => T["printOutput"] | null;
3062
- }) => (options?: T["options"]) => {
3063
- name: T["name"];
3064
- options: T["options"];
3065
- transform: (node: TNode) => T["output"] | null;
3066
- print: (node: TNode) => T["printOutput"] | null;
2251
+ type OperationNode = HttpOperationNode | GenericOperationNode;
2252
+ type OperationInput = {
2253
+ operationId: string;
2254
+ method?: HttpOperationNode['method'];
2255
+ path?: HttpOperationNode['path'];
2256
+ requestBody?: UserRequestBody;
2257
+ [key: string]: unknown;
3067
2258
  };
3068
- //#endregion
3069
- //#region src/visitor.d.ts
3070
2259
  /**
3071
- * Ordered mapping of `[NodeType, ParentType]` pairs.
3072
- *
3073
- * `ParentOf` uses this map to find parent types.
2260
+ * Definition for the {@link OperationNode}. HTTP operations (those carrying both
2261
+ * `method` and `path`) are tagged with `protocol: 'http'`, and the request body is
2262
+ * normalized into a `RequestBodyNode`.
3074
2263
  */
3075
- 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]];
2264
+ declare const operationDef: NodeDef<OperationNode, OperationInput>;
3076
2265
  /**
3077
- * Resolves the parent node type for a given AST node type.
3078
- *
3079
- * This is used by visitor context so `ctx.parent` is correctly typed
3080
- * for each callback.
3081
- *
3082
- * @example
3083
- * ```ts
3084
- * type InputParent = ParentOf<InputNode>
3085
- * // undefined
3086
- * ```
3087
- *
3088
- * @example
3089
- * ```ts
3090
- * type PropertyParent = ParentOf<PropertyNode>
3091
- * // SchemaNode
3092
- * ```
2266
+ * Creates an `OperationNode` with default empty arrays for `tags`, `parameters`, and `responses`.
3093
2267
  *
3094
2268
  * @example
3095
2269
  * ```ts
3096
- * type SchemaParent = ParentOf<SchemaNode>
3097
- * // InputNode | OperationNode | SchemaNode | PropertyNode | ParameterNode | ResponseNode
2270
+ * const operation = createOperation({ operationId: 'getPetById', method: 'GET', path: '/pet/{petId}' })
2271
+ * // tags, parameters, and responses are []
3098
2272
  * ```
3099
2273
  */
3100
- type ParentOf<T extends Node, TEntries extends ReadonlyArray<[Node, unknown]> = ParentNodeMap> = TEntries extends [infer TEntry extends [Node, unknown], ...infer TRest extends ReadonlyArray<[Node, unknown]>] ? T extends TEntry[0] ? TEntry[1] : ParentOf<T, TRest> : Node;
2274
+ declare function createOperation(props: Pick<HttpOperationNode, 'operationId' | 'method' | 'path'> & Partial<Omit<HttpOperationNode, 'kind' | 'operationId' | 'method' | 'path' | 'requestBody'>> & {
2275
+ requestBody?: UserRequestBody;
2276
+ }): HttpOperationNode;
2277
+ declare function createOperation(props: Pick<GenericOperationNode, 'operationId'> & Partial<Omit<GenericOperationNode, 'kind' | 'operationId' | 'requestBody'>> & {
2278
+ requestBody?: UserRequestBody;
2279
+ }): GenericOperationNode;
2280
+ //#endregion
2281
+ //#region src/nodes/input.d.ts
3101
2282
  /**
3102
- * Traversal context passed as the second argument to every visitor callback.
3103
- * `parent` is typed from the current node type.
2283
+ * Metadata for an API document, populated by the adapter and available to every generator.
2284
+ *
2285
+ * All fields are plain JSON-serializable values, no `Set`, no `Map`, no class instances.
2286
+ * Computed fields (`circularNames`, `enumNames`) are pre-calculated once during the adapter
2287
+ * pre-scan so generators never need to iterate the full schema list themselves.
3104
2288
  *
3105
2289
  * @example
3106
2290
  * ```ts
3107
- * const visitor: Visitor = {
3108
- * schema(node, { parent }) {
3109
- * // parent type is narrowed by node kind
3110
- * },
3111
- * }
2291
+ * const meta: InputMeta = { title: 'Pet Store', version: '1.0.0', baseURL: 'https://petstore.swagger.io/v2', circularNames: [], enumNames: [] }
3112
2292
  * ```
3113
2293
  */
3114
- type VisitorContext<T extends Node = Node> = {
2294
+ type InputMeta = {
2295
+ /**
2296
+ * API title from `info.title` in the source document.
2297
+ */
2298
+ title?: string;
2299
+ /**
2300
+ * API description from `info.description` in the source document.
2301
+ */
2302
+ description?: string;
2303
+ /**
2304
+ * API version string from `info.version` in the source document.
2305
+ */
2306
+ version?: string;
2307
+ /**
2308
+ * Resolved base URL from the first matching server entry in the source document.
2309
+ */
2310
+ baseURL?: string | null;
2311
+ /**
2312
+ * Names of schemas that participate in a circular reference chain.
2313
+ * Computed once during the adapter pre-scan, use this instead of calling
2314
+ * `findCircularSchemas` per generator call.
2315
+ *
2316
+ * Convert to a `Set` once at the start of a generator, not per-schema,
2317
+ * to keep lookup O(1) without repeated allocations.
2318
+ *
2319
+ * @example Wrap a circular schema in z.lazy()
2320
+ * ```ts
2321
+ * const circular = new Set(meta.circularNames)
2322
+ * if (circular.has(schema.name)) { ... }
2323
+ * ```
2324
+ */
2325
+ circularNames: ReadonlyArray<string>;
3115
2326
  /**
3116
- * Parent node of the currently visited node.
3117
- * For `InputNode`, this is `undefined`.
2327
+ * Names of schemas whose type is `enum`.
2328
+ * Computed once during the adapter pre-scan, use this instead of filtering
2329
+ * schemas per generator call.
2330
+ *
2331
+ * Convert to a `Set` once at the start of a generator when you need repeated
2332
+ * membership checks, rather than calling `.includes()` per schema.
2333
+ *
2334
+ * @example Check if a referenced schema is an enum
2335
+ * `const enums = new Set(meta.enumNames)`
2336
+ * `const isEnum = enums.has(schemaName)`
3118
2337
  */
3119
- parent?: ParentOf<T>;
2338
+ enumNames: ReadonlyArray<string>;
3120
2339
  };
3121
2340
  /**
3122
- * Synchronous visitor consumed by `transform`. Each optional callback runs
3123
- * for the matching node type. Return a new node to replace it, or `undefined`
3124
- * to leave it untouched.
2341
+ * Input AST node that contains all schemas and operations for one API document.
2342
+ * Produced by the adapter and consumed by all Kubb plugins.
3125
2343
  *
3126
- * Plugins typically expose `transformer` so users can supply a `Visitor` that
3127
- * rewrites operation IDs, drops descriptions, or otherwise tweaks the AST
3128
- * before printing.
2344
+ * `Stream` switches `schemas` and `operations` between eager `Array`s (the default) and lazy
2345
+ * `AsyncIterable`s. The streaming variant `InputNode<true>` yields nodes one at a time and makes
2346
+ * `meta` optional, since the adapter can emit metadata before the first node is parsed.
3129
2347
  *
3130
- * @example Prefix every operationId
2348
+ * @example
3131
2349
  * ```ts
3132
- * const visitor: Visitor = {
3133
- * operation(node) {
3134
- * return { ...node, operationId: `api_${node.operationId}` }
3135
- * },
2350
+ * const input: InputNode = {
2351
+ * kind: 'Input',
2352
+ * schemas: [],
2353
+ * operations: [],
2354
+ * meta: { circularNames: [], enumNames: [] },
3136
2355
  * }
3137
2356
  * ```
3138
2357
  *
3139
- * @example Strip schema descriptions
2358
+ * @example Streaming variant for large specs
3140
2359
  * ```ts
3141
- * const visitor: Visitor = {
3142
- * schema(node) {
3143
- * return { ...node, description: undefined }
3144
- * },
2360
+ * for await (const schema of inputNode.schemas) {
2361
+ * // only this one SchemaNode is live here. Previous ones are GC-eligible
3145
2362
  * }
3146
2363
  * ```
3147
2364
  */
3148
- type Visitor = {
3149
- input?(node: InputNode, context: VisitorContext<InputNode>): undefined | null | InputNode;
3150
- output?(node: OutputNode, context: VisitorContext<OutputNode>): undefined | null | OutputNode;
3151
- operation?(node: OperationNode, context: VisitorContext<OperationNode>): undefined | null | OperationNode;
3152
- schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): undefined | null | SchemaNode;
3153
- property?(node: PropertyNode, context: VisitorContext<PropertyNode>): undefined | null | PropertyNode;
3154
- parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): undefined | null | ParameterNode;
3155
- response?(node: ResponseNode, context: VisitorContext<ResponseNode>): undefined | null | ResponseNode;
3156
- };
2365
+ type InputNode<Stream extends boolean = false> = BaseNode & {
2366
+ /**
2367
+ * Node kind.
2368
+ */
2369
+ kind: 'Input';
2370
+ /**
2371
+ * All schema nodes in the document.
2372
+ */
2373
+ schemas: Streamable<SchemaNode, Stream>;
2374
+ /**
2375
+ * All operation nodes in the document.
2376
+ */
2377
+ operations: Streamable<OperationNode, Stream>;
2378
+ } & (Stream extends true ? {
2379
+ meta?: InputMeta;
2380
+ } : {
2381
+ meta: InputMeta;
2382
+ });
3157
2383
  /**
3158
- * Utility type for values that can be returned directly or asynchronously.
2384
+ * Definition for the {@link InputNode}.
3159
2385
  */
3160
- type MaybePromise<T> = T | Promise<T>;
2386
+ declare const inputDef: NodeDef<InputNode<false>, Partial<Omit<InputNode<false>, "kind">>>;
3161
2387
  /**
3162
- * Async visitor for `walk`. Synchronous `Visitor` objects are compatible.
2388
+ * Creates an `InputNode`. Pass `stream: true` for the streaming variant whose `schemas` and
2389
+ * `operations` are `AsyncIterable` sources and whose `meta` is optional. Otherwise it builds the
2390
+ * eager variant with array `schemas`/`operations` and the defaulted `meta`.
3163
2391
  *
3164
- * @example
2392
+ * @example Eager
3165
2393
  * ```ts
3166
- * const visitor: AsyncVisitor = {
3167
- * async operation(node) {
3168
- * await Promise.resolve(node.operationId)
3169
- * },
3170
- * }
2394
+ * const input = createInput()
2395
+ * // { kind: 'Input', schemas: [], operations: [] }
3171
2396
  * ```
3172
- */
3173
- type AsyncVisitor = {
3174
- input?(node: InputNode, context: VisitorContext<InputNode>): MaybePromise<undefined | null | InputNode>;
3175
- output?(node: OutputNode, context: VisitorContext<OutputNode>): MaybePromise<undefined | null | OutputNode>;
3176
- operation?(node: OperationNode, context: VisitorContext<OperationNode>): MaybePromise<undefined | null | OperationNode>;
3177
- schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): MaybePromise<undefined | null | SchemaNode>;
3178
- property?(node: PropertyNode, context: VisitorContext<PropertyNode>): MaybePromise<undefined | null | PropertyNode>;
3179
- parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): MaybePromise<undefined | null | ParameterNode>;
3180
- response?(node: ResponseNode, context: VisitorContext<ResponseNode>): MaybePromise<undefined | null | ResponseNode>;
3181
- };
3182
- /**
3183
- * Visitor used by `collect`.
3184
2397
  *
3185
- * @example
2398
+ * @example Streaming
3186
2399
  * ```ts
3187
- * const visitor: CollectVisitor<string> = {
3188
- * operation(node) {
3189
- * return node.operationId
3190
- * },
3191
- * }
2400
+ * const node = createInput({ stream: true, schemas: schemasIterable, operations: operationsIterable, meta: { title: 'My API' } })
3192
2401
  * ```
3193
2402
  */
3194
- type CollectVisitor<T> = {
3195
- input?(node: InputNode, context: VisitorContext<InputNode>): T | null | undefined;
3196
- output?(node: OutputNode, context: VisitorContext<OutputNode>): T | null | undefined;
3197
- operation?(node: OperationNode, context: VisitorContext<OperationNode>): T | null | undefined;
3198
- schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): T | null | undefined;
3199
- property?(node: PropertyNode, context: VisitorContext<PropertyNode>): T | null | undefined;
3200
- parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): T | null | undefined;
3201
- response?(node: ResponseNode, context: VisitorContext<ResponseNode>): T | null | undefined;
3202
- };
2403
+ declare function createInput<Stream extends boolean = false>(options?: Partial<Omit<InputNode<Stream>, 'kind'>> & {
2404
+ stream?: Stream;
2405
+ }): InputNode<Stream>;
2406
+ //#endregion
2407
+ //#region src/nodes/output.d.ts
3203
2408
  /**
3204
- * Options for `transform`.
2409
+ * Output AST node that groups all generated file output for one API document.
3205
2410
  *
3206
- * @example
3207
- * ```ts
3208
- * const options: TransformOptions = { depth: 'deep', schema: (node) => node }
3209
- * ```
2411
+ * Produced by generators and consumed by the build pipeline to write files.
3210
2412
  *
3211
2413
  * @example
3212
2414
  * ```ts
3213
- * // Only transform the current node, not nested children
3214
- * const options: TransformOptions = { depth: 'shallow', schema: (node) => node }
2415
+ * const output: OutputNode = {
2416
+ * kind: 'Output',
2417
+ * files: [],
2418
+ * }
3215
2419
  * ```
3216
2420
  */
3217
- type TransformOptions = Visitor & {
2421
+ type OutputNode = BaseNode & {
3218
2422
  /**
3219
- * Traversal depth (`'deep'` by default).
3220
- * @default 'deep'
2423
+ * Node kind.
3221
2424
  */
3222
- depth?: VisitorDepth;
2425
+ kind: 'Output';
3223
2426
  /**
3224
- * Internal parent override used during recursion.
2427
+ * Generated file nodes.
3225
2428
  */
3226
- parent?: Node;
2429
+ files: Array<FileNode>;
3227
2430
  };
3228
2431
  /**
3229
- * Options for `walk`.
3230
- *
3231
- * @example
3232
- * ```ts
3233
- * const options: WalkOptions = { depth: 'deep', concurrency: 10, root: () => {} }
3234
- * ```
2432
+ * Definition for the {@link OutputNode}.
3235
2433
  */
3236
- type WalkOptions = AsyncVisitor & {
3237
- /**
3238
- * Traversal depth (`'deep'` by default).
3239
- * @default 'deep'
3240
- */
3241
- depth?: VisitorDepth;
3242
- /**
3243
- * Maximum number of sibling nodes visited concurrently.
3244
- * @default 30
3245
- */
3246
- concurrency?: number;
3247
- };
2434
+ declare const outputDef: NodeDef<OutputNode, Partial<Omit<OutputNode, "kind">>>;
3248
2435
  /**
3249
- * Options for `collect`.
2436
+ * Creates an `OutputNode` with a stable default for `files`.
3250
2437
  *
3251
2438
  * @example
3252
2439
  * ```ts
3253
- * const options: CollectOptions<string> = { depth: 'shallow', schema: () => undefined }
3254
- * ```
3255
- */
3256
- type CollectOptions<T> = CollectVisitor<T> & {
3257
- /**
3258
- * Traversal depth (`'deep'` by default).
3259
- * @default 'deep'
3260
- */
3261
- depth?: VisitorDepth;
3262
- /**
3263
- * Internal parent override used during recursion.
3264
- */
3265
- parent?: Node;
3266
- };
3267
- /**
3268
- * Async depth-first traversal for side effects. Visitor return values are
3269
- * ignored. Use `transform` when you want to rewrite nodes.
3270
- *
3271
- * Sibling nodes at each depth run concurrently up to `options.concurrency`
3272
- * (defaults to `WALK_CONCURRENCY`). Higher values overlap I/O-bound visitor
3273
- * work. Lower values reduce memory pressure.
3274
- *
3275
- * @example Log every operation
3276
- * ```ts
3277
- * await walk(root, {
3278
- * operation(node) {
3279
- * console.log(node.operationId)
3280
- * },
3281
- * })
3282
- * ```
3283
- *
3284
- * @example Only visit the root node
3285
- * ```ts
3286
- * await walk(root, { depth: 'shallow', input: () => {} })
2440
+ * const output = createOutput()
2441
+ * // { kind: 'Output', files: [] }
3287
2442
  * ```
3288
2443
  */
3289
- declare function walk(node: Node, options: WalkOptions): Promise<void>;
2444
+ declare function createOutput(overrides?: Partial<Omit<OutputNode, 'kind'>>): OutputNode;
2445
+ //#endregion
2446
+ //#region src/nodes/index.d.ts
3290
2447
  /**
3291
- * Synchronous depth-first transform. Each visitor callback gets a chance to
3292
- * return a replacement node; `undefined` keeps the original.
3293
- *
3294
- * The transform is immutable. The original tree is not mutated. A new tree
3295
- * is returned. Use `depth: 'shallow'` to skip recursion into children.
3296
- *
3297
- * @example Prefix every operationId
3298
- * ```ts
3299
- * const next = transform(root, {
3300
- * operation(node) {
3301
- * return { ...node, operationId: `prefixed_${node.operationId}` }
3302
- * },
3303
- * })
3304
- * ```
2448
+ * Union of all AST node types.
3305
2449
  *
3306
- * @example Replace only the root node
3307
- * ```ts
3308
- * const next = transform(root, {
3309
- * depth: 'shallow',
3310
- * input: (node) => ({ ...node, meta: { ...node.meta, title: 'Rewritten' } }),
3311
- * })
3312
- * ```
3313
- */
3314
- declare function transform(node: InputNode, options: TransformOptions): InputNode;
3315
- declare function transform(node: OutputNode, options: TransformOptions): OutputNode;
3316
- declare function transform(node: OperationNode, options: TransformOptions): OperationNode;
3317
- declare function transform(node: SchemaNode, options: TransformOptions): SchemaNode;
3318
- declare function transform(node: PropertyNode, options: TransformOptions): PropertyNode;
3319
- declare function transform(node: ParameterNode, options: TransformOptions): ParameterNode;
3320
- declare function transform(node: ResponseNode, options: TransformOptions): ResponseNode;
3321
- declare function transform(node: Node, options: TransformOptions): Node;
3322
- /**
3323
- * Eager depth-first collection pass. Returns an array of every non-null value
3324
- * the visitor callbacks return.
2450
+ * This lets TypeScript narrow types in `switch (node.kind)` blocks.
3325
2451
  *
3326
- * @example Collect every operationId
2452
+ * @example
3327
2453
  * ```ts
3328
- * const ids = collect<string>(root, {
3329
- * operation(node) {
3330
- * return node.operationId
3331
- * },
3332
- * })
2454
+ * function getKind(node: Node): string {
2455
+ * switch (node.kind) {
2456
+ * case 'Input':
2457
+ * return 'input'
2458
+ * case 'Output':
2459
+ * return 'output'
2460
+ * default:
2461
+ * return 'other'
2462
+ * }
2463
+ * }
3333
2464
  * ```
3334
2465
  */
3335
- declare function collect<T>(node: Node, options: CollectOptions<T>): Array<T>;
2466
+ type Node = InputNode | OutputNode | OperationNode | SchemaNode | PropertyNode | ParameterNode | ResponseNode | RequestBodyNode | ContentNode | FunctionParamNode | FileNode | ImportNode | ExportNode | SourceNode | ConstNode | TypeNode | FunctionNode | ArrowFunctionNode;
3336
2467
  //#endregion
3337
2468
  //#region src/utils/ast.d.ts
3338
2469
  /**
@@ -3373,6 +2504,19 @@ declare function createDiscriminantNode({
3373
2504
  propertyName: string;
3374
2505
  value: string;
3375
2506
  }): SchemaNode;
2507
+ /**
2508
+ * Named type for a group of parameters (query or header) emitted as a single typed parameter.
2509
+ */
2510
+ type ParamGroupType = {
2511
+ /**
2512
+ * Type expression for the group, a plain group-name reference.
2513
+ */
2514
+ type: TypeExpression;
2515
+ /**
2516
+ * Whether the parameter group is optional.
2517
+ */
2518
+ optional: boolean;
2519
+ };
3376
2520
  /**
3377
2521
  * Resolver interface for {@link createOperationParams}.
3378
2522
  *
@@ -3458,7 +2602,7 @@ type CreateOperationParamsOptions = {
3458
2602
  * extraParams: [createFunctionParameter({ name: 'options', type: 'Partial<RequestOptions>', default: '{}' })]
3459
2603
  * ```
3460
2604
  */
3461
- extraParams?: Array<FunctionParameterNode | ParameterGroupNode>;
2605
+ extraParams?: Array<FunctionParameterNode>;
3462
2606
  /**
3463
2607
  * Override the default parameter names used for body, query, header, and rest-path groups.
3464
2608
  *
@@ -3497,22 +2641,65 @@ type CreateOperationParamsOptions = {
3497
2641
  */
3498
2642
  typeWrapper?: (type: string) => string;
3499
2643
  };
2644
+ /**
2645
+ * Resolves the {@link TypeExpression} for an individual parameter.
2646
+ *
2647
+ * Without a resolver, falls back to the schema primitive (a plain type-name string).
2648
+ * When the parameter belongs to a named group, emits an {@link IndexedAccessTypeNode}
2649
+ * (`GroupParams['petId']`); otherwise the resolved individual name as a plain string.
2650
+ */
2651
+ declare function resolveParamType({
2652
+ node,
2653
+ param,
2654
+ resolver
2655
+ }: {
2656
+ node: OperationNode;
2657
+ param: ParameterNode;
2658
+ resolver: OperationParamsResolver | undefined;
2659
+ }): TypeExpression;
3500
2660
  /**
3501
2661
  * Converts an `OperationNode` into function parameters for code generation.
3502
2662
  *
3503
- * Centralizes parameter grouping logic for all plugins. Provide a `resolver` for type name resolution
3504
- * and `extraParams` for plugin-specific trailing parameters (e.g., `options` objects).
3505
- * Supports three grouping modes: `object` (single destructured param), `inline` (separate params),
3506
- * and `inlineSpread` (rest parameter). Use `CreateOperationParamsOptions` to fine-tune output.
2663
+ * Centralizes parameter grouping logic for all plugins. `paramsType` chooses between one
2664
+ * destructured object parameter (`object`) and separate top-level parameters (`inline`), while
2665
+ * `pathParamsType` controls how path params render in inline mode. Provide a `resolver` for type
2666
+ * name resolution and `extraParams` for plugin-specific trailing parameters such as an `options` object.
3507
2667
  */
3508
2668
  declare function createOperationParams(node: OperationNode, options: CreateOperationParamsOptions): FunctionParametersNode;
3509
2669
  /**
3510
- * Extracts all string content from a `CodeNode` tree recursively.
2670
+ * Shared arguments for building a query or header parameter group.
2671
+ */
2672
+ type BuildGroupArgs = {
2673
+ name: string;
2674
+ node: OperationNode;
2675
+ params: Array<ParameterNode>;
2676
+ groupType: ParamGroupType | null;
2677
+ resolver: OperationParamsResolver | undefined;
2678
+ wrapType: (type: string) => string;
2679
+ };
2680
+ /**
2681
+ * Builds a single {@link FunctionParameterNode} for a query or header group.
2682
+ * Returns an empty array when there are no params to emit.
3511
2683
  *
3512
- * Collects text node values, identifier references in string fields (`params`, `generics`, `returnType`, `type`),
3513
- * and nested node content. Used internally to build the full source string for import filtering.
2684
+ * A pre-resolved `groupType` emits `name: GroupType`. Otherwise it builds an inline
2685
+ * {@link TypeLiteralNode} from the individual params.
3514
2686
  */
3515
- declare function extractStringsFromNodes(nodes: Array<CodeNode> | undefined): string;
2687
+ declare function buildGroupParam(args: BuildGroupArgs): Array<FunctionParameterNode>;
2688
+ /**
2689
+ * Builds a {@link TypeLiteralNode} for an inline anonymous type grouping named fields.
2690
+ *
2691
+ * Used when query or header parameters have no dedicated group type name.
2692
+ * Each language printer renders this appropriately (TypeScript: `{ petId: string; name?: string }`).
2693
+ */
2694
+ declare function buildTypeLiteral({
2695
+ node,
2696
+ params,
2697
+ resolver
2698
+ }: {
2699
+ node: OperationNode;
2700
+ params: Array<ParameterNode>;
2701
+ resolver: OperationParamsResolver | undefined;
2702
+ }): TypeLiteralNode;
3516
2703
  declare function collectUsedSchemaNames(operations: ReadonlyArray<OperationNode>, schemas: ReadonlyArray<SchemaNode>): Set<string>;
3517
2704
  /**
3518
2705
  * Identifies all schemas that participate in circular dependency chains, including direct self-loops.
@@ -3540,5 +2727,5 @@ declare function containsCircularRef(node: SchemaNode | undefined, {
3540
2727
  excludeName?: string;
3541
2728
  }): boolean;
3542
2729
  //#endregion
3543
- export { DedupeCanonical as $, schemaTypes as $t, createFunctionParameter as A, NumberSchemaNode as At, createProperty as B, UnionSchemaNode as Bt, UserFileNode as C, ImportNode as Ct, createExport as D, DatetimeSchemaNode as Dt, createConst as E, DateSchemaNode as Et, createOperation as F, SchemaNode as Ft, createText as G, ConstNode as Gt, createSchema as H, PropertyNode as Ht, createOutput as I, SchemaNodeByType as It, update as J, JsxNode as Jt, createType as K, FunctionNode as Kt, createParameter as L, SchemaType as Lt, createImport as M, PrimitiveSchemaType as Mt, createInput as N, RefSchemaNode as Nt, createFile as O, EnumSchemaNode as Ot, createJsx as P, ScalarSchemaType as Pt, defineSchemaDialect as Q, httpMethods as Qt, createParameterGroup as R, StringSchemaNode as Rt, DistributiveOmit as S, FileNode as St, createBreak as T, ArraySchemaNode as Tt, createSource as U, ArrowFunctionNode as Ut, createResponse as V, UrlSchemaNode as Vt, createStreamInput as W, CodeNode as Wt, ParserOptions as X, TypeNode as Xt, InferSchemaNode as Y, TextNode as Yt, SchemaDialect as Z, NodeKind as Zt, Printer as _, FunctionParameterNode as _t, createDiscriminantNode as a, OutputNode as at, createPrinterFactory as b, ParamsTypeNode as bt, findCircularSchemas as c, HttpMethod as ct, ParentOf as d, ResponseNode as dt, DedupeLookups as et, Visitor as f, StatusCode as ft, walk as g, FunctionParamNode as gt, transform as h, FunctionNodeType as ht, containsCircularRef as i, Node as it, createFunctionParameters as j, ObjectSchemaNode as jt, createFunction as k, IntersectionSchemaNode as kt, isStringType as l, HttpOperationNode as lt, collect as m, ParameterNode as mt, caseParams as n, applyDedupe as nt, createOperationParams as o, InputMeta as ot, VisitorContext as p, ParameterLocation as pt, syncOptionality as q, JSDocNode as qt, collectUsedSchemaNames as r, buildDedupePlan as rt, extractStringsFromNodes as s, InputNode as st, OperationParamsResolver as t, DedupePlan as tt, syncSchemaRef as u, OperationNode as ut, PrinterFactoryOptions as v, FunctionParametersNode as vt, createArrowFunction as w, SourceNode as wt, definePrinter as x, ExportNode as xt, PrinterPartial as y, ParameterGroupNode as yt, createParamsType as z, TimeSchemaNode as zt };
3544
- //# sourceMappingURL=types-BL7RpQAE.d.ts.map
2730
+ export { functionParametersDef as $, createBreak as $t, responseDef as A, StringSchemaNode as At, FunctionParamNode as B, ParserOptions as Bt, HttpMethod as C, ObjectSchemaNode as Ct, operationDef as D, SchemaNode as Dt, createOperation as E, ScalarSchemaType as Et, ParameterLocation as F, schemaDef as Ft, TypeExpression as G, JSDocNode as Gt, FunctionParametersNode as H, CodeNode as Ht, ParameterNode as I, PropertyNode as It, createFunctionParameters as J, TypeNode as Jt, TypeLiteralNode as K, JsxNode as Kt, createParameter as L, createProperty as Lt, RequestBodyNode as M, UnionSchemaNode as Mt, createRequestBody as N, UrlSchemaNode as Nt, ResponseNode as O, SchemaNodeByType as Ot, requestBodyDef as P, createSchema as Pt, functionParameterDef as Q, createArrowFunction as Qt, parameterDef as R, propertyDef as Rt, inputDef as S, NumberSchemaNode as St, OperationNode as T, RefSchemaNode as Tt, IndexedAccessTypeNode as U, ConstNode as Ut, FunctionParameterNode as V, ArrowFunctionNode as Vt, ObjectBindingPatternNode as W, FunctionNode as Wt, createObjectBindingPattern as X, breakDef as Xt, createIndexedAccessType as Y, arrowFunctionDef as Yt, createTypeLiteral as Z, constDef as Zt, createOutput as _, ArraySchemaNode as _t, buildTypeLiteral as a, functionDef as an, ImportNode as at, InputNode as b, EnumSchemaNode as bt, containsCircularRef as c, typeDef as cn, createImport as ct, findCircularSchemas as d, defineNode as dn, fileDef as dt, createConst as en, indexedAccessTypeDef as et, isStringType as f, syncOptionality as fn, importDef as ft, OutputNode as g, createContent as gt, Node as h, contentDef as ht, buildGroupParam as i, createType as in, FileNode as it, StatusCode as j, TimeSchemaNode as jt, createResponse as k, SchemaType as kt, createDiscriminantNode as l, DistributiveOmit as ln, createSource as lt, syncSchemaRef as m, ContentNode as mt, OperationParamsResolver as n, createJsx as nn, typeLiteralDef as nt, caseParams as o, jsxDef as on, SourceNode as ot, resolveParamType as p, NodeKind as pn, sourceDef as pt, createFunctionParameter as q, TextNode as qt, ParamGroupType as r, createText as rn, ExportNode as rt, collectUsedSchemaNames as s, textDef as sn, createExport as st, BuildGroupArgs as t, createFunction as tn, objectBindingPatternDef as tt, createOperationParams as u, NodeDef as un, exportDef as ut, outputDef as v, DateSchemaNode as vt, HttpOperationNode as w, PrimitiveSchemaType as wt, createInput as x, IntersectionSchemaNode as xt, InputMeta as y, DatetimeSchemaNode as yt, FunctionParamKind as z, InferSchemaNode as zt };
2731
+ //# sourceMappingURL=ast-ClnJg9BN.d.ts.map