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

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.
@@ -146,7 +146,7 @@ declare const httpMethods: {
146
146
  * const kind: NodeKind = 'Schema'
147
147
  * ```
148
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';
149
+ 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';
150
150
  /**
151
151
  * Base shape shared by all AST nodes.
152
152
  *
@@ -162,6 +162,102 @@ type BaseNode = {
162
162
  kind: NodeKind;
163
163
  };
164
164
  //#endregion
165
+ //#region src/node.d.ts
166
+ /**
167
+ * Visitor callback names, one per traversable node kind. Kept in sync with the
168
+ * keys of `Visitor` in `visitor.ts`.
169
+ */
170
+ type VisitorKey = 'input' | 'output' | 'operation' | 'schema' | 'property' | 'parameter' | 'response';
171
+ /**
172
+ * Distributive `Omit` that preserves each member of a union.
173
+ *
174
+ * @example
175
+ * ```ts
176
+ * type A = { kind: 'a'; keep: string; drop: number }
177
+ * type B = { kind: 'b'; keep: boolean; drop: number }
178
+ * type Result = DistributiveOmit<A | B, 'drop'>
179
+ * // -> { kind: 'a'; keep: string } | { kind: 'b'; keep: boolean }
180
+ * ```
181
+ */
182
+ type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
183
+ /**
184
+ * Updates a schema's `optional` and `nullish` flags from a parent's `required`
185
+ * value and the schema's own `nullable`. Mirrors how OpenAPI parameters and
186
+ * object properties combine "required" and "nullable" into a single AST.
187
+ *
188
+ * - Non-required + non-nullable → `optional: true`.
189
+ * - Non-required + nullable → `nullish: true`.
190
+ * - Required → both flags cleared.
191
+ */
192
+ declare function syncOptionality(schema: SchemaNode, required: boolean): SchemaNode;
193
+ /**
194
+ * The single definition derived from one {@link defineNode} call: the node's
195
+ * `create` builder, its `is` guard, and the traversal metadata the registry
196
+ * collects into the visitor tables.
197
+ */
198
+ type NodeDef<TNode extends BaseNode = BaseNode, TInput = never> = {
199
+ /**
200
+ * Node discriminator this definition owns.
201
+ */
202
+ kind: NodeKind;
203
+ /**
204
+ * Builds a node from its input, applying `defaults` and the optional `build` hook.
205
+ */
206
+ create: (input: TInput) => TNode;
207
+ /**
208
+ * Type guard matching this node kind.
209
+ */
210
+ is: (node: unknown) => node is TNode;
211
+ /**
212
+ * Child node fields in traversal order. Feeds `VISITOR_KEYS`.
213
+ */
214
+ children?: ReadonlyArray<string>;
215
+ /**
216
+ * Visitor callback name. Feeds `VISITOR_KEY_BY_KIND`.
217
+ */
218
+ visitorKey?: VisitorKey;
219
+ /**
220
+ * When `true`, `create` is rerun after children are rebuilt so computed fields
221
+ * stay in sync. Feeds `nodeRebuilders`.
222
+ */
223
+ rebuild?: boolean;
224
+ };
225
+ type DefineNodeConfig<TNode extends BaseNode, TInput, TBuilt extends object> = {
226
+ kind: TNode['kind'];
227
+ defaults?: Partial<TNode>;
228
+ build?: (input: TInput) => TBuilt;
229
+ children?: ReadonlyArray<string>;
230
+ visitorKey?: VisitorKey;
231
+ rebuild?: boolean;
232
+ };
233
+ /**
234
+ * Defines a node once and derives its `create` builder, `is` guard, and traversal
235
+ * metadata. `create` merges `defaults`, the `build` hook (or the raw input), and the
236
+ * `kind`, so node construction lives in one place without scattered `as` casts.
237
+ *
238
+ * Set `rebuild: true` when the `build` hook derives fields from children. After a
239
+ * transform rewrites those children, the registry reruns `create` so the derived
240
+ * fields stay correct.
241
+ *
242
+ * @example Simple node
243
+ * ```ts
244
+ * const importDef = defineNode<ImportNode>({ kind: 'Import' })
245
+ * const createImport = importDef.create
246
+ * ```
247
+ *
248
+ * @example Node with a build hook that is rerun on transform
249
+ * ```ts
250
+ * const propertyDef = defineNode<PropertyNode, UserPropertyNode>({
251
+ * kind: 'Property',
252
+ * build: (props) => ({ ...props, required: props.required ?? false }),
253
+ * children: ['schema'],
254
+ * visitorKey: 'property',
255
+ * rebuild: true,
256
+ * })
257
+ * ```
258
+ */
259
+ declare function defineNode<TNode extends BaseNode, TInput = Omit<TNode, 'kind'>, TBuilt extends object = Omit<TNode, 'kind'>>(config: DefineNodeConfig<TNode, TInput, TBuilt>): NodeDef<TNode, TInput>;
260
+ //#endregion
165
261
  //#region src/nodes/code.d.ts
166
262
  /**
167
263
  * JSDoc documentation metadata attached to code declarations.
@@ -451,1885 +547,1972 @@ type JsxNode = BaseNode & {
451
547
  * structured children in {@link SourceNode.nodes}.
452
548
  */
453
549
  type CodeNode = ConstNode | TypeNode | FunctionNode | ArrowFunctionNode | TextNode | BreakNode | JsxNode;
454
- //#endregion
455
- //#region src/nodes/property.d.ts
456
550
  /**
457
- * AST node representing one named object property.
551
+ * Definition for the {@link ConstNode}.
552
+ */
553
+ declare const constDef: NodeDef<ConstNode, Omit<ConstNode, "kind">>;
554
+ /**
555
+ * Creates a `ConstNode` representing a TypeScript `const` declaration.
458
556
  *
459
- * @example
557
+ * @example Exported constant with type and `as const`
460
558
  * ```ts
461
- * const property: PropertyNode = {
462
- * kind: 'Property',
463
- * name: 'id',
464
- * schema: createSchema({ type: 'integer' }),
465
- * required: true,
466
- * }
559
+ * createConst({ name: 'pets', export: true, type: 'Pet[]', asConst: true })
560
+ * // export const pets: Pet[] = ... as const
467
561
  * ```
468
562
  */
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'
563
+ declare const createConst: (input: Omit<ConstNode, "kind">) => ConstNode;
510
564
  /**
511
- * Null value.
565
+ * Definition for the {@link TypeNode}.
512
566
  */
513
- | 'null'
567
+ declare const typeDef: NodeDef<TypeNode, Omit<TypeNode, "kind">>;
514
568
  /**
515
- * Any value.
569
+ * Creates a `TypeNode` representing a TypeScript `type` alias declaration.
570
+ *
571
+ * @example
572
+ * ```ts
573
+ * createType({ name: 'Pet', export: true })
574
+ * // export type Pet = ...
575
+ * ```
516
576
  */
517
- | 'any'
577
+ declare const createType: (input: Omit<TypeNode, "kind">) => TypeNode;
518
578
  /**
519
- * Unknown value.
579
+ * Definition for the {@link FunctionNode}.
520
580
  */
521
- | 'unknown'
581
+ declare const functionDef: NodeDef<FunctionNode, Omit<FunctionNode, "kind">>;
522
582
  /**
523
- * No value (`void`).
583
+ * Creates a `FunctionNode` representing a TypeScript `function` declaration.
584
+ *
585
+ * @example
586
+ * ```ts
587
+ * createFunction({ name: 'fetchPet', export: true, async: true, returnType: 'Pet' })
588
+ * // export async function fetchPet(): Promise<Pet> { ... }
589
+ * ```
524
590
  */
525
- | 'void'
591
+ declare const createFunction: (input: Omit<FunctionNode, "kind">) => FunctionNode;
526
592
  /**
527
- * Never value.
593
+ * Definition for the {@link ArrowFunctionNode}.
528
594
  */
529
- | 'never'
595
+ declare const arrowFunctionDef: NodeDef<ArrowFunctionNode, Omit<ArrowFunctionNode, "kind">>;
530
596
  /**
531
- * Object value.
597
+ * Creates an `ArrowFunctionNode` representing a TypeScript arrow function.
598
+ *
599
+ * @example
600
+ * ```ts
601
+ * createArrowFunction({ name: 'double', export: true, params: 'n: number', singleLine: true })
602
+ * // export const double = (n: number) => ...
603
+ * ```
532
604
  */
533
- | 'object'
605
+ declare const createArrowFunction: (input: Omit<ArrowFunctionNode, "kind">) => ArrowFunctionNode;
534
606
  /**
535
- * Array value.
607
+ * Definition for the {@link TextNode}.
536
608
  */
537
- | 'array'
609
+ declare const textDef: NodeDef<TextNode, string>;
538
610
  /**
539
- * Date value.
611
+ * Creates a {@link TextNode} representing a raw string fragment in the source output.
612
+ *
613
+ * @example
614
+ * ```ts
615
+ * createText('return fetch(id)')
616
+ * // { kind: 'Text', value: 'return fetch(id)' }
617
+ * ```
540
618
  */
541
- | 'date';
619
+ declare const createText: (input: string) => TextNode;
542
620
  /**
543
- * Composite schema types.
621
+ * Definition for the {@link BreakNode}.
544
622
  */
545
- type ComplexSchemaType = 'tuple' | 'union' | 'intersection' | 'enum';
623
+ declare const breakDef: NodeDef<BreakNode, void>;
546
624
  /**
547
- * Schema types that need special handling in generators.
625
+ * Creates a {@link BreakNode} representing a line break in the source output.
626
+ *
627
+ * @example
628
+ * ```ts
629
+ * createBreak()
630
+ * // { kind: 'Break' }
631
+ * ```
548
632
  */
549
- type SpecialSchemaType = 'ref' | 'datetime' | 'time' | 'uuid' | 'email' | 'url' | 'ipv4' | 'ipv6' | 'blob';
633
+ declare function createBreak(): BreakNode;
550
634
  /**
551
- * All schema type strings.
635
+ * Definition for the {@link JsxNode}.
552
636
  */
553
- type SchemaType = PrimitiveSchemaType | ComplexSchemaType | SpecialSchemaType;
637
+ declare const jsxDef: NodeDef<JsxNode, string>;
554
638
  /**
555
- * Scalar schema types without extra object/array/ref structure.
639
+ * Creates a {@link JsxNode} representing a raw JSX fragment in the source output.
640
+ *
641
+ * @example
642
+ * ```ts
643
+ * createJsx('<>\n <a href={href}>Open</a>\n</>')
644
+ * // { kind: 'Jsx', value: '<>\n <a href={href}>Open</a>\n</>' }
645
+ * ```
556
646
  */
557
- type ScalarSchemaType = Exclude<SchemaType, 'object' | 'array' | 'tuple' | 'union' | 'intersection' | 'enum' | 'ref' | 'datetime' | 'date' | 'time' | 'string' | 'number' | 'integer' | 'bigint' | 'url' | 'uuid' | 'email'>;
647
+ declare const createJsx: (input: string) => JsxNode;
648
+ //#endregion
649
+ //#region src/infer.d.ts
558
650
  /**
559
- * Fields shared by all schema nodes.
651
+ * Shared parser options used by OAS-to-AST inference and parser flows.
560
652
  */
561
- type SchemaNodeBase = BaseNode & {
562
- /**
563
- * Node kind.
564
- */
565
- kind: 'Schema';
566
- /**
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.
571
- */
572
- name?: string | null;
573
- /**
574
- * Short schema title.
575
- */
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;
653
+ type ParserOptions = {
601
654
  /**
602
- * Whether the schema is write-only.
655
+ * How `format: 'date-time'` schemas are represented downstream.
656
+ * - `false` falls through to a plain `string` (no validation).
657
+ * - `'string'` emits a datetime string node.
658
+ * - `'stringOffset'` emits a datetime node with timezone offset.
659
+ * - `'stringLocal'` emits a local datetime node.
660
+ * - `'date'` emits a `date` node (JavaScript `Date` object).
603
661
  */
604
- writeOnly?: boolean;
662
+ dateType: false | 'string' | 'stringOffset' | 'stringLocal' | 'date';
605
663
  /**
606
- * Default value.
664
+ * How `type: 'integer'` (and `format: 'int64'`) maps to TypeScript.
665
+ * - `'bigint'` is exact for 64-bit IDs, but does not round-trip through JSON.
666
+ * - `'number'` fits most JSON APIs. Loses precision above `Number.MAX_SAFE_INTEGER`.
667
+ *
668
+ * @default 'bigint'
607
669
  */
608
- default?: unknown;
670
+ integerType?: 'number' | 'bigint';
609
671
  /**
610
- * Example value.
672
+ * AST type used when a schema's type cannot be inferred from the spec
673
+ * (`additionalProperties: true`, missing `type`, ...).
611
674
  */
612
- example?: unknown;
675
+ unknownType: 'any' | 'unknown' | 'void';
613
676
  /**
614
- * Base primitive type.
615
- * For example, this is `'string'` for a `uuid` schema.
677
+ * AST type used for completely empty schemas (`{}`).
616
678
  */
617
- primitive?: PrimitiveSchemaType;
679
+ emptySchemaType: 'any' | 'unknown' | 'void';
618
680
  /**
619
- * Schema `format` value.
681
+ * Suffix appended to derived enum names when Kubb has to invent one
682
+ * (typically for inline enums on object properties).
620
683
  */
621
- format?: string;
684
+ enumSuffix: 'enum' | (string & {});
622
685
  };
623
686
  /**
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
- * ```
687
+ * Maps each `dateType` option value to the AST node produced by `format: 'date-time'`.
634
688
  */
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>;
660
- /**
661
- * Minimum number of properties allowed.
662
- */
663
- minProperties?: number;
664
- /**
665
- * Maximum number of properties allowed.
666
- */
667
- maxProperties?: number;
689
+ type DateTimeNodeByDateType = {
690
+ date: DateSchemaNode;
691
+ string: DatetimeSchemaNode;
692
+ stringOffset: DatetimeSchemaNode;
693
+ stringLocal: DatetimeSchemaNode;
694
+ false: StringSchemaNode;
668
695
  };
669
696
  /**
670
- * Array-like schema (`array` or `tuple`).
697
+ * Resolves the AST node produced by `format: 'date-time'` based on the `dateType` option.
698
+ */
699
+ type ResolveDateTimeNode<TDateType extends ParserOptions['dateType']> = DateTimeNodeByDateType[TDateType extends keyof DateTimeNodeByDateType ? TDateType : 'string'];
700
+ /**
701
+ * Ordered list of `[schema-shape, SchemaNode]` pairs.
702
+ * `InferSchemaNode` walks this tuple in order and returns the first matching node type.
703
+ */
704
+ type SchemaNodeMap<TDateType extends ParserOptions['dateType'] = 'string'> = [[{
705
+ $ref: string;
706
+ }, RefSchemaNode], [{
707
+ allOf: ReadonlyArray<unknown>;
708
+ properties: object;
709
+ }, IntersectionSchemaNode], [{
710
+ allOf: readonly [unknown, unknown, ...Array<unknown>];
711
+ }, IntersectionSchemaNode], [{
712
+ allOf: ReadonlyArray<unknown>;
713
+ }, SchemaNode], [{
714
+ oneOf: ReadonlyArray<unknown>;
715
+ }, UnionSchemaNode], [{
716
+ anyOf: ReadonlyArray<unknown>;
717
+ }, UnionSchemaNode], [{
718
+ const: null;
719
+ }, ScalarSchemaNode], [{
720
+ const: string | number | boolean;
721
+ }, EnumSchemaNode], [{
722
+ type: ReadonlyArray<string>;
723
+ }, UnionSchemaNode], [{
724
+ type: 'array';
725
+ enum: ReadonlyArray<unknown>;
726
+ }, ArraySchemaNode], [{
727
+ enum: ReadonlyArray<unknown>;
728
+ }, EnumSchemaNode], [{
729
+ type: 'enum';
730
+ }, EnumSchemaNode], [{
731
+ type: 'union';
732
+ }, UnionSchemaNode], [{
733
+ type: 'intersection';
734
+ }, IntersectionSchemaNode], [{
735
+ type: 'tuple';
736
+ }, ArraySchemaNode], [{
737
+ type: 'ref';
738
+ }, RefSchemaNode], [{
739
+ type: 'datetime';
740
+ }, DatetimeSchemaNode], [{
741
+ type: 'date';
742
+ }, DateSchemaNode], [{
743
+ type: 'time';
744
+ }, TimeSchemaNode], [{
745
+ type: 'url';
746
+ }, UrlSchemaNode], [{
747
+ type: 'object';
748
+ }, ObjectSchemaNode], [{
749
+ additionalProperties: boolean | {};
750
+ }, ObjectSchemaNode], [{
751
+ type: 'array';
752
+ }, ArraySchemaNode], [{
753
+ items: object;
754
+ }, ArraySchemaNode], [{
755
+ prefixItems: ReadonlyArray<unknown>;
756
+ }, ArraySchemaNode], [{
757
+ type: string;
758
+ format: 'date-time';
759
+ }, ResolveDateTimeNode<TDateType>], [{
760
+ type: string;
761
+ format: 'date';
762
+ }, DateSchemaNode], [{
763
+ type: string;
764
+ format: 'time';
765
+ }, TimeSchemaNode], [{
766
+ format: 'date-time';
767
+ }, ResolveDateTimeNode<TDateType>], [{
768
+ format: 'date';
769
+ }, DateSchemaNode], [{
770
+ format: 'time';
771
+ }, TimeSchemaNode], [{
772
+ type: 'string';
773
+ }, StringSchemaNode], [{
774
+ type: 'number';
775
+ }, NumberSchemaNode], [{
776
+ type: 'integer';
777
+ }, NumberSchemaNode], [{
778
+ type: 'bigint';
779
+ }, NumberSchemaNode], [{
780
+ type: string;
781
+ }, ScalarSchemaNode], [{
782
+ minLength: number;
783
+ }, StringSchemaNode], [{
784
+ maxLength: number;
785
+ }, StringSchemaNode], [{
786
+ pattern: string;
787
+ }, StringSchemaNode], [{
788
+ minimum: number;
789
+ }, NumberSchemaNode], [{
790
+ maximum: number;
791
+ }, NumberSchemaNode]];
792
+ /**
793
+ * Infers the matching AST `SchemaNode` type from an input schema shape.
794
+ */
795
+ 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;
796
+ //#endregion
797
+ //#region src/nodes/property.d.ts
798
+ /**
799
+ * AST node representing one named object property.
671
800
  *
672
801
  * @example
673
802
  * ```ts
674
- * const arraySchema: ArraySchemaNode = {
675
- * kind: 'Schema',
676
- * type: 'array',
677
- * items: [],
803
+ * const property: PropertyNode = {
804
+ * kind: 'Property',
805
+ * name: 'id',
806
+ * schema: createSchema({ type: 'integer' }),
807
+ * required: true,
678
808
  * }
679
809
  * ```
680
810
  */
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>;
811
+ type PropertyNode = BaseNode & {
690
812
  /**
691
- * Tuple rest-item schema for elements beyond positional `items`.
813
+ * Node kind.
692
814
  */
693
- rest?: SchemaNode;
815
+ kind: 'Property';
694
816
  /**
695
- * Minimum item count (or tuple length).
817
+ * Property key.
696
818
  */
697
- min?: number;
819
+ name: string;
698
820
  /**
699
- * Maximum item count (or tuple length).
821
+ * Property schema.
700
822
  */
701
- max?: number;
823
+ schema: SchemaNode;
702
824
  /**
703
- * Whether all items must be unique.
825
+ * Whether the property is required.
704
826
  */
705
- unique?: boolean;
827
+ required: boolean;
706
828
  };
707
829
  /**
708
- * Shared shape for union and intersection schemas.
830
+ * Loosely-typed property accepted by `createProperty`, with `required` optional.
709
831
  */
710
- type CompositeSchemaNodeBase = SchemaNodeBase & {
711
- /**
712
- * Member schemas.
713
- */
714
- members?: Array<SchemaNode>;
715
- };
832
+ type UserPropertyNode = Pick<PropertyNode, 'name' | 'schema'> & Partial<Omit<PropertyNode, 'kind' | 'name' | 'schema'>>;
716
833
  /**
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
- * ```
834
+ * Definition for the {@link PropertyNode}. `required` defaults to `false` and the
835
+ * schema's `optional`/`nullish` flags are kept in sync with it.
727
836
  */
728
- type UnionSchemaNode = CompositeSchemaNodeBase & {
729
- /**
730
- * Schema type discriminator.
731
- */
732
- 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
- };
837
+ declare const propertyDef: NodeDef<PropertyNode, UserPropertyNode>;
743
838
  /**
744
- * Intersection schema, often from `allOf`.
839
+ * Creates a `PropertyNode`.
745
840
  *
746
841
  * @example
747
842
  * ```ts
748
- * const intersectionSchema: IntersectionSchemaNode = {
749
- * kind: 'Schema',
750
- * type: 'intersection',
751
- * members: [],
752
- * }
843
+ * const property = createProperty({
844
+ * name: 'status',
845
+ * required: true,
846
+ * schema: createSchema({ type: 'string', nullable: true }),
847
+ * })
848
+ * // required=true, no optional/nullish
753
849
  * ```
754
850
  */
755
- type IntersectionSchemaNode = CompositeSchemaNodeBase & {
756
- /**
757
- * Schema type discriminator.
758
- */
759
- type: 'intersection';
760
- };
851
+ declare const createProperty: (input: UserPropertyNode) => PropertyNode;
852
+ //#endregion
853
+ //#region src/nodes/schema.d.ts
854
+ type PrimitiveSchemaType =
761
855
  /**
762
- * One named enum item.
856
+ * Text value.
763
857
  */
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
- };
858
+ 'string'
778
859
  /**
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
- * ```
860
+ * Floating-point number.
789
861
  */
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
- };
862
+ | 'number'
805
863
  /**
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
- * ```
864
+ * Integer number.
816
865
  */
817
- type RefSchemaNode = SchemaNodeBase & {
818
- /**
819
- * Schema type discriminator.
820
- */
821
- 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
- };
866
+ | 'integer'
844
867
  /**
845
- * Datetime schema.
846
- *
847
- * @example
848
- * ```ts
849
- * const datetimeSchema: DatetimeSchemaNode = { kind: 'Schema', type: 'datetime' }
850
- * ```
868
+ * Big integer number.
851
869
  */
852
- type DatetimeSchemaNode = SchemaNodeBase & {
853
- /**
854
- * Schema type discriminator.
855
- */
856
- 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
- };
870
+ | 'bigint'
866
871
  /**
867
- * Shared base for `date` and `time` schemas.
872
+ * Boolean value.
868
873
  */
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
- };
874
+ | 'boolean'
879
875
  /**
880
- * Date schema node.
881
- *
882
- * @example
883
- * ```ts
884
- * const dateSchema: DateSchemaNode = { kind: 'Schema', type: 'date', representation: 'string' }
885
- * ```
876
+ * Null value.
886
877
  */
887
- type DateSchemaNode = TemporalSchemaNodeBase<'date'>;
878
+ | 'null'
888
879
  /**
889
- * Time schema node.
890
- *
891
- * @example
892
- * ```ts
893
- * const timeSchema: TimeSchemaNode = { kind: 'Schema', type: 'time', representation: 'string' }
894
- * ```
880
+ * Any value.
895
881
  */
896
- type TimeSchemaNode = TemporalSchemaNodeBase<'time'>;
882
+ | 'any'
897
883
  /**
898
- * String schema node.
899
- *
900
- * @example
901
- * ```ts
902
- * const stringSchema: StringSchemaNode = { kind: 'Schema', type: 'string' }
903
- * ```
884
+ * Unknown value.
904
885
  */
905
- type StringSchemaNode = SchemaNodeBase & {
886
+ | 'unknown'
887
+ /**
888
+ * No value (`void`).
889
+ */
890
+ | 'void'
891
+ /**
892
+ * Never value.
893
+ */
894
+ | 'never'
895
+ /**
896
+ * Object value.
897
+ */
898
+ | 'object'
899
+ /**
900
+ * Array value.
901
+ */
902
+ | 'array'
903
+ /**
904
+ * Date value.
905
+ */
906
+ | 'date';
907
+ /**
908
+ * Composite schema types.
909
+ */
910
+ type ComplexSchemaType = 'tuple' | 'union' | 'intersection' | 'enum';
911
+ /**
912
+ * Schema types that need special handling in generators.
913
+ */
914
+ type SpecialSchemaType = 'ref' | 'datetime' | 'time' | 'uuid' | 'email' | 'url' | 'ipv4' | 'ipv6' | 'blob';
915
+ /**
916
+ * All schema type strings.
917
+ */
918
+ type SchemaType = PrimitiveSchemaType | ComplexSchemaType | SpecialSchemaType;
919
+ /**
920
+ * Scalar schema types without extra object/array/ref structure.
921
+ */
922
+ type ScalarSchemaType = Exclude<SchemaType, 'object' | 'array' | 'tuple' | 'union' | 'intersection' | 'enum' | 'ref' | 'datetime' | 'date' | 'time' | 'string' | 'number' | 'integer' | 'bigint' | 'url' | 'uuid' | 'email'>;
923
+ /**
924
+ * Fields shared by all schema nodes.
925
+ */
926
+ type SchemaNodeBase = BaseNode & {
906
927
  /**
907
- * Schema type discriminator.
928
+ * Node kind.
908
929
  */
909
- type: 'string';
930
+ kind: 'Schema';
910
931
  /**
911
- * Minimum string length.
932
+ * Schema name for named definitions (for example, `"Pet"`).
933
+ * Inline schemas omit this field.
934
+ * `null` means kubb has processed this and determined there is no applicable name.
935
+ * `undefined` means the name has not been set yet.
912
936
  */
913
- min?: number;
937
+ name?: string | null;
914
938
  /**
915
- * Maximum string length.
939
+ * Short schema title.
916
940
  */
917
- max?: number;
941
+ title?: string;
918
942
  /**
919
- * Regex pattern.
943
+ * Schema description text.
920
944
  */
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 & {
945
+ description?: string;
932
946
  /**
933
- * Schema type discriminator.
947
+ * Whether `null` is allowed.
934
948
  */
935
- type: 'number' | 'integer' | 'bigint';
949
+ nullable?: boolean;
936
950
  /**
937
- * Minimum value.
951
+ * Whether the field is optional.
938
952
  */
939
- min?: number;
953
+ optional?: boolean;
940
954
  /**
941
- * Maximum value.
955
+ * Both optional and nullable (`optional` + `nullable`).
942
956
  */
943
- max?: number;
957
+ nullish?: boolean;
944
958
  /**
945
- * Exclusive minimum value.
959
+ * Whether the schema is deprecated.
946
960
  */
947
- exclusiveMinimum?: number;
961
+ deprecated?: boolean;
948
962
  /**
949
- * Exclusive maximum value.
963
+ * Whether the schema is read-only.
964
+ */
965
+ readOnly?: boolean;
966
+ /**
967
+ * Whether the schema is write-only.
968
+ */
969
+ writeOnly?: boolean;
970
+ /**
971
+ * Default value.
972
+ */
973
+ default?: unknown;
974
+ /**
975
+ * Example value.
976
+ */
977
+ example?: unknown;
978
+ /**
979
+ * Base primitive type.
980
+ * For example, this is `'string'` for a `uuid` schema.
950
981
  */
951
- exclusiveMaximum?: number;
982
+ primitive?: PrimitiveSchemaType;
952
983
  /**
953
- * The value must be a multiple of this number.
984
+ * Schema `format` value.
954
985
  */
955
- multipleOf?: number;
986
+ format?: string;
956
987
  };
957
988
  /**
958
- * Scalar schema with no extra constraints.
989
+ * Object schema with ordered properties.
959
990
  *
960
991
  * @example
961
992
  * ```ts
962
- * const anySchema: ScalarSchemaNode = { kind: 'Schema', type: 'any' }
993
+ * const objectSchema: ObjectSchemaNode = {
994
+ * kind: 'Schema',
995
+ * type: 'object',
996
+ * properties: [],
997
+ * }
963
998
  * ```
964
999
  */
965
- type ScalarSchemaNode = SchemaNodeBase & {
1000
+ type ObjectSchemaNode = SchemaNodeBase & {
966
1001
  /**
967
1002
  * Schema type discriminator.
968
1003
  */
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 & {
1004
+ type: 'object';
981
1005
  /**
982
- * Schema type discriminator.
1006
+ * Primitive type, always `'object'` for object schemas.
983
1007
  */
984
- type: 'url';
1008
+ primitive: 'object';
985
1009
  /**
986
- * OpenAPI-style path template, for example, `'/pets/{petId}'`.
1010
+ * Ordered object properties.
987
1011
  */
988
- path?: string;
1012
+ properties: Array<PropertyNode>;
989
1013
  /**
990
- * Minimum string length.
1014
+ * Additional object properties behavior:
1015
+ * - `true`: allow any value
1016
+ * - `false`: reject unknown properties (maps to `.strict()` in Zod)
1017
+ * - `SchemaNode`: allow values that match that schema
1018
+ * - `undefined`: no additional properties constraint (open object)
991
1019
  */
992
- min?: number;
1020
+ additionalProperties?: SchemaNode | boolean;
993
1021
  /**
994
- * Maximum string length.
1022
+ * Pattern-based property schemas.
995
1023
  */
996
- max?: number;
1024
+ patternProperties?: Record<string, SchemaNode>;
1025
+ /**
1026
+ * Minimum number of properties allowed.
1027
+ */
1028
+ minProperties?: number;
1029
+ /**
1030
+ * Maximum number of properties allowed.
1031
+ */
1032
+ maxProperties?: number;
997
1033
  };
998
1034
  /**
999
- * Format-string schema for string-based formats that support length constraints.
1035
+ * Array-like schema (`array` or `tuple`).
1000
1036
  *
1001
1037
  * @example
1002
1038
  * ```ts
1003
- * const uuidSchema: FormatStringSchemaNode = { kind: 'Schema', type: 'uuid', min: 36, max: 36 }
1039
+ * const arraySchema: ArraySchemaNode = {
1040
+ * kind: 'Schema',
1041
+ * type: 'array',
1042
+ * items: [],
1043
+ * }
1004
1044
  * ```
1005
1045
  */
1006
- type FormatStringSchemaNode = SchemaNodeBase & {
1046
+ type ArraySchemaNode = SchemaNodeBase & {
1007
1047
  /**
1008
- * Schema type discriminator.
1048
+ * Schema type discriminator (`array` or `tuple`).
1009
1049
  */
1010
- type: 'uuid' | 'email';
1050
+ type: 'array' | 'tuple';
1011
1051
  /**
1012
- * Minimum string length.
1052
+ * Item schemas.
1053
+ */
1054
+ items?: Array<SchemaNode>;
1055
+ /**
1056
+ * Tuple rest-item schema for elements beyond positional `items`.
1057
+ */
1058
+ rest?: SchemaNode;
1059
+ /**
1060
+ * Minimum item count (or tuple length).
1013
1061
  */
1014
1062
  min?: number;
1015
1063
  /**
1016
- * Maximum string length.
1064
+ * Maximum item count (or tuple length).
1017
1065
  */
1018
1066
  max?: number;
1067
+ /**
1068
+ * Whether all items must be unique.
1069
+ */
1070
+ unique?: boolean;
1019
1071
  };
1020
1072
  /**
1021
- * IPv4 address schema node.
1022
- *
1023
- * @example
1024
- * ```ts
1025
- * const ipv4Schema: Ipv4SchemaNode = { kind: 'Schema', type: 'ipv4' }
1026
- * ```
1073
+ * Shared shape for union and intersection schemas.
1027
1074
  */
1028
- type Ipv4SchemaNode = SchemaNodeBase & {
1075
+ type CompositeSchemaNodeBase = SchemaNodeBase & {
1029
1076
  /**
1030
- * Schema type discriminator.
1077
+ * Member schemas.
1031
1078
  */
1032
- type: 'ipv4';
1079
+ members?: Array<SchemaNode>;
1033
1080
  };
1034
1081
  /**
1035
- * IPv6 address schema node.
1082
+ * Union schema, often from `oneOf` or `anyOf`.
1036
1083
  *
1037
1084
  * @example
1038
1085
  * ```ts
1039
- * const ipv6Schema: Ipv6SchemaNode = { kind: 'Schema', type: 'ipv6' }
1086
+ * const unionSchema: UnionSchemaNode = {
1087
+ * kind: 'Schema',
1088
+ * type: 'union',
1089
+ * members: [],
1090
+ * }
1040
1091
  * ```
1041
1092
  */
1042
- type Ipv6SchemaNode = SchemaNodeBase & {
1093
+ type UnionSchemaNode = CompositeSchemaNodeBase & {
1043
1094
  /**
1044
1095
  * Schema type discriminator.
1045
1096
  */
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;
1097
+ type: 'union';
1098
+ /**
1099
+ * Discriminator property name from OpenAPI `discriminator.propertyName`.
1100
+ */
1101
+ discriminatorPropertyName?: string;
1102
+ /**
1103
+ * Logical strategy applied to union members: 'one' means exactly one member must be valid (from `oneOf`),
1104
+ * 'any' means any number of members can be valid (from `anyOf`).
1105
+ */
1106
+ strategy?: 'one' | 'any';
1079
1107
  };
1080
1108
  /**
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.
1109
+ * Intersection schema, often from `allOf`.
1091
1110
  *
1092
1111
  * @example
1093
1112
  * ```ts
1094
- * const content: ContentNode = {
1095
- * kind: 'Content',
1096
- * contentType: 'application/json',
1097
- * schema: createSchema({ type: 'string' }),
1113
+ * const intersectionSchema: IntersectionSchemaNode = {
1114
+ * kind: 'Schema',
1115
+ * type: 'intersection',
1116
+ * members: [],
1098
1117
  * }
1099
1118
  * ```
1100
1119
  */
1101
- type ContentNode = BaseNode & {
1120
+ type IntersectionSchemaNode = CompositeSchemaNodeBase & {
1102
1121
  /**
1103
- * Node kind.
1122
+ * Schema type discriminator.
1104
1123
  */
1105
- kind: 'Content';
1124
+ type: 'intersection';
1125
+ };
1126
+ /**
1127
+ * One named enum item.
1128
+ */
1129
+ type EnumValueNode = {
1106
1130
  /**
1107
- * The content type for this entry (e.g. `'application/json'`).
1131
+ * Enum item name.
1108
1132
  */
1109
- contentType: string;
1133
+ name: string;
1110
1134
  /**
1111
- * Body schema for this content type.
1135
+ * Enum item value.
1112
1136
  */
1113
- schema?: SchemaNode;
1137
+ value: string | number | boolean;
1114
1138
  /**
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.
1139
+ * Primitive type of the enum value.
1117
1140
  */
1118
- keysToOmit?: Array<string> | null;
1141
+ primitive: Extract<PrimitiveSchemaType, 'string' | 'number' | 'boolean'>;
1119
1142
  };
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
1143
  /**
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
- * ```
1144
+ * Enum schema node.
1147
1145
  *
1148
- * @example Namespace import (TypeScript: `import * as React from 'react'`)
1146
+ * @example
1149
1147
  * ```ts
1150
- * createImport({ name: 'React', path: 'react', isNameSpace: true })
1148
+ * const enumSchema: EnumSchemaNode = {
1149
+ * kind: 'Schema',
1150
+ * type: 'enum',
1151
+ * enumValues: ['a', 'b'],
1152
+ * }
1151
1153
  * ```
1152
1154
  */
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;
1155
+ type EnumSchemaNode = SchemaNodeBase & {
1166
1156
  /**
1167
- * Add type-only import prefix.
1168
- * - `true` generates `import type { Type } from './path'`
1169
- * - `false` generates `import { Type } from './path'`
1170
- * @default false
1157
+ * Schema type discriminator.
1171
1158
  */
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
1159
+ type: 'enum';
1160
+ /**
1161
+ * Enum values in simple form.
1178
1162
  */
1179
- isNameSpace?: boolean | null;
1163
+ enumValues?: Array<string | number | boolean | null>;
1180
1164
  /**
1181
- * When set, the import path is resolved relative to this root.
1165
+ * Enum values in named form.
1166
+ * If present, this is used instead of `enumValues`.
1182
1167
  */
1183
- root?: string | null;
1168
+ namedEnumValues?: Array<EnumValueNode>;
1184
1169
  };
1185
1170
  /**
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
- * ```
1171
+ * Reference schema that points to another schema definition.
1202
1172
  *
1203
- * @example Namespace alias (TypeScript: `export * as utils from './utils'`)
1173
+ * @example
1204
1174
  * ```ts
1205
- * createExport({ name: 'utils', path: './utils', asAlias: true })
1175
+ * const refSchema: RefSchemaNode = {
1176
+ * kind: 'Schema',
1177
+ * type: 'ref',
1178
+ * ref: '#/components/schemas/Pet',
1179
+ * }
1206
1180
  * ```
1207
1181
  */
1208
- type ExportNode = BaseNode & {
1209
- kind: 'Export';
1182
+ type RefSchemaNode = SchemaNodeBase & {
1210
1183
  /**
1211
- * Export name(s) to be used. When omitted, generates a wildcard export.
1212
- * @example ['useState']
1213
- * @example 'React'
1184
+ * Schema type discriminator.
1214
1185
  */
1215
- name?: string | Array<string> | null;
1186
+ type: 'ref';
1216
1187
  /**
1217
- * Path for the export.
1218
- * @example '@kubb/core'
1188
+ * Referenced schema name.
1189
+ * `null` means Kubb has processed this and determined there is no applicable name.
1219
1190
  */
1220
- path: string;
1191
+ name?: string | null;
1221
1192
  /**
1222
- * Add type-only export prefix.
1223
- * - `true` generates `export type { Type } from './path'`
1224
- * - `false` generates `export { Type } from './path'`
1225
- * @default false
1193
+ * Original `$ref` path, for example, `#/components/schemas/Order`.
1194
+ * Used to resolve names later.
1226
1195
  */
1227
- isTypeOnly?: boolean | null;
1196
+ ref?: string;
1228
1197
  /**
1229
- * Export as an aliased namespace.
1230
- * - `true` generates `export * as aliasName from './path'`
1231
- * - `false` generates a standard export
1232
- * @default false
1198
+ * Pattern copied from a sibling `pattern` field.
1233
1199
  */
1234
- asAlias?: boolean | null;
1200
+ pattern?: string;
1201
+ /**
1202
+ * The fully-parsed schema this ref resolves to, so its structure (`primitive`, `properties`)
1203
+ * can be read without following the reference. Populated during OAS parsing when the
1204
+ * definition resolves, `null` when it can't or the ref is circular, and `undefined` when
1205
+ * resolution has not been attempted.
1206
+ */
1207
+ schema?: SchemaNode | null;
1235
1208
  };
1236
1209
  /**
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
- * ```
1210
+ * Datetime schema.
1243
1211
  *
1244
- * @example Inline unnamed code block
1212
+ * @example
1245
1213
  * ```ts
1246
- * createSource({ nodes: [createText('const x = 1')] })
1214
+ * const datetimeSchema: DatetimeSchemaNode = { kind: 'Schema', type: 'datetime' }
1247
1215
  * ```
1248
1216
  */
1249
- type SourceNode = BaseNode & {
1250
- kind: 'Source';
1217
+ type DatetimeSchemaNode = SchemaNodeBase & {
1251
1218
  /**
1252
- * Optional name identifying this source (used for deduplication and barrel generation).
1219
+ * Schema type discriminator.
1253
1220
  */
1254
- name?: string | null;
1221
+ type: 'datetime';
1255
1222
  /**
1256
- * Mark this source as a type-only export.
1257
- * @default false
1223
+ * Whether the datetime includes a timezone offset (`dateType: 'stringOffset'`).
1258
1224
  */
1259
- isTypeOnly?: boolean | null;
1225
+ offset?: boolean;
1260
1226
  /**
1261
- * Include `export` keyword in the generated source.
1262
- * @default false
1227
+ * Whether the datetime is local (no timezone, `dateType: 'stringLocal'`).
1263
1228
  */
1264
- isExportable?: boolean | null;
1229
+ local?: boolean;
1230
+ };
1231
+ /**
1232
+ * Shared base for `date` and `time` schemas.
1233
+ */
1234
+ type TemporalSchemaNodeBase<T extends 'date' | 'time'> = SchemaNodeBase & {
1265
1235
  /**
1266
- * Include this source in barrel/index file generation.
1267
- * @default false
1236
+ * Schema type discriminator.
1268
1237
  */
1269
- isIndexable?: boolean | null;
1238
+ type: T;
1270
1239
  /**
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.
1240
+ * Output representation in generated code.
1273
1241
  */
1274
- nodes?: Array<CodeNode>;
1242
+ representation: 'date' | 'string';
1275
1243
  };
1276
1244
  /**
1277
- * Represents a fully resolved file in the AST.
1245
+ * Date schema node.
1278
1246
  *
1279
- * Created via `createFile()`, which computes the `id`, `name`, and `extname` from the input
1280
- * and deduplicates `imports`, `exports`, and `sources`.
1247
+ * @example
1248
+ * ```ts
1249
+ * const dateSchema: DateSchemaNode = { kind: 'Schema', type: 'date', representation: 'string' }
1250
+ * ```
1251
+ */
1252
+ type DateSchemaNode = TemporalSchemaNodeBase<'date'>;
1253
+ /**
1254
+ * Time schema node.
1281
1255
  *
1282
1256
  * @example
1283
1257
  * ```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'
1258
+ * const timeSchema: TimeSchemaNode = { kind: 'Schema', type: 'time', representation: 'string' }
1294
1259
  * ```
1295
1260
  */
1296
- type FileNode<TMeta extends object = object> = BaseNode & {
1297
- kind: 'File';
1298
- /**
1299
- * Unique identifier derived from a SHA256 hash of the file path. Computed
1300
- * by `createFile`; callers do not need to provide it.
1301
- */
1302
- id: string;
1261
+ type TimeSchemaNode = TemporalSchemaNodeBase<'time'>;
1262
+ /**
1263
+ * String schema node.
1264
+ *
1265
+ * @example
1266
+ * ```ts
1267
+ * const stringSchema: StringSchemaNode = { kind: 'Schema', type: 'string' }
1268
+ * ```
1269
+ */
1270
+ type StringSchemaNode = SchemaNodeBase & {
1303
1271
  /**
1304
- * File name without extension, derived from `baseName`.
1305
- * @link https://nodejs.org/api/path.html#pathformatpathobject
1272
+ * Schema type discriminator.
1306
1273
  */
1307
- name: string;
1274
+ type: 'string';
1308
1275
  /**
1309
- * File base name, including extension.
1310
- * Based on UNIX basename: `${name}${extname}`
1311
- * @link https://nodejs.org/api/path.html#pathbasenamepath-suffix
1276
+ * Minimum string length.
1312
1277
  */
1313
- baseName: `${string}.${string}`;
1278
+ min?: number;
1314
1279
  /**
1315
- * Full qualified path to the file.
1280
+ * Maximum string length.
1316
1281
  */
1317
- path: string;
1282
+ max?: number;
1318
1283
  /**
1319
- * File extension extracted from `baseName`.
1284
+ * Regex pattern.
1320
1285
  */
1321
- extname: Extname;
1286
+ pattern?: string;
1287
+ };
1288
+ /**
1289
+ * Numeric schema (`number`, `integer`, or `bigint`).
1290
+ *
1291
+ * @example
1292
+ * ```ts
1293
+ * const numberSchema: NumberSchemaNode = { kind: 'Schema', type: 'number' }
1294
+ * ```
1295
+ */
1296
+ type NumberSchemaNode = SchemaNodeBase & {
1322
1297
  /**
1323
- * Deduplicated list of source code fragments.
1298
+ * Schema type discriminator.
1324
1299
  */
1325
- sources: Array<SourceNode>;
1300
+ type: 'number' | 'integer' | 'bigint';
1326
1301
  /**
1327
- * Deduplicated list of import declarations.
1302
+ * Minimum value.
1328
1303
  */
1329
- imports: Array<ImportNode>;
1304
+ min?: number;
1330
1305
  /**
1331
- * Deduplicated list of export declarations.
1306
+ * Maximum value.
1332
1307
  */
1333
- exports: Array<ExportNode>;
1308
+ max?: number;
1334
1309
  /**
1335
- * Optional metadata attached to this file (used by plugins for barrel generation etc.).
1310
+ * Exclusive minimum value.
1336
1311
  */
1337
- meta?: TMeta;
1312
+ exclusiveMinimum?: number;
1338
1313
  /**
1339
- * Optional banner prepended to the generated file content.
1340
- * Accepts `null` so `resolver.resolveBanner()` results can be passed directly.
1314
+ * Exclusive maximum value.
1341
1315
  */
1342
- banner?: string | null;
1316
+ exclusiveMaximum?: number;
1343
1317
  /**
1344
- * Optional footer appended to the generated file content.
1345
- * Accepts `null` so `resolver.resolveFooter()` results can be passed directly.
1318
+ * The value must be a multiple of this number.
1346
1319
  */
1347
- footer?: string | null;
1320
+ multipleOf?: number;
1348
1321
  };
1349
- //#endregion
1350
- //#region src/nodes/function.d.ts
1351
1322
  /**
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
- * ```
1323
+ * Scalar schema with no extra constraints.
1365
1324
  *
1366
- * @example Struct variant
1325
+ * @example
1367
1326
  * ```ts
1368
- * createParamsType({ variant: 'struct', properties: [{ name: 'petId', optional: false, type: createParamsType({ variant: 'reference', name: 'string' }) }] })
1369
- * // { petId: string }
1327
+ * const anySchema: ScalarSchemaNode = { kind: 'Schema', type: 'any' }
1370
1328
  * ```
1329
+ */
1330
+ type ScalarSchemaNode = SchemaNodeBase & {
1331
+ /**
1332
+ * Schema type discriminator.
1333
+ */
1334
+ type: ScalarSchemaType;
1335
+ };
1336
+ /**
1337
+ * URL schema node.
1338
+ * Can include an OpenAPI-style path template for template literal types.
1371
1339
  *
1372
- * @example Member variant
1340
+ * @example
1373
1341
  * ```ts
1374
- * createParamsType({ variant: 'member', base: 'PathParams', key: 'petId' })
1375
- * // PathParams['petId']
1342
+ * const urlSchema: UrlSchemaNode = { kind: 'Schema', type: 'url', path: '/pets/{petId}' }
1376
1343
  * ```
1377
1344
  */
1378
- type ParamsTypeNode = BaseNode & {
1345
+ type UrlSchemaNode = SchemaNodeBase & {
1379
1346
  /**
1380
- * Node kind.
1347
+ * Schema type discriminator.
1381
1348
  */
1382
- kind: 'ParamsType';
1383
- } & ({
1349
+ type: 'url';
1384
1350
  /**
1385
- * Reference variant, a plain type name or identifier.
1386
- * TypeScript renders as-is, e.g. `string`, `QueryParams`, `Partial<Config>`.
1351
+ * OpenAPI-style path template, for example, `'/pets/{petId}'`.
1387
1352
  */
1388
- variant: 'reference';
1353
+ path?: string;
1389
1354
  /**
1390
- * The full type name string, e.g. `'string'`, `'QueryParams'`, `'Partial<Config>'`.
1355
+ * Minimum string length.
1391
1356
  */
1392
- name: string;
1393
- } | {
1357
+ min?: number;
1358
+ /**
1359
+ * Maximum string length.
1360
+ */
1361
+ max?: number;
1362
+ };
1363
+ /**
1364
+ * Format-string schema for string-based formats that support length constraints.
1365
+ *
1366
+ * @example
1367
+ * ```ts
1368
+ * const uuidSchema: FormatStringSchemaNode = { kind: 'Schema', type: 'uuid', min: 36, max: 36 }
1369
+ * ```
1370
+ */
1371
+ type FormatStringSchemaNode = SchemaNodeBase & {
1394
1372
  /**
1395
- * Struct variant, an inline anonymous type grouping named fields.
1396
- * TypeScript renders as `{ key: Type; other?: OtherType }`.
1373
+ * Schema type discriminator.
1397
1374
  */
1398
- variant: 'struct';
1375
+ type: 'uuid' | 'email';
1399
1376
  /**
1400
- * Properties of the struct type.
1377
+ * Minimum string length.
1401
1378
  */
1402
- properties: Array<{
1403
- name: string;
1404
- optional: boolean;
1405
- type: ParamsTypeNode;
1406
- }>;
1407
- } | {
1379
+ min?: number;
1408
1380
  /**
1409
- * Member variant, a single named field accessed from a group type.
1410
- * TypeScript renders as `Base['key']`.
1381
+ * Maximum string length.
1411
1382
  */
1412
- variant: 'member';
1383
+ max?: number;
1384
+ };
1385
+ /**
1386
+ * IPv4 address schema node.
1387
+ *
1388
+ * @example
1389
+ * ```ts
1390
+ * const ipv4Schema: Ipv4SchemaNode = { kind: 'Schema', type: 'ipv4' }
1391
+ * ```
1392
+ */
1393
+ type Ipv4SchemaNode = SchemaNodeBase & {
1413
1394
  /**
1414
- * Base type name, e.g. `'DeletePetPathParams'`.
1395
+ * Schema type discriminator.
1415
1396
  */
1416
- base: string;
1397
+ type: 'ipv4';
1398
+ };
1399
+ /**
1400
+ * IPv6 address schema node.
1401
+ *
1402
+ * @example
1403
+ * ```ts
1404
+ * const ipv6Schema: Ipv6SchemaNode = { kind: 'Schema', type: 'ipv6' }
1405
+ * ```
1406
+ */
1407
+ type Ipv6SchemaNode = SchemaNodeBase & {
1417
1408
  /**
1418
- * The field name to access, e.g. `'petId'`.
1409
+ * Schema type discriminator.
1419
1410
  */
1420
- key: string;
1421
- });
1411
+ type: 'ipv6';
1412
+ };
1422
1413
  /**
1423
- * AST node for one function parameter.
1414
+ * Mapping from schema type literals to concrete schema node types.
1415
+ * Used by `narrowSchema`.
1416
+ */
1417
+ type SchemaNodeByType = {
1418
+ object: ObjectSchemaNode;
1419
+ array: ArraySchemaNode;
1420
+ tuple: ArraySchemaNode;
1421
+ union: UnionSchemaNode;
1422
+ intersection: IntersectionSchemaNode;
1423
+ enum: EnumSchemaNode;
1424
+ ref: RefSchemaNode;
1425
+ datetime: DatetimeSchemaNode;
1426
+ date: DateSchemaNode;
1427
+ time: TimeSchemaNode;
1428
+ string: StringSchemaNode;
1429
+ number: NumberSchemaNode;
1430
+ integer: NumberSchemaNode;
1431
+ bigint: NumberSchemaNode;
1432
+ boolean: ScalarSchemaNode;
1433
+ null: ScalarSchemaNode;
1434
+ any: ScalarSchemaNode;
1435
+ unknown: ScalarSchemaNode;
1436
+ void: ScalarSchemaNode;
1437
+ never: ScalarSchemaNode;
1438
+ uuid: FormatStringSchemaNode;
1439
+ email: FormatStringSchemaNode;
1440
+ url: UrlSchemaNode;
1441
+ ipv4: Ipv4SchemaNode;
1442
+ ipv6: Ipv6SchemaNode;
1443
+ blob: ScalarSchemaNode;
1444
+ };
1445
+ /**
1446
+ * Union of all schema node types.
1447
+ */
1448
+ type SchemaNode = ObjectSchemaNode | ArraySchemaNode | UnionSchemaNode | IntersectionSchemaNode | EnumSchemaNode | RefSchemaNode | DatetimeSchemaNode | DateSchemaNode | TimeSchemaNode | StringSchemaNode | NumberSchemaNode | UrlSchemaNode | FormatStringSchemaNode | Ipv4SchemaNode | Ipv6SchemaNode | ScalarSchemaNode;
1449
+ type CreateSchemaObjectInput = Omit<ObjectSchemaNode, 'kind' | 'properties' | 'primitive'> & {
1450
+ properties?: Array<PropertyNode>;
1451
+ primitive?: 'object';
1452
+ };
1453
+ type CreateSchemaInput = CreateSchemaObjectInput | DistributiveOmit<Exclude<SchemaNode, ObjectSchemaNode>, 'kind'>;
1454
+ type CreateSchemaOutput<T extends CreateSchemaInput> = InferSchemaNode<T> & {
1455
+ kind: 'Schema';
1456
+ };
1457
+ /**
1458
+ * Definition for the {@link SchemaNode}. Object schemas default `properties` to an
1459
+ * empty array, and `primitive` is inferred from `type` when not explicitly provided.
1460
+ */
1461
+ declare const schemaDef: NodeDef<SchemaNode, CreateSchemaInput>;
1462
+ /**
1463
+ * Creates a `SchemaNode`, narrowed to the variant of `props.type`.
1424
1464
  *
1425
- * @example Required parameter
1426
- * `name: Type`
1465
+ * @example
1466
+ * ```ts
1467
+ * const scalar = createSchema({ type: 'string' })
1468
+ * // { kind: 'Schema', type: 'string', primitive: 'string' }
1469
+ * ```
1427
1470
  *
1428
- * @example Optional parameter
1429
- * `name?: Type`
1471
+ * @example
1472
+ * ```ts
1473
+ * const object = createSchema({ type: 'object' })
1474
+ * // { kind: 'Schema', type: 'object', primitive: 'object', properties: [] }
1475
+ * ```
1476
+ */
1477
+ declare function createSchema<T extends CreateSchemaInput>(props: T): CreateSchemaOutput<T>;
1478
+ declare function createSchema(props: CreateSchemaInput): SchemaNode;
1479
+ //#endregion
1480
+ //#region src/nodes/content.d.ts
1481
+ /**
1482
+ * AST node representing one content-type entry of a request body or response.
1430
1483
  *
1431
- * @example Parameter with default value
1432
- * `name: Type = defaultValue`
1484
+ * One entry per content type declared in the spec (e.g. `application/json`,
1485
+ * `multipart/form-data`), each carrying its own body schema.
1433
1486
  *
1434
- * @example Rest parameter
1435
- * `...name: Type[]`
1487
+ * @example
1488
+ * ```ts
1489
+ * const content: ContentNode = {
1490
+ * kind: 'Content',
1491
+ * contentType: 'application/json',
1492
+ * schema: createSchema({ type: 'string' }),
1493
+ * }
1494
+ * ```
1436
1495
  */
1437
- type FunctionParameterNode = BaseNode & {
1496
+ type ContentNode = BaseNode & {
1438
1497
  /**
1439
1498
  * Node kind.
1440
1499
  */
1441
- kind: 'FunctionParameter';
1500
+ kind: 'Content';
1442
1501
  /**
1443
- * Parameter name in the generated signature.
1502
+ * The content type for this entry (e.g. `'application/json'`).
1444
1503
  */
1445
- name: string;
1504
+ contentType: string;
1446
1505
  /**
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']`
1506
+ * Body schema for this content type.
1458
1507
  */
1459
- type?: ParamsTypeNode;
1508
+ schema?: SchemaNode;
1460
1509
  /**
1461
- * When `true` the parameter is emitted as a rest parameter.
1462
- *
1463
- * @example Rest parameter
1464
- * `...name: Type[]`
1510
+ * Property keys to exclude from the generated type via `Omit<Type, Keys>`.
1511
+ * Set when a referenced schema has `readOnly`/`writeOnly` fields that should be omitted.
1465
1512
  */
1466
- rest?: boolean;
1467
- }
1513
+ keysToOmit?: Array<string> | null;
1514
+ };
1468
1515
  /**
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
- }
1516
+ * Loosely-typed content entry accepted by the builders, normalized into a {@link ContentNode}.
1517
+ */
1518
+ type UserContent = Omit<ContentNode, 'kind'>;
1476
1519
  /**
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`
1520
+ * Definition for the {@link ContentNode}.
1484
1521
  */
1485
- | {
1486
- optional?: false;
1487
- default?: string;
1488
- });
1522
+ declare const contentDef: NodeDef<ContentNode, UserContent>;
1523
+ //#endregion
1524
+ //#region src/nodes/file.d.ts
1525
+ /**
1526
+ * Supported file extensions.
1527
+ */
1528
+ type Extname = '.ts' | '.js' | '.tsx' | '.json' | `.${string}`;
1529
+ type ImportName = string | Array<string | {
1530
+ propertyName: string;
1531
+ name?: string;
1532
+ }>;
1489
1533
  /**
1490
- * AST node for a group of related function parameters treated as a single unit.
1534
+ * Represents a language-agnostic import/dependency declaration.
1491
1535
  *
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
1536
+ * @example Named import (TypeScript: `import { useState } from 'react'`)
1537
+ * ```ts
1538
+ * createImport({ name: ['useState'], path: 'react' })
1539
+ * ```
1496
1540
  *
1497
- * When `inline` is `true`, the group is spread as individual top-level parameters
1498
- * rather than wrapped in a single grouped construct.
1541
+ * @example Default import (TypeScript: `import React from 'react'`)
1542
+ * ```ts
1543
+ * createImport({ name: 'React', path: 'react' })
1544
+ * ```
1499
1545
  *
1500
- * @example Grouped destructuring
1501
- * `{ id, name }: { id: string; name: string } = {}`
1546
+ * @example Type-only import (TypeScript: `import type { FC } from 'react'`)
1547
+ * ```ts
1548
+ * createImport({ name: ['FC'], path: 'react', isTypeOnly: true })
1549
+ * ```
1502
1550
  *
1503
- * @example Inline (spread as individual parameters)
1504
- * `id: string, name: string`
1551
+ * @example Namespace import (TypeScript: `import * as React from 'react'`)
1552
+ * ```ts
1553
+ * createImport({ name: 'React', path: 'react', isNameSpace: true })
1554
+ * ```
1505
1555
  */
1506
- type ParameterGroupNode = BaseNode & {
1507
- /**
1508
- * Node kind.
1509
- */
1510
- kind: 'ParameterGroup';
1556
+ type ImportNode = BaseNode & {
1557
+ kind: 'Import';
1511
1558
  /**
1512
- * The individual parameters that form the group.
1513
- * Rendered as a destructured object or spread inline when `inline` is `true`.
1559
+ * Import name(s) to be used.
1560
+ * @example ['useState']
1561
+ * @example 'React'
1514
1562
  */
1515
- properties: Array<FunctionParameterNode>;
1563
+ name: ImportName;
1516
1564
  /**
1517
- * Optional explicit type annotation for the whole group.
1518
- * When absent, printers auto-compute it from `properties`.
1565
+ * Path for the import.
1566
+ * @example '@kubb/core'
1519
1567
  */
1520
- type?: ParamsTypeNode;
1568
+ path: string;
1521
1569
  /**
1522
- * When `true`, `properties` are emitted as individual top-level parameters instead of
1523
- * being wrapped in a single grouped construct.
1524
- *
1570
+ * Add type-only import prefix.
1571
+ * - `true` generates `import type { Type } from './path'`
1572
+ * - `false` generates `import { Type } from './path'`
1525
1573
  * @default false
1526
1574
  */
1527
- inline?: boolean;
1528
- /**
1529
- * Whether the group as a whole is optional.
1530
- * If omitted, printers infer this from child properties.
1531
- */
1532
- optional?: boolean;
1533
- /**
1534
- * Default value for the group, written verbatim after `=`.
1535
- * Commonly `'{}'` to allow omitting the argument entirely.
1536
- */
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 & {
1575
+ isTypeOnly?: boolean | null;
1552
1576
  /**
1553
- * Node kind.
1577
+ * Import entire module as namespace.
1578
+ * - `true` generates `import * as Name from './path'`
1579
+ * - `false` generates standard import
1580
+ * @default false
1554
1581
  */
1555
- kind: 'FunctionParameters';
1582
+ isNameSpace?: boolean | null;
1556
1583
  /**
1557
- * Ordered parameter nodes.
1584
+ * When set, the import path is resolved relative to this root.
1558
1585
  */
1559
- params: ReadonlyArray<FunctionParameterNode | ParameterGroupNode>;
1586
+ root?: string | null;
1560
1587
  };
1561
1588
  /**
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>`.
1589
+ * Represents a language-agnostic export/public API declaration.
1573
1590
  *
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.
1591
+ * @example Named export (TypeScript: `export { Pets } from './Pets'`)
1592
+ * ```ts
1593
+ * createExport({ name: ['Pets'], path: './Pets' })
1594
+ * ```
1577
1595
  *
1578
- * @example
1596
+ * @example Type-only export (TypeScript: `export type { Pet } from './Pet'`)
1579
1597
  * ```ts
1580
- * type Eager = Streamable<number> // Array<number>
1581
- * type Lazy = Streamable<number, true> // AsyncIterable<number>
1598
+ * createExport({ name: ['Pet'], path: './Pet', isTypeOnly: true })
1582
1599
  * ```
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.
1590
1600
  *
1591
- * @example
1601
+ * @example Wildcard export (TypeScript: `export * from './utils'`)
1592
1602
  * ```ts
1593
- * const param: ParameterNode = {
1594
- * kind: 'Parameter',
1595
- * name: 'petId',
1596
- * in: 'path',
1597
- * schema: createSchema({ type: 'string' }),
1598
- * required: true,
1599
- * }
1603
+ * createExport({ path: './utils' })
1604
+ * ```
1605
+ *
1606
+ * @example Namespace alias (TypeScript: `export * as utils from './utils'`)
1607
+ * ```ts
1608
+ * createExport({ name: 'utils', path: './utils', asAlias: true })
1600
1609
  * ```
1601
1610
  */
1602
- type ParameterNode = BaseNode & {
1603
- /**
1604
- * Node kind.
1605
- */
1606
- kind: 'Parameter';
1611
+ type ExportNode = BaseNode & {
1612
+ kind: 'Export';
1607
1613
  /**
1608
- * Parameter name.
1614
+ * Export name(s) to be used. When omitted, generates a wildcard export.
1615
+ * @example ['useState']
1616
+ * @example 'React'
1609
1617
  */
1610
- name: string;
1618
+ name?: string | Array<string> | null;
1611
1619
  /**
1612
- * Parameter location (`path`, `query`, `header`, or `cookie`).
1620
+ * Path for the export.
1621
+ * @example '@kubb/core'
1613
1622
  */
1614
- in: ParameterLocation;
1623
+ path: string;
1615
1624
  /**
1616
- * Parameter schema.
1625
+ * Add type-only export prefix.
1626
+ * - `true` generates `export type { Type } from './path'`
1627
+ * - `false` generates `export { Type } from './path'`
1628
+ * @default false
1617
1629
  */
1618
- schema: SchemaNode;
1630
+ isTypeOnly?: boolean | null;
1619
1631
  /**
1620
- * Whether the parameter is required.
1632
+ * Export as an aliased namespace.
1633
+ * - `true` generates `export * as aliasName from './path'`
1634
+ * - `false` generates a standard export
1635
+ * @default false
1621
1636
  */
1622
- required: boolean;
1637
+ asAlias?: boolean | null;
1623
1638
  };
1624
- //#endregion
1625
- //#region src/nodes/requestBody.d.ts
1626
1639
  /**
1627
- * AST node representing an operation request body.
1640
+ * Represents a fragment of source code within a file.
1628
1641
  *
1629
- * Body schemas live exclusively inside the `content` array (one entry per content type),
1630
- * mirroring {@link ResponseNode}.
1642
+ * @example Named exportable source
1643
+ * ```ts
1644
+ * createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true, isIndexable: true })
1645
+ * ```
1631
1646
  *
1632
- * @example
1647
+ * @example Inline unnamed code block
1633
1648
  * ```ts
1634
- * const requestBody: RequestBodyNode = {
1635
- * kind: 'RequestBody',
1636
- * required: true,
1637
- * content: [{ kind: 'Content', contentType: 'application/json', schema: createSchema({ type: 'string' }) }],
1638
- * }
1649
+ * createSource({ nodes: [createText('const x = 1')] })
1639
1650
  * ```
1640
1651
  */
1641
- type RequestBodyNode = BaseNode & {
1652
+ type SourceNode = BaseNode & {
1653
+ kind: 'Source';
1642
1654
  /**
1643
- * Node kind.
1655
+ * Optional name identifying this source (used for deduplication and barrel generation).
1644
1656
  */
1645
- kind: 'RequestBody';
1657
+ name?: string | null;
1646
1658
  /**
1647
- * Human-readable request body description.
1659
+ * Mark this source as a type-only export.
1660
+ * @default false
1648
1661
  */
1649
- description?: string;
1662
+ isTypeOnly?: boolean | null;
1650
1663
  /**
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.
1664
+ * Include `export` keyword in the generated source.
1665
+ * @default false
1653
1666
  */
1654
- required?: boolean;
1667
+ isExportable?: boolean | null;
1655
1668
  /**
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`).
1669
+ * Include this source in barrel/index file generation.
1670
+ * @default false
1662
1671
  */
1663
- content?: Array<ContentNode>;
1672
+ isIndexable?: boolean | null;
1673
+ /**
1674
+ * Structured child nodes representing the content of this source fragment, in DOM order.
1675
+ * Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
1676
+ */
1677
+ nodes?: Array<CodeNode>;
1664
1678
  };
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
1679
  /**
1687
- * AST node representing one operation response variant.
1680
+ * Represents a fully resolved file in the AST.
1688
1681
  *
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`.
1682
+ * Created via `createFile()`, which computes the `id`, `name`, and `extname` from the input
1683
+ * and deduplicates `imports`, `exports`, and `sources`.
1692
1684
  *
1693
1685
  * @example
1694
1686
  * ```ts
1695
- * const response: ResponseNode = {
1696
- * kind: 'Response',
1697
- * statusCode: '200',
1698
- * content: [{ contentType: 'application/json', schema: createSchema({ type: 'string' }) }],
1699
- * }
1687
+ * const file = createFile({
1688
+ * baseName: 'petStore.ts',
1689
+ * path: 'src/models/petStore.ts',
1690
+ * sources: [createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true })],
1691
+ * imports: [createImport({ name: ['z'], path: 'zod' })],
1692
+ * exports: [createExport({ name: ['Pet'], path: './petStore' })],
1693
+ * })
1694
+ * // file.id = SHA256 hash of the path
1695
+ * // file.name = 'petStore'
1696
+ * // file.extname = '.ts'
1700
1697
  * ```
1701
1698
  */
1702
- type ResponseNode = BaseNode & {
1699
+ type FileNode<TMeta extends object = object> = BaseNode & {
1700
+ kind: 'File';
1703
1701
  /**
1704
- * Node kind.
1702
+ * Unique identifier derived from a SHA256 hash of the file path. Computed
1703
+ * by `createFile`; callers do not need to provide it.
1705
1704
  */
1706
- kind: 'Response';
1705
+ id: string;
1707
1706
  /**
1708
- * HTTP status code or `'default'` for a fallback response.
1707
+ * File name without extension, derived from `baseName`.
1708
+ * @link https://nodejs.org/api/path.html#pathformatpathobject
1709
1709
  */
1710
- statusCode: StatusCode;
1710
+ name: string;
1711
1711
  /**
1712
- * Optional response description.
1712
+ * File base name, including extension.
1713
+ * Based on UNIX basename: `${name}${extname}`
1714
+ * @link https://nodejs.org/api/path.html#pathbasenamepath-suffix
1713
1715
  */
1714
- description?: string;
1716
+ baseName: `${string}.${string}`;
1715
1717
  /**
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
- * ```
1718
+ * Full qualified path to the file.
1729
1719
  */
1730
- content?: Array<ContentNode>;
1731
- };
1732
- //#endregion
1733
- //#region src/nodes/operation.d.ts
1734
- type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'TRACE';
1735
- /**
1736
- * Transport an operation belongs to.
1737
- */
1738
- type OperationProtocol = 'http';
1739
- /**
1740
- * Fields shared by every operation, regardless of transport.
1741
- */
1742
- type OperationNodeBase = BaseNode & {
1720
+ path: string;
1743
1721
  /**
1744
- * Node kind.
1722
+ * File extension extracted from `baseName`.
1745
1723
  */
1746
- kind: 'Operation';
1724
+ extname: Extname;
1747
1725
  /**
1748
- * Operation identifier, usually from OpenAPI `operationId`.
1726
+ * Deduplicated list of source code fragments.
1749
1727
  */
1750
- operationId: string;
1728
+ sources: Array<SourceNode>;
1751
1729
  /**
1752
- * Group labels for the operation.
1753
- * Usually copied from OpenAPI `tags`.
1730
+ * Deduplicated list of import declarations.
1754
1731
  */
1755
- tags: Array<string>;
1732
+ imports: Array<ImportNode>;
1756
1733
  /**
1757
- * Short one-line operation summary.
1734
+ * Deduplicated list of export declarations.
1758
1735
  */
1759
- summary?: string;
1736
+ exports: Array<ExportNode>;
1760
1737
  /**
1761
- * Full operation description.
1738
+ * Optional metadata attached to this file (used by plugins for barrel generation etc.).
1762
1739
  */
1763
- description?: string;
1740
+ meta?: TMeta;
1764
1741
  /**
1765
- * Marks the operation as deprecated.
1742
+ * Optional banner prepended to the generated file content.
1743
+ * Accepts `null` so `resolver.resolveBanner()` results can be passed directly.
1766
1744
  */
1767
- deprecated?: boolean;
1745
+ banner?: string | null;
1768
1746
  /**
1769
- * Parameters that could be used, we have QueryParams, PathParams, HeaderParams and CookieParams
1747
+ * Optional footer appended to the generated file content.
1748
+ * Accepts `null` so `resolver.resolveFooter()` results can be passed directly.
1770
1749
  */
1771
- parameters: Array<ParameterNode>;
1750
+ footer?: string | null;
1751
+ };
1752
+ /**
1753
+ * Definition for the {@link ImportNode}.
1754
+ */
1755
+ declare const importDef: NodeDef<ImportNode, Omit<ImportNode, "kind">>;
1756
+ /**
1757
+ * Creates an `ImportNode` representing a language-agnostic import/dependency declaration.
1758
+ *
1759
+ * @example Named import
1760
+ * ```ts
1761
+ * createImport({ name: ['useState'], path: 'react' })
1762
+ * // import { useState } from 'react'
1763
+ * ```
1764
+ */
1765
+ declare const createImport: (input: Omit<ImportNode, "kind">) => ImportNode;
1766
+ /**
1767
+ * Definition for the {@link ExportNode}.
1768
+ */
1769
+ declare const exportDef: NodeDef<ExportNode, Omit<ExportNode, "kind">>;
1770
+ /**
1771
+ * Creates an `ExportNode` representing a language-agnostic export/public API declaration.
1772
+ *
1773
+ * @example Named export
1774
+ * ```ts
1775
+ * createExport({ name: ['Pet'], path: './Pet' })
1776
+ * // export { Pet } from './Pet'
1777
+ * ```
1778
+ */
1779
+ declare const createExport: (input: Omit<ExportNode, "kind">) => ExportNode;
1780
+ /**
1781
+ * Definition for the {@link SourceNode}.
1782
+ */
1783
+ declare const sourceDef: NodeDef<SourceNode, Omit<SourceNode, "kind">>;
1784
+ /**
1785
+ * Creates a `SourceNode` representing a fragment of source code within a file.
1786
+ *
1787
+ * @example
1788
+ * ```ts
1789
+ * createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true })
1790
+ * ```
1791
+ */
1792
+ declare const createSource: (input: Omit<SourceNode, "kind">) => SourceNode;
1793
+ /**
1794
+ * Definition for the {@link FileNode}. The fully resolved builder lives in
1795
+ * `createFile`, so this definition only supplies the guard.
1796
+ */
1797
+ declare const fileDef: NodeDef<FileNode<object>, Omit<FileNode<object>, "kind">>;
1798
+ //#endregion
1799
+ //#region src/nodes/function.d.ts
1800
+ /**
1801
+ * A language-agnostic type expression used as a function parameter type annotation.
1802
+ *
1803
+ * - a plain `string` is a type reference rendered as-is, e.g. `'string'`, `'QueryParams'`, `'Partial<Config>'`
1804
+ * - a {@link TypeLiteralNode} is an inline anonymous type, e.g. `{ petId: string; name?: string }`
1805
+ * - an {@link IndexedAccessTypeNode} is a single field accessed from a named type, e.g. `PathParams['petId']`
1806
+ */
1807
+ type TypeExpression = string | TypeLiteralNode | IndexedAccessTypeNode;
1808
+ /**
1809
+ * AST node for an inline anonymous object type grouping named fields.
1810
+ * TypeScript renders as `{ key: Type; other?: OtherType }`.
1811
+ *
1812
+ * @example
1813
+ * ```ts
1814
+ * createTypeLiteral({ members: [{ name: 'petId', type: 'string', optional: false }] })
1815
+ * // { petId: string }
1816
+ * ```
1817
+ */
1818
+ type TypeLiteralNode = BaseNode & {
1772
1819
  /**
1773
- * Request body for the operation.
1820
+ * Node kind.
1774
1821
  */
1775
- requestBody?: RequestBodyNode;
1822
+ kind: 'TypeLiteral';
1776
1823
  /**
1777
- * Operation responses.
1824
+ * Members of the object type, rendered in order.
1778
1825
  */
1779
- responses: Array<ResponseNode>;
1826
+ members: Array<{
1827
+ /**
1828
+ * Member key.
1829
+ */
1830
+ name: string;
1831
+ /**
1832
+ * Member type expression.
1833
+ */
1834
+ type: TypeExpression;
1835
+ /**
1836
+ * Whether the member is optional, rendered with `?`.
1837
+ */
1838
+ optional?: boolean;
1839
+ }>;
1780
1840
  };
1781
1841
  /**
1782
- * Operation served over HTTP/REST (OpenAPI). `method` and `path` are guaranteed.
1842
+ * AST node for a single field accessed from a named group type.
1843
+ * TypeScript renders as `objectType['indexType']`.
1783
1844
  *
1784
1845
  * @example
1785
1846
  * ```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: [],
1795
- * }
1847
+ * createIndexedAccessType({ objectType: 'GetPetPathParams', indexType: 'petId' })
1848
+ * // GetPetPathParams['petId']
1796
1849
  * ```
1797
1850
  */
1798
- type HttpOperationNode = OperationNodeBase & {
1851
+ type IndexedAccessTypeNode = BaseNode & {
1799
1852
  /**
1800
- * Transport the operation belongs to.
1853
+ * Node kind.
1801
1854
  */
1802
- protocol?: 'http';
1855
+ kind: 'IndexedAccessType';
1803
1856
  /**
1804
- * HTTP method like `'GET'`.
1857
+ * Name of the type being indexed, e.g. `'GetPetPathParams'`.
1805
1858
  */
1806
- method: HttpMethod;
1859
+ objectType: string;
1807
1860
  /**
1808
- * OpenAPI-style path string, for example `/pets/{petId}`, with `{param}` notation preserved.
1861
+ * Field key to access, e.g. `'petId'`.
1809
1862
  */
1810
- path: string;
1863
+ indexType: string;
1811
1864
  };
1812
1865
  /**
1813
- * Operation for a non-HTTP transport. HTTP-only fields are forbidden.
1866
+ * AST node for an object destructuring binding, used as the name of a grouped function parameter.
1867
+ * TypeScript renders as `{ id, name }` or `{ id: renamed }` when `propertyName` differs.
1868
+ *
1869
+ * @example
1870
+ * ```ts
1871
+ * createObjectBindingPattern({ elements: [{ name: 'id' }, { name: 'name' }] })
1872
+ * // { id, name }
1873
+ * ```
1814
1874
  */
1815
- type GenericOperationNode = OperationNodeBase & {
1875
+ type ObjectBindingPatternNode = BaseNode & {
1816
1876
  /**
1817
- * Transport the operation belongs to.
1877
+ * Node kind.
1818
1878
  */
1819
- protocol?: Exclude<OperationProtocol, 'http'>;
1820
- method?: never;
1821
- path?: never;
1879
+ kind: 'ObjectBindingPattern';
1880
+ /**
1881
+ * Bound elements, rendered in order.
1882
+ */
1883
+ elements: Array<{
1884
+ /**
1885
+ * Local binding name.
1886
+ */
1887
+ name: string;
1888
+ /**
1889
+ * Source key when it differs from the binding name, rendered as `propertyName: name`.
1890
+ */
1891
+ propertyName?: string;
1892
+ }>;
1822
1893
  };
1823
1894
  /**
1824
- * AST node representing one API operation.
1895
+ * AST node for one function parameter.
1825
1896
  *
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.
1897
+ * A simple parameter has a `string` name. A destructured group has an
1898
+ * {@link ObjectBindingPatternNode} name paired with a {@link TypeLiteralNode} type.
1835
1899
  *
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.
1900
+ * @example Required parameter
1901
+ * `name: Type`
1839
1902
  *
1840
- * @example
1841
- * ```ts
1842
- * const meta: InputMeta = { title: 'Pet Store', version: '1.0.0', baseURL: 'https://petstore.swagger.io/v2', circularNames: [], enumNames: [] }
1843
- * ```
1903
+ * @example Optional parameter
1904
+ * `name?: Type`
1905
+ *
1906
+ * @example Parameter with default value
1907
+ * `name: Type = defaultValue`
1908
+ *
1909
+ * @example Rest parameter
1910
+ * `...name: Type[]`
1911
+ *
1912
+ * @example Destructured group
1913
+ * `{ id, name? }: { id: string; name?: string } = {}`
1844
1914
  */
1845
- type InputMeta = {
1915
+ type FunctionParameterNode = BaseNode & {
1846
1916
  /**
1847
- * API title from `info.title` in the source document.
1917
+ * Node kind.
1848
1918
  */
1849
- title?: string;
1919
+ kind: 'FunctionParameter';
1850
1920
  /**
1851
- * API description from `info.description` in the source document.
1921
+ * Parameter name, or an {@link ObjectBindingPatternNode} for a destructured group.
1852
1922
  */
1853
- description?: string;
1923
+ name: string | ObjectBindingPatternNode;
1854
1924
  /**
1855
- * API version string from `info.version` in the source document.
1925
+ * Type annotation as a {@link TypeExpression}. Omit for untyped output.
1856
1926
  */
1857
- version?: string;
1927
+ type?: TypeExpression;
1858
1928
  /**
1859
- * Resolved base URL from the first matching server entry in the source document.
1929
+ * Whether the parameter is optional, rendered with `?`.
1860
1930
  */
1861
- baseURL?: string | null;
1931
+ optional?: boolean;
1862
1932
  /**
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
- * ```
1933
+ * Default value, written verbatim after `=`. Commonly `'{}'` for a destructured group.
1875
1934
  */
1876
- circularNames: ReadonlyArray<string>;
1935
+ default?: string;
1877
1936
  /**
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)`
1937
+ * When `true` the parameter is emitted as a rest parameter, e.g. `...name: Type[]`.
1888
1938
  */
1889
- enumNames: ReadonlyArray<string>;
1939
+ rest?: boolean;
1890
1940
  };
1891
1941
  /**
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.
1942
+ * AST node for a complete function parameter list.
1894
1943
  *
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.
1944
+ * Printers are responsible for sorting (`required` `optional` `defaulted`).
1945
+ * Nodes are plain immutable data.
1946
+ *
1947
+ * Renders differently depending on the output mode:
1948
+ * - `declaration` → `(id: string, config: Config = {})` function declaration parameters
1949
+ * - `call` → `(id, { method, url })` function call arguments
1950
+ */
1951
+ type FunctionParametersNode = BaseNode & {
1952
+ /**
1953
+ * Node kind.
1954
+ */
1955
+ kind: 'FunctionParameters';
1956
+ /**
1957
+ * Ordered parameter nodes.
1958
+ */
1959
+ params: ReadonlyArray<FunctionParameterNode>;
1960
+ };
1961
+ /**
1962
+ * Union of all function-parameter AST node variants used by the function-parameter printer.
1963
+ */
1964
+ type FunctionParamNode = FunctionParameterNode | FunctionParametersNode | TypeLiteralNode | IndexedAccessTypeNode | ObjectBindingPatternNode;
1965
+ /**
1966
+ * Handler map keys, one per `FunctionParamNode` kind.
1967
+ */
1968
+ type FunctionNodeType = 'functionParameter' | 'functionParameters' | 'typeLiteral' | 'indexedAccessType' | 'objectBindingPattern';
1969
+ /**
1970
+ * Definition for the {@link TypeLiteralNode}.
1971
+ */
1972
+ declare const typeLiteralDef: NodeDef<TypeLiteralNode, Pick<TypeLiteralNode, "members">>;
1973
+ /**
1974
+ * Creates a {@link TypeLiteralNode} representing an inline anonymous object type.
1898
1975
  *
1899
1976
  * @example
1900
1977
  * ```ts
1901
- * const input: InputNode = {
1902
- * kind: 'Input',
1903
- * schemas: [],
1904
- * operations: [],
1905
- * meta: { circularNames: [], enumNames: [] },
1906
- * }
1978
+ * createTypeLiteral({ members: [{ name: 'petId', type: 'string', optional: false }] })
1979
+ * // { petId: string }
1980
+ * ```
1981
+ */
1982
+ declare const createTypeLiteral: (input: Pick<TypeLiteralNode, "members">) => TypeLiteralNode;
1983
+ /**
1984
+ * Definition for the {@link IndexedAccessTypeNode}.
1985
+ */
1986
+ declare const indexedAccessTypeDef: NodeDef<IndexedAccessTypeNode, Omit<IndexedAccessTypeNode, "kind">>;
1987
+ /**
1988
+ * Creates an {@link IndexedAccessTypeNode} representing a single field accessed from a named type.
1989
+ *
1990
+ * @example
1991
+ * ```ts
1992
+ * createIndexedAccessType({ objectType: 'DeletePetPathParams', indexType: 'petId' })
1993
+ * // DeletePetPathParams['petId']
1907
1994
  * ```
1995
+ */
1996
+ declare const createIndexedAccessType: (input: Omit<IndexedAccessTypeNode, "kind">) => IndexedAccessTypeNode;
1997
+ /**
1998
+ * Definition for the {@link ObjectBindingPatternNode}.
1999
+ */
2000
+ declare const objectBindingPatternDef: NodeDef<ObjectBindingPatternNode, Pick<ObjectBindingPatternNode, "elements">>;
2001
+ /**
2002
+ * Creates an {@link ObjectBindingPatternNode} for a destructured parameter binding.
1908
2003
  *
1909
- * @example Streaming variant for large specs
2004
+ * @example
1910
2005
  * ```ts
1911
- * for await (const schema of inputNode.schemas) {
1912
- * // only this one SchemaNode is live here. Previous ones are GC-eligible
1913
- * }
2006
+ * createObjectBindingPattern({ elements: [{ name: 'id' }, { name: 'name' }] })
2007
+ * // { id, name }
1914
2008
  * ```
1915
2009
  */
1916
- type InputNode<Stream extends boolean = false> = BaseNode & {
1917
- /**
1918
- * Node kind.
1919
- */
1920
- kind: 'Input';
1921
- /**
1922
- * All schema nodes in the document.
1923
- */
1924
- schemas: Streamable<SchemaNode, Stream>;
1925
- /**
1926
- * All operation nodes in the document.
1927
- */
1928
- operations: Streamable<OperationNode, Stream>;
1929
- } & (Stream extends true ? {
1930
- meta?: InputMeta;
1931
- } : {
1932
- meta: InputMeta;
1933
- });
2010
+ declare const createObjectBindingPattern: (input: Pick<ObjectBindingPatternNode, "elements">) => ObjectBindingPatternNode;
2011
+ /**
2012
+ * Plain property descriptor for a destructured group built by {@link createFunctionParameter}.
2013
+ */
2014
+ type FunctionParameterProperty = {
2015
+ name: string;
2016
+ type: TypeExpression;
2017
+ optional?: boolean;
2018
+ };
2019
+ type FunctionParameterInput = {
2020
+ name: string;
2021
+ type?: TypeExpression;
2022
+ optional?: boolean;
2023
+ default?: string;
2024
+ rest?: boolean;
2025
+ } | {
2026
+ properties: Array<FunctionParameterProperty>;
2027
+ optional?: boolean;
2028
+ default?: string;
2029
+ };
2030
+ /**
2031
+ * Definition for the {@link FunctionParameterNode}. `optional` defaults to `false`.
2032
+ * Passing `properties` builds a destructured group: an {@link ObjectBindingPatternNode} name
2033
+ * paired with a {@link TypeLiteralNode} type.
2034
+ */
2035
+ declare const functionParameterDef: NodeDef<FunctionParameterNode, FunctionParameterInput>;
2036
+ /**
2037
+ * Creates a `FunctionParameterNode`. `optional` defaults to `false`.
2038
+ *
2039
+ * @example Optional param
2040
+ * ```ts
2041
+ * createFunctionParameter({ name: 'params', type: 'QueryParams', optional: true })
2042
+ * // → params?: QueryParams
2043
+ * ```
2044
+ *
2045
+ * @example Destructured group
2046
+ * ```ts
2047
+ * createFunctionParameter({ properties: [{ name: 'id', type: 'string' }, { name: 'name', type: 'string', optional: true }], default: '{}' })
2048
+ * // → { id, name }: { id: string; name?: string } = {}
2049
+ * ```
2050
+ */
2051
+ declare const createFunctionParameter: (input: FunctionParameterInput) => FunctionParameterNode;
2052
+ /**
2053
+ * Definition for the {@link FunctionParametersNode}.
2054
+ */
2055
+ declare const functionParametersDef: NodeDef<FunctionParametersNode, Partial<Omit<FunctionParametersNode, "kind">>>;
2056
+ /**
2057
+ * Creates a `FunctionParametersNode` from an ordered list of parameters.
2058
+ *
2059
+ * @example
2060
+ * ```ts
2061
+ * const empty = createFunctionParameters()
2062
+ * // { kind: 'FunctionParameters', params: [] }
2063
+ * ```
2064
+ */
2065
+ declare function createFunctionParameters(props?: Partial<Omit<FunctionParametersNode, 'kind'>>): FunctionParametersNode;
1934
2066
  //#endregion
1935
- //#region src/nodes/output.d.ts
2067
+ //#region ../../internals/utils/src/promise.d.ts
1936
2068
  /**
1937
- * Output AST node that groups all generated file output for one API document.
2069
+ * Container that switches between an eager `Array<T>` and a lazy `AsyncIterable<T>`.
1938
2070
  *
1939
- * Produced by generators and consumed by the build pipeline to write files.
2071
+ * `Array<T>` by default. With `Stream` set to `true` it becomes `AsyncIterable<T>`, so large
2072
+ * collections can be produced lazily without holding every item in memory. Pairs with
2073
+ * {@link arrayToAsyncIterable}, which lifts a plain array into the streaming form.
1940
2074
  *
1941
2075
  * @example
1942
2076
  * ```ts
1943
- * const output: OutputNode = {
1944
- * kind: 'Output',
1945
- * files: [],
2077
+ * type Eager = Streamable<number> // Array<number>
2078
+ * type Lazy = Streamable<number, true> // AsyncIterable<number>
2079
+ * ```
2080
+ */
2081
+ type Streamable<T, Stream extends boolean = false> = Stream extends true ? AsyncIterable<T> : Array<T>;
2082
+ //#endregion
2083
+ //#region src/nodes/parameter.d.ts
2084
+ type ParameterLocation = 'path' | 'query' | 'header' | 'cookie';
2085
+ /**
2086
+ * AST node representing one operation parameter.
2087
+ *
2088
+ * @example
2089
+ * ```ts
2090
+ * const param: ParameterNode = {
2091
+ * kind: 'Parameter',
2092
+ * name: 'petId',
2093
+ * in: 'path',
2094
+ * schema: createSchema({ type: 'string' }),
2095
+ * required: true,
1946
2096
  * }
1947
2097
  * ```
1948
2098
  */
1949
- type OutputNode = BaseNode & {
2099
+ type ParameterNode = BaseNode & {
1950
2100
  /**
1951
2101
  * Node kind.
1952
2102
  */
1953
- kind: 'Output';
2103
+ kind: 'Parameter';
1954
2104
  /**
1955
- * Generated file nodes.
2105
+ * Parameter name.
1956
2106
  */
1957
- files: Array<FileNode>;
2107
+ name: string;
2108
+ /**
2109
+ * Parameter location (`path`, `query`, `header`, or `cookie`).
2110
+ */
2111
+ in: ParameterLocation;
2112
+ /**
2113
+ * Parameter schema.
2114
+ */
2115
+ schema: SchemaNode;
2116
+ /**
2117
+ * Whether the parameter is required.
2118
+ */
2119
+ required: boolean;
1958
2120
  };
1959
- //#endregion
1960
- //#region src/nodes/index.d.ts
2121
+ type UserParameterNode = Pick<ParameterNode, 'name' | 'in' | 'schema'> & Partial<Omit<ParameterNode, 'kind' | 'name' | 'in' | 'schema'>>;
1961
2122
  /**
1962
- * Union of all AST node types.
1963
- *
1964
- * This lets TypeScript narrow types in `switch (node.kind)` blocks.
2123
+ * Definition for the {@link ParameterNode}. `required` defaults to `false` and the
2124
+ * schema's `optional`/`nullish` flags are kept in sync with it.
2125
+ */
2126
+ declare const parameterDef: NodeDef<ParameterNode, UserParameterNode>;
2127
+ /**
2128
+ * Creates a `ParameterNode`.
1965
2129
  *
1966
2130
  * @example
1967
2131
  * ```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
- * }
2132
+ * const param = createParameter({
2133
+ * name: 'petId',
2134
+ * in: 'path',
2135
+ * required: true,
2136
+ * schema: createSchema({ type: 'string' }),
2137
+ * })
1978
2138
  * ```
1979
2139
  */
1980
- type Node = InputNode | OutputNode | OperationNode | SchemaNode | PropertyNode | ParameterNode | ResponseNode | RequestBodyNode | ContentNode | FunctionParamNode | FileNode | ImportNode | ExportNode | SourceNode | ConstNode | TypeNode | ParamsTypeNode | FunctionNode | ArrowFunctionNode;
2140
+ declare const createParameter: (input: UserParameterNode) => ParameterNode;
1981
2141
  //#endregion
1982
- //#region src/dedupe.d.ts
2142
+ //#region src/nodes/requestBody.d.ts
1983
2143
  /**
1984
- * A canonical destination for a deduplicated shape: the shared schema name and
1985
- * the synthetic `$ref` path that points at it.
2144
+ * AST node representing an operation request body.
2145
+ *
2146
+ * Body schemas live exclusively inside the `content` array (one entry per content type),
2147
+ * mirroring {@link ResponseNode}.
2148
+ *
2149
+ * @example
2150
+ * ```ts
2151
+ * const requestBody: RequestBodyNode = {
2152
+ * kind: 'RequestBody',
2153
+ * required: true,
2154
+ * content: [{ kind: 'Content', contentType: 'application/json', schema: createSchema({ type: 'string' }) }],
2155
+ * }
2156
+ * ```
1986
2157
  */
1987
- type DedupeCanonical = {
1988
- /**
1989
- * Canonical schema name every duplicate occurrence refers to.
1990
- */
1991
- name: string;
2158
+ type RequestBodyNode = BaseNode & {
1992
2159
  /**
1993
- * `$ref` path stored on the generated `ref` nodes (for example `#/components/schemas/Status`).
2160
+ * Node kind.
1994
2161
  */
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 = {
2162
+ kind: 'RequestBody';
2003
2163
  /**
2004
- * Maps a structural signature to the canonical schema that represents it.
2164
+ * Human-readable request body description.
2005
2165
  */
2006
- canonicalBySignature: Map<string, DedupeCanonical>;
2166
+ description?: string;
2007
2167
  /**
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.
2168
+ * Whether the request body is required (`requestBody.required: true` in the spec).
2169
+ * When `false` or absent, the generated `data` parameter should be optional.
2010
2170
  */
2011
- aliasNames: Map<string, DedupeCanonical>;
2171
+ required?: boolean;
2012
2172
  /**
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.
2173
+ * All available content type entries for this request body.
2174
+ *
2175
+ * When the adapter `contentType` option is set, this array contains exactly one entry for
2176
+ * that content type. Otherwise it contains one entry per content type declared in the spec,
2177
+ * so that plugins can generate code for every variant (e.g. separate hooks for
2178
+ * `application/json` and `multipart/form-data`).
2015
2179
  */
2016
- hoisted: Array<SchemaNode>;
2180
+ content?: Array<ContentNode>;
2017
2181
  };
2018
2182
  /**
2019
- * The lookups {@link applyDedupe} needs from a {@link DedupePlan}.
2183
+ * Loosely-typed request body accepted by `createOperation`, normalized into a {@link RequestBodyNode}.
2020
2184
  */
2021
- type DedupeLookups = Pick<DedupePlan, 'canonicalBySignature' | 'aliasNames'>;
2185
+ type UserRequestBody = Omit<RequestBodyNode, 'kind' | 'content'> & {
2186
+ content?: Array<UserContent>;
2187
+ };
2022
2188
  /**
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.
2189
+ * Definition for the {@link RequestBodyNode}, normalizing each content entry into a `ContentNode`.
2025
2190
  */
2026
- type BuildDedupePlanOptions = {
2191
+ declare const requestBodyDef: NodeDef<RequestBodyNode, UserRequestBody>;
2192
+ //#endregion
2193
+ //#region src/nodes/http.d.ts
2194
+ /**
2195
+ * All supported HTTP status code literals as strings, as used in API specs
2196
+ * (for example, `"200"` and `"404"`).
2197
+ */
2198
+ 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';
2199
+ /**
2200
+ * Response status code literal used by operations.
2201
+ *
2202
+ * Includes specific HTTP status code strings and `"default"` for catch-all responses.
2203
+ *
2204
+ * @example
2205
+ * ```ts
2206
+ * const status: StatusCode = '200'
2207
+ * const fallback: StatusCode = 'default'
2208
+ * ```
2209
+ */
2210
+ type StatusCode = HttpStatusCode | 'default';
2211
+ //#endregion
2212
+ //#region src/nodes/response.d.ts
2213
+ /**
2214
+ * AST node representing one operation response variant.
2215
+ *
2216
+ * Mirrors {@link OperationNode.requestBody}: the response body schemas live exclusively inside
2217
+ * the `content` array (one entry per content type), so the same schema is never duplicated at the
2218
+ * node root and inside `content`.
2219
+ *
2220
+ * @example
2221
+ * ```ts
2222
+ * const response: ResponseNode = {
2223
+ * kind: 'Response',
2224
+ * statusCode: '200',
2225
+ * content: [{ contentType: 'application/json', schema: createSchema({ type: 'string' }) }],
2226
+ * }
2227
+ * ```
2228
+ */
2229
+ type ResponseNode = BaseNode & {
2027
2230
  /**
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).
2231
+ * Node kind.
2031
2232
  */
2032
- isCandidate: (node: SchemaNode) => boolean;
2233
+ kind: 'Response';
2033
2234
  /**
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).
2235
+ * HTTP status code or `'default'` for a fallback response.
2036
2236
  */
2037
- nameFor: (node: SchemaNode, signature: string) => string | null;
2237
+ statusCode: StatusCode;
2038
2238
  /**
2039
- * Builds the `$ref` path for a canonical name.
2239
+ * Optional response description.
2040
2240
  */
2041
- refFor: (name: string) => string;
2241
+ description?: string;
2042
2242
  /**
2043
- * Minimum number of occurrences before a shape is deduplicated.
2243
+ * All available content type entries for this response.
2044
2244
  *
2045
- * @default 2
2245
+ * When the adapter `contentType` option is set, this array contains exactly one entry for that
2246
+ * content type. Otherwise it contains one entry per content type declared in the spec, so that
2247
+ * plugins can generate a union of response types (e.g. `application/json` and `application/xml`).
2248
+ * Body-less responses keep a single entry whose `schema` is the empty/`void` placeholder.
2249
+ *
2250
+ * @example
2251
+ * ```ts
2252
+ * // spec response declares both application/json and application/xml
2253
+ * response.content[0].contentType // 'application/json'
2254
+ * response.content[1].contentType // 'application/xml'
2255
+ * ```
2046
2256
  */
2047
- minOccurrences?: number;
2257
+ content?: Array<ContentNode>;
2258
+ };
2259
+ type ResponseInput = Pick<ResponseNode, 'statusCode'> & Partial<Omit<ResponseNode, 'kind' | 'statusCode' | 'content'>> & {
2260
+ content?: Array<UserContent>;
2261
+ schema?: SchemaNode;
2262
+ mediaType?: string | null;
2263
+ keysToOmit?: Array<string> | null;
2048
2264
  };
2049
2265
  /**
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.
2058
- *
2059
- * @example
2060
- * ```ts
2061
- * const next = applyDedupe(operationNode, plan)
2062
- * ```
2266
+ * Definition for the {@link ResponseNode}. A single legacy `schema` (with optional
2267
+ * `mediaType`/`keysToOmit`) is normalized into one `content` entry.
2063
2268
  */
2064
- declare function applyDedupe(node: SchemaNode, plan: DedupeLookups, skipRootMatch?: boolean): SchemaNode;
2065
- declare function applyDedupe(node: OperationNode, plan: DedupeLookups, skipRootMatch?: boolean): OperationNode;
2269
+ declare const responseDef: NodeDef<ResponseNode, ResponseInput>;
2066
2270
  /**
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}.
2271
+ * Creates a `ResponseNode`.
2075
2272
  *
2076
2273
  * @example
2077
2274
  * ```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}`,
2275
+ * const response = createResponse({
2276
+ * statusCode: '200',
2277
+ * content: [{ contentType: 'application/json', schema: createSchema({ type: 'object', properties: [] }) }],
2082
2278
  * })
2083
2279
  * ```
2084
2280
  */
2085
- declare function buildDedupePlan(roots: ReadonlyArray<Node>, options: BuildDedupePlanOptions): DedupePlan;
2281
+ declare const createResponse: (input: ResponseInput) => ResponseNode;
2086
2282
  //#endregion
2087
- //#region src/dialect.d.ts
2283
+ //#region src/nodes/operation.d.ts
2284
+ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'TRACE';
2088
2285
  /**
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.
2286
+ * Transport an operation belongs to.
2092
2287
  */
2093
- type SchemaDialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown> = {
2288
+ type OperationProtocol = 'http';
2289
+ /**
2290
+ * Fields shared by every operation, regardless of transport.
2291
+ */
2292
+ type OperationNodeBase = BaseNode & {
2094
2293
  /**
2095
- * Identifies the dialect in logs and diagnostics.
2294
+ * Node kind.
2096
2295
  */
2097
- name: string;
2296
+ kind: 'Operation';
2098
2297
  /**
2099
- * Whether the schema is nullable.
2298
+ * Operation identifier, usually from OpenAPI `operationId`.
2100
2299
  */
2101
- isNullable: (schema?: TSchema) => boolean;
2300
+ operationId: string;
2102
2301
  /**
2103
- * Whether the value is a `$ref` pointer.
2302
+ * Group labels for the operation.
2303
+ * Usually copied from OpenAPI `tags`.
2104
2304
  */
2105
- isReference: (value?: unknown) => value is TRef;
2305
+ tags: Array<string>;
2106
2306
  /**
2107
- * Whether the schema carries a discriminator for polymorphism.
2307
+ * Short one-line operation summary.
2108
2308
  */
2109
- isDiscriminator: (value?: unknown) => value is TDiscriminated;
2309
+ summary?: string;
2310
+ /**
2311
+ * Full operation description.
2312
+ */
2313
+ description?: string;
2314
+ /**
2315
+ * Marks the operation as deprecated.
2316
+ */
2317
+ deprecated?: boolean;
2318
+ /**
2319
+ * Parameters that could be used, we have QueryParams, PathParams, HeaderParams and CookieParams
2320
+ */
2321
+ parameters: Array<ParameterNode>;
2110
2322
  /**
2111
- * Whether the schema is binary data, converted to a `blob` node.
2323
+ * Request body for the operation.
2112
2324
  */
2113
- isBinary: (schema: TSchema) => boolean;
2325
+ requestBody?: RequestBodyNode;
2114
2326
  /**
2115
- * Resolves a local `$ref` against the document, or nullish when it cannot.
2327
+ * Operation responses.
2116
2328
  */
2117
- resolveRef: <TResolved>(document: TDocument, ref: string) => TResolved | null | undefined;
2329
+ responses: Array<ResponseNode>;
2118
2330
  };
2119
2331
  /**
2120
- * Types a {@link SchemaDialect} for an adapter. Adds no runtime behavior and only pins the
2121
- * dialect's type for inference.
2332
+ * Operation served over HTTP/REST (OpenAPI). `method` and `path` are guaranteed.
2122
2333
  *
2123
2334
  * @example
2124
2335
  * ```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
- * })
2336
+ * const operation: HttpOperationNode = {
2337
+ * kind: 'Operation',
2338
+ * operationId: 'listPets',
2339
+ * protocol: 'http',
2340
+ * method: 'GET',
2341
+ * path: '/pets',
2342
+ * tags: [],
2343
+ * parameters: [],
2344
+ * responses: [],
2345
+ * }
2133
2346
  * ```
2134
2347
  */
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';
2348
+ type HttpOperationNode = OperationNodeBase & {
2159
2349
  /**
2160
- * AST type used when a schema's type cannot be inferred from the spec
2161
- * (`additionalProperties: true`, missing `type`, ...).
2350
+ * Transport the operation belongs to.
2162
2351
  */
2163
- unknownType: 'any' | 'unknown' | 'void';
2352
+ protocol?: 'http';
2164
2353
  /**
2165
- * AST type used for completely empty schemas (`{}`).
2354
+ * HTTP method like `'GET'`.
2166
2355
  */
2167
- emptySchemaType: 'any' | 'unknown' | 'void';
2356
+ method: HttpMethod;
2168
2357
  /**
2169
- * Suffix appended to derived enum names when Kubb has to invent one
2170
- * (typically for inline enums on object properties).
2358
+ * OpenAPI-style path string, for example `/pets/{petId}`, with `{param}` notation preserved.
2171
2359
  */
2172
- enumSuffix: 'enum' | (string & {});
2360
+ path: string;
2173
2361
  };
2174
2362
  /**
2175
- * Maps each `dateType` option value to the AST node produced by `format: 'date-time'`.
2363
+ * Operation for a non-HTTP transport. HTTP-only fields are forbidden.
2176
2364
  */
2177
- type DateTimeNodeByDateType = {
2178
- date: DateSchemaNode;
2179
- string: DatetimeSchemaNode;
2180
- stringOffset: DatetimeSchemaNode;
2181
- stringLocal: DatetimeSchemaNode;
2182
- false: StringSchemaNode;
2365
+ type GenericOperationNode = OperationNodeBase & {
2366
+ /**
2367
+ * Transport the operation belongs to.
2368
+ */
2369
+ protocol?: Exclude<OperationProtocol, 'http'>;
2370
+ method?: never;
2371
+ path?: never;
2183
2372
  };
2184
2373
  /**
2185
- * Resolves the AST node produced by `format: 'date-time'` based on the `dateType` option.
2374
+ * AST node representing one API operation.
2375
+ *
2376
+ * Discriminated on `protocol`: an {@link HttpOperationNode} (`protocol: 'http'`) guarantees
2377
+ * `method` and `path`, while a {@link GenericOperationNode} omits them. Narrow with
2378
+ * `isHttpOperationNode(node)` or `node.protocol === 'http'` before reading `method`/`path`.
2186
2379
  */
2187
- type ResolveDateTimeNode<TDateType extends ParserOptions['dateType']> = DateTimeNodeByDateType[TDateType extends keyof DateTimeNodeByDateType ? TDateType : 'string'];
2380
+ type OperationNode = HttpOperationNode | GenericOperationNode;
2381
+ type OperationInput = {
2382
+ operationId: string;
2383
+ method?: HttpOperationNode['method'];
2384
+ path?: HttpOperationNode['path'];
2385
+ requestBody?: UserRequestBody;
2386
+ [key: string]: unknown;
2387
+ };
2188
2388
  /**
2189
- * Ordered list of `[schema-shape, SchemaNode]` pairs.
2190
- * `InferSchemaNode` walks this tuple in order and returns the first matching node type.
2389
+ * Definition for the {@link OperationNode}. HTTP operations (those carrying both
2390
+ * `method` and `path`) are tagged with `protocol: 'http'`, and the request body is
2391
+ * normalized into a `RequestBodyNode`.
2191
2392
  */
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]];
2393
+ declare const operationDef: NodeDef<OperationNode, OperationInput>;
2280
2394
  /**
2281
- * Infers the matching AST `SchemaNode` type from an input schema shape.
2395
+ * Creates an `OperationNode` with default empty arrays for `tags`, `parameters`, and `responses`.
2396
+ *
2397
+ * @example
2398
+ * ```ts
2399
+ * const operation = createOperation({ operationId: 'getPetById', method: 'GET', path: '/pet/{petId}' })
2400
+ * // tags, parameters, and responses are []
2401
+ * ```
2282
2402
  */
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;
2403
+ declare function createOperation(props: Pick<HttpOperationNode, 'operationId' | 'method' | 'path'> & Partial<Omit<HttpOperationNode, 'kind' | 'operationId' | 'method' | 'path' | 'requestBody'>> & {
2404
+ requestBody?: UserRequestBody;
2405
+ }): HttpOperationNode;
2406
+ declare function createOperation(props: Pick<GenericOperationNode, 'operationId'> & Partial<Omit<GenericOperationNode, 'kind' | 'operationId' | 'requestBody'>> & {
2407
+ requestBody?: UserRequestBody;
2408
+ }): GenericOperationNode;
2284
2409
  //#endregion
2285
- //#region src/factory.d.ts
2410
+ //#region src/nodes/input.d.ts
2286
2411
  /**
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.
2412
+ * Metadata for an API document, populated by the adapter and available to every generator.
2290
2413
  *
2291
- * - Non-required + non-nullable `optional: true`.
2292
- * - Non-required + nullable `nullish: true`.
2293
- * - Required both flags cleared.
2414
+ * All fields are plain JSON-serializable values, no `Set`, no `Map`, no class instances.
2415
+ * Computed fields (`circularNames`, `enumNames`) are pre-calculated once during the adapter
2416
+ * pre-scan so generators never need to iterate the full schema list themselves.
2417
+ *
2418
+ * @example
2419
+ * ```ts
2420
+ * const meta: InputMeta = { title: 'Pet Store', version: '1.0.0', baseURL: 'https://petstore.swagger.io/v2', circularNames: [], enumNames: [] }
2421
+ * ```
2294
2422
  */
2295
- declare function syncOptionality(schema: SchemaNode, required: boolean): SchemaNode;
2423
+ type InputMeta = {
2424
+ /**
2425
+ * API title from `info.title` in the source document.
2426
+ */
2427
+ title?: string;
2428
+ /**
2429
+ * API description from `info.description` in the source document.
2430
+ */
2431
+ description?: string;
2432
+ /**
2433
+ * API version string from `info.version` in the source document.
2434
+ */
2435
+ version?: string;
2436
+ /**
2437
+ * Resolved base URL from the first matching server entry in the source document.
2438
+ */
2439
+ baseURL?: string | null;
2440
+ /**
2441
+ * Names of schemas that participate in a circular reference chain.
2442
+ * Computed once during the adapter pre-scan, use this instead of calling
2443
+ * `findCircularSchemas` per generator call.
2444
+ *
2445
+ * Convert to a `Set` once at the start of a generator, not per-schema,
2446
+ * to keep lookup O(1) without repeated allocations.
2447
+ *
2448
+ * @example Wrap a circular schema in z.lazy()
2449
+ * ```ts
2450
+ * const circular = new Set(meta.circularNames)
2451
+ * if (circular.has(schema.name)) { ... }
2452
+ * ```
2453
+ */
2454
+ circularNames: ReadonlyArray<string>;
2455
+ /**
2456
+ * Names of schemas whose type is `enum`.
2457
+ * Computed once during the adapter pre-scan, use this instead of filtering
2458
+ * schemas per generator call.
2459
+ *
2460
+ * Convert to a `Set` once at the start of a generator when you need repeated
2461
+ * membership checks, rather than calling `.includes()` per schema.
2462
+ *
2463
+ * @example Check if a referenced schema is an enum
2464
+ * `const enums = new Set(meta.enumNames)`
2465
+ * `const isEnum = enums.has(schemaName)`
2466
+ */
2467
+ enumNames: ReadonlyArray<string>;
2468
+ };
2296
2469
  /**
2297
- * Distributive `Omit` that preserves each member of a union.
2470
+ * Input AST node that contains all schemas and operations for one API document.
2471
+ * Produced by the adapter and consumed by all Kubb plugins.
2472
+ *
2473
+ * `Stream` switches `schemas` and `operations` between eager `Array`s (the default) and lazy
2474
+ * `AsyncIterable`s. The streaming variant `InputNode<true>` yields nodes one at a time and makes
2475
+ * `meta` optional, since the adapter can emit metadata before the first node is parsed.
2298
2476
  *
2299
2477
  * @example
2300
2478
  * ```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 }
2479
+ * const input: InputNode = {
2480
+ * kind: 'Input',
2481
+ * schemas: [],
2482
+ * operations: [],
2483
+ * meta: { circularNames: [], enumNames: [] },
2484
+ * }
2305
2485
  * ```
2306
- */
2307
- type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
2308
- /**
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.
2317
2486
  *
2318
- * @example
2487
+ * @example Streaming variant for large specs
2319
2488
  * ```ts
2320
- * update(node, { name: node.name }) // -> same `node` reference
2321
- * update(node, { name: 'renamed' }) // -> new node, `name` replaced
2489
+ * for await (const schema of inputNode.schemas) {
2490
+ * // only this one SchemaNode is live here. Previous ones are GC-eligible
2491
+ * }
2322
2492
  * ```
2323
2493
  */
2324
- declare function update<T extends Node>(node: T, changes: Partial<T>): T;
2325
- type CreateSchemaObjectInput = Omit<ObjectSchemaNode, 'kind' | 'properties' | 'primitive'> & {
2326
- properties?: Array<PropertyNode>;
2327
- primitive?: 'object';
2328
- };
2329
- type CreateSchemaInput = CreateSchemaObjectInput | DistributiveOmit<Exclude<SchemaNode, ObjectSchemaNode>, 'kind'>;
2330
- type CreateSchemaOutput<T extends CreateSchemaInput> = InferSchemaNode<T> & {
2331
- kind: 'Schema';
2332
- };
2494
+ type InputNode<Stream extends boolean = false> = BaseNode & {
2495
+ /**
2496
+ * Node kind.
2497
+ */
2498
+ kind: 'Input';
2499
+ /**
2500
+ * All schema nodes in the document.
2501
+ */
2502
+ schemas: Streamable<SchemaNode, Stream>;
2503
+ /**
2504
+ * All operation nodes in the document.
2505
+ */
2506
+ operations: Streamable<OperationNode, Stream>;
2507
+ } & (Stream extends true ? {
2508
+ meta?: InputMeta;
2509
+ } : {
2510
+ meta: InputMeta;
2511
+ });
2512
+ /**
2513
+ * Definition for the {@link InputNode}.
2514
+ */
2515
+ declare const inputDef: NodeDef<InputNode<false>, Partial<Omit<InputNode<false>, "kind">>>;
2333
2516
  /**
2334
2517
  * Creates an `InputNode` with stable defaults for `schemas` and `operations`.
2335
2518
  *
@@ -2338,12 +2521,6 @@ type CreateSchemaOutput<T extends CreateSchemaInput> = InferSchemaNode<T> & {
2338
2521
  * const input = createInput()
2339
2522
  * // { kind: 'Input', schemas: [], operations: [] }
2340
2523
  * ```
2341
- *
2342
- * @example
2343
- * ```ts
2344
- * const input = createInput({ schemas: [petSchema] })
2345
- * // keeps default operations: []
2346
- * ```
2347
2524
  */
2348
2525
  declare function createInput(overrides?: Partial<Omit<InputNode, 'kind'>>): InputNode;
2349
2526
  /**
@@ -2355,328 +2532,245 @@ declare function createInput(overrides?: Partial<Omit<InputNode, 'kind'>>): Inpu
2355
2532
  * ```
2356
2533
  */
2357
2534
  declare function createStreamInput(schemas: AsyncIterable<SchemaNode>, operations: AsyncIterable<OperationNode>, meta?: InputMeta): InputNode<true>;
2535
+ //#endregion
2536
+ //#region src/nodes/output.d.ts
2358
2537
  /**
2359
- * Creates an `OutputNode` with a stable default for `files`.
2538
+ * Output AST node that groups all generated file output for one API document.
2539
+ *
2540
+ * Produced by generators and consumed by the build pipeline to write files.
2360
2541
  *
2361
2542
  * @example
2362
2543
  * ```ts
2363
- * const output = createOutput()
2364
- * // { kind: 'Output', files: [] }
2544
+ * const output: OutputNode = {
2545
+ * kind: 'Output',
2546
+ * files: [],
2547
+ * }
2365
2548
  * ```
2549
+ */
2550
+ type OutputNode = BaseNode & {
2551
+ /**
2552
+ * Node kind.
2553
+ */
2554
+ kind: 'Output';
2555
+ /**
2556
+ * Generated file nodes.
2557
+ */
2558
+ files: Array<FileNode>;
2559
+ };
2560
+ /**
2561
+ * Definition for the {@link OutputNode}.
2562
+ */
2563
+ declare const outputDef: NodeDef<OutputNode, Partial<Omit<OutputNode, "kind">>>;
2564
+ /**
2565
+ * Creates an `OutputNode` with a stable default for `files`.
2366
2566
  *
2367
2567
  * @example
2368
2568
  * ```ts
2369
- * const output = createOutput({ files: [petFile] })
2569
+ * const output = createOutput()
2570
+ * // { kind: 'Output', files: [] }
2370
2571
  * ```
2371
2572
  */
2372
2573
  declare function createOutput(overrides?: Partial<Omit<OutputNode, 'kind'>>): OutputNode;
2574
+ //#endregion
2575
+ //#region src/nodes/index.d.ts
2373
2576
  /**
2374
- * Creates an `OperationNode` with default empty arrays for `tags`, `parameters`, and `responses`.
2577
+ * Union of all AST node types.
2375
2578
  *
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
- * ```
2579
+ * This lets TypeScript narrow types in `switch (node.kind)` blocks.
2385
2580
  *
2386
2581
  * @example
2387
2582
  * ```ts
2388
- * const operation = createOperation({
2389
- * operationId: 'findPets',
2390
- * method: 'GET',
2391
- * path: '/pet/findByStatus',
2392
- * tags: ['pet'],
2393
- * })
2583
+ * function getKind(node: Node): string {
2584
+ * switch (node.kind) {
2585
+ * case 'Input':
2586
+ * return 'input'
2587
+ * case 'Output':
2588
+ * return 'output'
2589
+ * default:
2590
+ * return 'other'
2591
+ * }
2592
+ * }
2394
2593
  * ```
2395
2594
  */
2595
+ type Node = InputNode | OutputNode | OperationNode | SchemaNode | PropertyNode | ParameterNode | ResponseNode | RequestBodyNode | ContentNode | FunctionParamNode | FileNode | ImportNode | ExportNode | SourceNode | ConstNode | TypeNode | FunctionNode | ArrowFunctionNode;
2596
+ //#endregion
2597
+ //#region src/dedupe.d.ts
2396
2598
  /**
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}.
2599
+ * A canonical destination for a deduplicated shape: the shared schema name and
2600
+ * the synthetic `$ref` path that points at it.
2402
2601
  */
2403
- type UserRequestBody = Omit<RequestBodyNode, 'kind' | 'content'> & {
2404
- content?: Array<UserContent>;
2602
+ type DedupeCanonical = {
2603
+ /**
2604
+ * Canonical schema name every duplicate occurrence refers to.
2605
+ */
2606
+ name: string;
2607
+ /**
2608
+ * `$ref` path stored on the generated `ref` nodes (for example `#/components/schemas/Status`).
2609
+ */
2610
+ ref: string;
2405
2611
  };
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;
2412
2612
  /**
2413
- * 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
- *
2417
- * @example
2418
- * ```ts
2419
- * const scalar = createSchema({ type: 'string' })
2420
- * // { kind: 'Schema', type: 'string', primitive: 'string' }
2421
- * ```
2422
- *
2423
- * @example
2424
- * ```ts
2425
- * const uuid = createSchema({ type: 'uuid' })
2426
- * // { kind: 'Schema', type: 'uuid', primitive: 'string' }
2427
- * ```
2428
- *
2429
- * @example
2430
- * ```ts
2431
- * const object = createSchema({ type: 'object' })
2432
- * // { kind: 'Schema', type: 'object', primitive: 'object', properties: [] }
2433
- * ```
2434
- *
2435
- * @example
2436
- * ```ts
2437
- * const enumSchema = createSchema({
2438
- * type: 'enum',
2439
- * primitive: 'string',
2440
- * enumValues: ['available', 'pending'],
2441
- * })
2442
- * ```
2613
+ * The result of {@link buildDedupePlan}: a lookup from structural signature to its
2614
+ * canonical target, plus the freshly hoisted definitions that must be added to
2615
+ * the schema list.
2443
2616
  */
2444
- declare function createSchema<T extends CreateSchemaInput>(props: T): CreateSchemaOutput<T>;
2445
- declare function createSchema(props: CreateSchemaInput): SchemaNode;
2446
- type UserPropertyNode = Pick<PropertyNode, 'name' | 'schema'> & Partial<Omit<PropertyNode, 'kind' | 'name' | 'schema'>>;
2617
+ type DedupePlan = {
2618
+ /**
2619
+ * Maps a structural signature to the canonical schema that represents it.
2620
+ */
2621
+ canonicalBySignature: Map<string, DedupeCanonical>;
2622
+ /**
2623
+ * Maps the name of a top-level schema that duplicates a canonical one to that canonical, so
2624
+ * references to the duplicate can be repointed at the first schema with the same content.
2625
+ */
2626
+ aliasNames: Map<string, DedupeCanonical>;
2627
+ /**
2628
+ * New top-level schema definitions created for inline shapes that had no existing
2629
+ * named component. Nested duplicates inside each definition are already collapsed.
2630
+ */
2631
+ hoisted: Array<SchemaNode>;
2632
+ };
2447
2633
  /**
2448
- * Creates a `PropertyNode`.
2449
- *
2450
- * `required` defaults to `false`.
2451
- * `schema.optional` and `schema.nullish` are derived from `required` and `schema.nullable`.
2452
- *
2453
- * @example
2454
- * ```ts
2455
- * const property = createProperty({
2456
- * name: 'status',
2457
- * 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
2470
- * ```
2634
+ * The lookups {@link applyDedupe} needs from a {@link DedupePlan}.
2471
2635
  */
2472
- declare function createProperty(props: UserPropertyNode): PropertyNode;
2636
+ type DedupeLookups = Pick<DedupePlan, 'canonicalBySignature' | 'aliasNames'>;
2473
2637
  /**
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
- * ```
2638
+ * Options that inject the naming and candidate policy into {@link buildDedupePlan}.
2639
+ * The mechanics (grouping, counting, rewriting) live here. The policy lives in the caller.
2498
2640
  */
2499
- declare function createParameter(props: Pick<ParameterNode, 'name' | 'in' | 'schema'> & Partial<Omit<ParameterNode, 'kind' | 'name' | 'in' | 'schema'>>): ParameterNode;
2641
+ type BuildDedupePlanOptions = {
2642
+ /**
2643
+ * Returns `true` when a node should be deduplicated. This is the only gate, so it must
2644
+ * reject both ineligible kinds (return `false` for anything other than, say, enums and
2645
+ * objects) and unsafe shapes (e.g. nodes that reference a circular schema).
2646
+ */
2647
+ isCandidate: (node: SchemaNode) => boolean;
2648
+ /**
2649
+ * Produces the canonical name for an inline shape with no existing named component.
2650
+ * Return `null` to leave the shape inline (for example when no contextual name exists).
2651
+ */
2652
+ nameFor: (node: SchemaNode, signature: string) => string | null;
2653
+ /**
2654
+ * Builds the `$ref` path for a canonical name.
2655
+ */
2656
+ refFor: (name: string) => string;
2657
+ /**
2658
+ * Minimum number of occurrences before a shape is deduplicated.
2659
+ *
2660
+ * @default 2
2661
+ */
2662
+ minOccurrences?: number;
2663
+ };
2500
2664
  /**
2501
- * Creates a `ResponseNode`.
2665
+ * Rewrites a node, replacing every candidate sub-schema whose signature has a canonical
2666
+ * target with a `ref` to that target. Replacing a node with a `ref` prunes its subtree,
2667
+ * so nested duplicates inside a replaced shape are not visited again. A `ref` that points
2668
+ * at a duplicate top-level schema (see `aliasNames`) is repointed at the first schema with
2669
+ * the same content.
2502
2670
  *
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`.
2671
+ * Pass `skipRootMatch` when rewriting a canonical definition so its own root is not
2672
+ * turned into a reference to itself. Nested duplicates are still collapsed.
2506
2673
  *
2507
2674
  * @example
2508
2675
  * ```ts
2509
- * const response = createResponse({
2510
- * statusCode: '200',
2511
- * content: [{ contentType: 'application/json', schema: createSchema({ type: 'object', properties: [] }) }],
2512
- * })
2676
+ * const next = applyDedupe(operationNode, plan)
2513
2677
  * ```
2514
2678
  */
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;
2679
+ declare function applyDedupe(node: SchemaNode, plan: DedupeLookups, skipRootMatch?: boolean): SchemaNode;
2680
+ declare function applyDedupe(node: OperationNode, plan: DedupeLookups, skipRootMatch?: boolean): OperationNode;
2521
2681
  /**
2522
- * Creates a `FunctionParameterNode`.
2523
- *
2524
- * `optional` defaults to `false`.
2525
- *
2526
- * @example Required typed param
2527
- * ```ts
2528
- * createFunctionParameter({ name: 'petId', type: createParamsType({ variant: 'reference', name: 'string' }) })
2529
- * // → petId: string
2530
- * ```
2682
+ * Scans a forest of schema and operation nodes and produces a {@link DedupePlan}.
2531
2683
  *
2532
- * @example Optional param
2533
- * ```ts
2534
- * createFunctionParameter({ name: 'params', type: createParamsType({ variant: 'reference', name: 'QueryParams' }), optional: true })
2535
- * // params?: QueryParams
2536
- * ```
2684
+ * A shape that occurs at least `minOccurrences` times is deduplicated: if any occurrence
2685
+ * is a named top-level schema, the first one becomes the canonical (so other top-level
2686
+ * duplicates and inline copies turn into references to it). Every other top-level name with
2687
+ * the same content is recorded in `aliasNames`, so refs to it can be repointed at the
2688
+ * canonical. Otherwise a new definition is hoisted using `nameFor`. The plan is then applied
2689
+ * per node with {@link applyDedupe}.
2537
2690
  *
2538
- * @example Param with default (implicitly optional. Cannot combine with `optional: true`)
2691
+ * @example
2539
2692
  * ```ts
2540
- * createFunctionParameter({ name: 'config', type: createParamsType({ variant: 'reference', name: 'RequestConfig' }), default: '{}' })
2541
- * // config: RequestConfig = {}
2693
+ * const plan = buildDedupePlan([...schemaNodes, ...operationNodes], {
2694
+ * isCandidate: (node) => node.type === 'enum' || node.type === 'object',
2695
+ * nameFor: (node) => node.name ?? null,
2696
+ * refFor: (name) => `#/components/schemas/${name}`,
2697
+ * })
2542
2698
  * ```
2543
2699
  */
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;
2700
+ declare function buildDedupePlan(roots: ReadonlyArray<Node>, options: BuildDedupePlanOptions): DedupePlan;
2701
+ //#endregion
2702
+ //#region src/dialect.d.ts
2555
2703
  /**
2556
- * Creates a {@link TypeNode} representing a language-agnostic structured type expression.
2557
- *
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, …).
2561
- *
2562
- * @example Reference type (TypeScript: `QueryParams`)
2563
- * ```ts
2564
- * createParamsType({ variant: 'reference', name: 'QueryParams' })
2565
- * ```
2566
- *
2567
- * @example Struct type (TypeScript: `{ petId: string }`)
2568
- * ```ts
2569
- * createParamsType({ variant: 'struct', properties: [{ name: 'petId', optional: false, type: createParamsType({ variant: 'reference', name: 'string' }) }] })
2570
- * ```
2571
- *
2572
- * @example Member type (TypeScript: `DeletePetPathParams['petId']`)
2573
- * ```ts
2574
- * createParamsType({ variant: 'member', base: 'DeletePetPathParams', key: 'petId' })
2575
- * ```
2704
+ * The spec-specific questions a schema parser answers while turning a source document into Kubb
2705
+ * AST nodes. The rest of the pipeline is generic JSON Schema, so this is the one seam where
2706
+ * OpenAPI, AsyncAPI, and plain JSON Schema differ.
2576
2707
  */
2577
- declare function createParamsType(props: {
2578
- variant: 'reference';
2708
+ type SchemaDialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown> = {
2709
+ /**
2710
+ * Identifies the dialect in logs and diagnostics.
2711
+ */
2579
2712
  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;
2592
- /**
2593
- * Creates a `ParameterGroupNode` representing a group of related parameters treated as a unit.
2594
- *
2595
- * @example Grouped param (TypeScript declaration)
2596
- * ```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 }
2606
- * ```
2607
- *
2608
- * @example Inline (spread), children emitted as individual top-level parameters
2609
- * ```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
2616
- * ```
2617
- */
2618
- declare function createParameterGroup(props: Pick<ParameterGroupNode, 'properties'> & Partial<Omit<ParameterGroupNode, 'kind' | 'properties'>>): ParameterGroupNode;
2713
+ /**
2714
+ * Whether the schema is nullable.
2715
+ */
2716
+ isNullable: (schema?: TSchema) => boolean;
2717
+ /**
2718
+ * Whether the value is a `$ref` pointer.
2719
+ */
2720
+ isReference: (value?: unknown) => value is TRef;
2721
+ /**
2722
+ * Whether the schema carries a discriminator for polymorphism.
2723
+ */
2724
+ isDiscriminator: (value?: unknown) => value is TDiscriminated;
2725
+ /**
2726
+ * Whether the schema is binary data, converted to a `blob` node.
2727
+ */
2728
+ isBinary: (schema: TSchema) => boolean;
2729
+ /**
2730
+ * Resolves a local `$ref` against the document, or nullish when it cannot.
2731
+ */
2732
+ resolveRef: <TResolved>(document: TDocument, ref: string) => TResolved | null | undefined;
2733
+ };
2619
2734
  /**
2620
- * Creates a `FunctionParametersNode` from an ordered list of parameters.
2735
+ * Types a {@link SchemaDialect} for an adapter. Adds no runtime behavior and only pins the
2736
+ * dialect's type for inference.
2621
2737
  *
2622
2738
  * @example
2623
2739
  * ```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
- * ],
2740
+ * export const oasDialect = defineSchemaDialect({
2741
+ * name: 'oas',
2742
+ * isNullable,
2743
+ * isReference,
2744
+ * isDiscriminator,
2745
+ * isBinary: (schema) => schema.type === 'string' && schema.contentMediaType === 'application/octet-stream',
2746
+ * resolveRef,
2629
2747
  * })
2630
2748
  * ```
2631
- *
2632
- * @example
2633
- * ```ts
2634
- * const empty = createFunctionParameters()
2635
- * // { kind: 'FunctionParameters', params: [] }
2636
- * ```
2637
- */
2638
- declare function createFunctionParameters(props?: Partial<Omit<FunctionParametersNode, 'kind'>>): FunctionParametersNode;
2639
- /**
2640
- * Creates an `ImportNode` representing a language-agnostic import/dependency declaration.
2641
- *
2642
- * @example Named import
2643
- * ```ts
2644
- * createImport({ name: ['useState'], path: 'react' })
2645
- * // import { useState } from 'react'
2646
- * ```
2647
- *
2648
- * @example Type-only import
2649
- * ```ts
2650
- * createImport({ name: ['FC'], path: 'react', isTypeOnly: true })
2651
- * // import type { FC } from 'react'
2652
- * ```
2653
2749
  */
2654
- declare function createImport(props: Omit<ImportNode, 'kind'>): ImportNode;
2750
+ declare function defineSchemaDialect<TSchema, TRef, TDiscriminated, TDocument>(dialect: SchemaDialect<TSchema, TRef, TDiscriminated, TDocument>): SchemaDialect<TSchema, TRef, TDiscriminated, TDocument>;
2751
+ //#endregion
2752
+ //#region src/factory.d.ts
2655
2753
  /**
2656
- * Creates an `ExportNode` representing a language-agnostic export/public API declaration.
2754
+ * Identity-preserving node update: returns `node` unchanged when every field in
2755
+ * `changes` already equals (by reference) the current value, otherwise a new node
2756
+ * with the changes applied.
2657
2757
  *
2658
- * @example Named export
2659
- * ```ts
2660
- * createExport({ name: ['Pet'], path: './Pet' })
2661
- * // export { Pet } from './Pet'
2662
- * ```
2758
+ * Mirrors the TypeScript compiler's `factory.updateX` contract, pair it with the
2759
+ * structural sharing in {@link transform} so a no-op rewrite doesn't allocate and
2760
+ * downstream passes can detect "nothing changed" by identity. Comparison is
2761
+ * shallow: a structurally-equal but newly-allocated array/object counts as a change.
2663
2762
  *
2664
- * @example Wildcard export
2763
+ * @example
2665
2764
  * ```ts
2666
- * createExport({ path: './utils' })
2667
- * // export * from './utils'
2765
+ * update(node, { name: node.name }) // -> same `node` reference
2766
+ * update(node, { name: 'renamed' }) // -> new node, `name` replaced
2668
2767
  * ```
2669
2768
  */
2670
- declare function createExport(props: Omit<ExportNode, 'kind'>): ExportNode;
2769
+ declare function update<T extends Node>(node: T, changes: Partial<T>): T;
2671
2770
  /**
2672
- * Creates a `SourceNode` representing a fragment of source code within a file.
2673
- *
2674
- * @example
2675
- * ```ts
2676
- * createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true })
2677
- * ```
2771
+ * Input descriptor for {@link createFile}, before `id`, `name`, and `extname` are computed
2772
+ * and `imports`/`exports`/`sources` are deduplicated.
2678
2773
  */
2679
- declare function createSource(props: Omit<SourceNode, 'kind'>): SourceNode;
2680
2774
  type UserFileNode<TMeta extends object = object> = Omit<FileNode<TMeta>, 'kind' | 'id' | 'name' | 'extname' | 'imports' | 'exports' | 'sources'> & Pick<Partial<FileNode<TMeta>>, 'imports' | 'exports' | 'sources'>;
2681
2775
  /**
2682
2776
  * Creates a fully resolved `FileNode` from a file input descriptor.
@@ -2708,159 +2802,6 @@ type UserFileNode<TMeta extends object = object> = Omit<FileNode<TMeta>, 'kind'
2708
2802
  * ```
2709
2803
  */
2710
2804
  declare function createFile<TMeta extends object = object>(input: UserFileNode<TMeta>): FileNode<TMeta>;
2711
- /**
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
- * ```
2722
- *
2723
- * @example Exported constant with type and `as const`
2724
- * ```ts
2725
- * createConst({ name: 'pets', export: true, type: 'Pet[]', asConst: true })
2726
- * // export const pets: Pet[] = ... as const
2727
- * ```
2728
- *
2729
- * @example With JSDoc and child nodes
2730
- * ```ts
2731
- * createConst({
2732
- * name: 'config',
2733
- * export: true,
2734
- * JSDoc: { comments: ['@description App configuration'] },
2735
- * nodes: [],
2736
- * })
2737
- * ```
2738
- */
2739
- declare function createConst(props: Omit<ConstNode, 'kind'>): ConstNode;
2740
- /**
2741
- * Creates a `TypeNode` representing a TypeScript `type` alias declaration.
2742
- *
2743
- * Mirrors the `Type` component from `@kubb/renderer-jsx`.
2744
- * The component's `children` are represented as `nodes`.
2745
- *
2746
- * @example Simple type alias
2747
- * ```ts
2748
- * createType({ name: 'Pet' })
2749
- * // type Pet = ...
2750
- * ```
2751
- *
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
- * ```
2761
- */
2762
- declare function createType(props: Omit<TypeNode, 'kind'>): TypeNode;
2763
- /**
2764
- * Creates a `FunctionNode` representing a TypeScript `function` declaration.
2765
- *
2766
- * Mirrors the `Function` component from `@kubb/renderer-jsx`.
2767
- * The component's `children` are represented as `nodes`.
2768
- *
2769
- * @example Simple function
2770
- * ```ts
2771
- * createFunction({ name: 'getPet' })
2772
- * // function getPet() { ... }
2773
- * ```
2774
- *
2775
- * @example Exported async function with return type
2776
- * ```ts
2777
- * createFunction({ name: 'fetchPet', export: true, async: true, returnType: 'Pet' })
2778
- * // export async function fetchPet(): Promise<Pet> { ... }
2779
- * ```
2780
- *
2781
- * @example Function with generics and params
2782
- * ```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 { ... }
2791
- * ```
2792
- */
2793
- declare function createFunction(props: Omit<FunctionNode, 'kind'>): FunctionNode;
2794
- /**
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`.
2799
- *
2800
- * @example Simple arrow function
2801
- * ```ts
2802
- * createArrowFunction({ name: 'getPet' })
2803
- * // const getPet = () => { ... }
2804
- * ```
2805
- *
2806
- * @example Single-line exported arrow function
2807
- * ```ts
2808
- * createArrowFunction({ name: 'double', export: true, params: 'n: number', singleLine: true })
2809
- * // export const double = (n: number) => ...
2810
- * ```
2811
- *
2812
- * @example Async arrow function with generics
2813
- * ```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> => { ... }
2823
- * ```
2824
- */
2825
- declare function createArrowFunction(props: Omit<ArrowFunctionNode, 'kind'>): ArrowFunctionNode;
2826
- /**
2827
- * Creates a {@link TextNode} representing a raw string fragment in the source output.
2828
- *
2829
- * Use this instead of bare strings when building `nodes` arrays so that every
2830
- * entry in the array is a typed {@link CodeNode}.
2831
- *
2832
- * @example
2833
- * ```ts
2834
- * createText('return fetch(id)')
2835
- * // { kind: 'Text', value: 'return fetch(id)' }
2836
- * ```
2837
- */
2838
- declare function createText(value: string): TextNode;
2839
- /**
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.
2844
- *
2845
- * @example
2846
- * ```ts
2847
- * createBreak()
2848
- * // { kind: 'Break' }
2849
- * ```
2850
- */
2851
- declare function createBreak(): BreakNode;
2852
- /**
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.
2856
- *
2857
- * @example
2858
- * ```ts
2859
- * createJsx('<>\n <a href={href}>Open</a>\n</>')
2860
- * // { kind: 'Jsx', value: '<>\n <a href={href}>Open</a>\n</>' }
2861
- * ```
2862
- */
2863
- declare function createJsx(value: string): JsxNode;
2864
2805
  //#endregion
2865
2806
  //#region src/printer.d.ts
2866
2807
  /**
@@ -3458,7 +3399,7 @@ type CreateOperationParamsOptions = {
3458
3399
  * extraParams: [createFunctionParameter({ name: 'options', type: 'Partial<RequestOptions>', default: '{}' })]
3459
3400
  * ```
3460
3401
  */
3461
- extraParams?: Array<FunctionParameterNode | ParameterGroupNode>;
3402
+ extraParams?: Array<FunctionParameterNode>;
3462
3403
  /**
3463
3404
  * Override the default parameter names used for body, query, header, and rest-path groups.
3464
3405
  *
@@ -3500,10 +3441,10 @@ type CreateOperationParamsOptions = {
3500
3441
  /**
3501
3442
  * Converts an `OperationNode` into function parameters for code generation.
3502
3443
  *
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.
3444
+ * Centralizes parameter grouping logic for all plugins. `paramsType` chooses between one
3445
+ * destructured object parameter (`object`) and separate top-level parameters (`inline`), while
3446
+ * `pathParamsType` controls how path params render in inline mode. Provide a `resolver` for type
3447
+ * name resolution and `extraParams` for plugin-specific trailing parameters such as an `options` object.
3507
3448
  */
3508
3449
  declare function createOperationParams(node: OperationNode, options: CreateOperationParamsOptions): FunctionParametersNode;
3509
3450
  /**
@@ -3540,5 +3481,5 @@ declare function containsCircularRef(node: SchemaNode | undefined, {
3540
3481
  excludeName?: string;
3541
3482
  }): boolean;
3542
3483
  //#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
3484
+ export { createParameter as $, InferSchemaNode as $t, applyDedupe as A, contentDef as At, inputDef as B, ScalarSchemaType as Bt, createFile as C, DistributiveOmit as Cn, createExport as Ct, DedupeCanonical as D, NodeKind as Dn, fileDef as Dt, defineSchemaDialect as E, syncOptionality as En, exportDef as Et, outputDef as F, IntersectionSchemaNode as Ft, operationDef as G, TimeSchemaNode as Gt, HttpOperationNode as H, SchemaNodeByType as Ht, InputMeta as I, NumberSchemaNode as It, responseDef as J, createSchema as Jt, ResponseNode as K, UnionSchemaNode as Kt, InputNode as L, ObjectSchemaNode as Lt, Node as M, DateSchemaNode as Mt, OutputNode as N, DatetimeSchemaNode as Nt, DedupeLookups as O, httpMethods as On, importDef as Ot, createOutput as P, EnumSchemaNode as Pt, ParameterNode as Q, propertyDef as Qt, createInput as R, PrimitiveSchemaType as Rt, UserFileNode as S, typeDef as Sn, SourceNode as St, SchemaDialect as T, defineNode as Tn, createSource as Tt, OperationNode as U, SchemaType as Ut, HttpMethod as V, SchemaNode as Vt, createOperation as W, StringSchemaNode as Wt, requestBodyDef as X, PropertyNode as Xt, StatusCode as Y, schemaDef as Yt, ParameterLocation as Z, createProperty as Zt, Printer as _, createText as _n, objectBindingPatternDef as _t, createDiscriminantNode as a, JSDocNode as an, IndexedAccessTypeNode as at, createPrinterFactory as b, jsxDef as bn, FileNode as bt, findCircularSchemas as c, TypeNode as cn, TypeLiteralNode as ct, ParentOf as d, constDef as dn, createIndexedAccessType as dt, ParserOptions as en, parameterDef as et, Visitor as f, createArrowFunction as fn, createObjectBindingPattern as ft, walk as g, createJsx as gn, indexedAccessTypeDef as gt, transform as h, createFunction as hn, functionParametersDef as ht, containsCircularRef as i, FunctionNode as in, FunctionParametersNode as it, buildDedupePlan as j, ArraySchemaNode as jt, DedupePlan as k, schemaTypes as kn, sourceDef as kt, isStringType as l, arrowFunctionDef as ln, createFunctionParameter as lt, collect as m, createConst as mn, functionParameterDef as mt, caseParams as n, CodeNode as nn, FunctionParamNode as nt, createOperationParams as o, JsxNode as on, ObjectBindingPatternNode as ot, VisitorContext as p, createBreak as pn, createTypeLiteral as pt, createResponse as q, UrlSchemaNode as qt, collectUsedSchemaNames as r, ConstNode as rn, FunctionParameterNode as rt, extractStringsFromNodes as s, TextNode as sn, TypeExpression as st, OperationParamsResolver as t, ArrowFunctionNode as tn, FunctionNodeType as tt, syncSchemaRef as u, breakDef as un, createFunctionParameters as ut, PrinterFactoryOptions as v, createType as vn, typeLiteralDef as vt, update as w, NodeDef as wn, createImport as wt, definePrinter as x, textDef as xn, ImportNode as xt, PrinterPartial as y, functionDef as yn, ExportNode as yt, createStreamInput as z, RefSchemaNode as zt };
3485
+ //# sourceMappingURL=types-C5aVnRE1.d.ts.map