@kubb/ast 5.0.0-beta.21 → 5.0.0-beta.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +55 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +147 -95
- package/dist/index.js +55 -34
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/factory.ts +6 -3
- package/src/infer.ts +15 -4
- package/src/nodes/code.ts +21 -21
- package/src/nodes/file.ts +16 -14
- package/src/printer.ts +19 -12
- package/src/utils.ts +4 -4
- package/src/visitor.ts +72 -43
package/dist/index.d.ts
CHANGED
|
@@ -251,21 +251,21 @@ type ConstNode = BaseNode & {
|
|
|
251
251
|
* Whether the declaration should be exported.
|
|
252
252
|
* @default false
|
|
253
253
|
*/
|
|
254
|
-
export?: boolean;
|
|
254
|
+
export?: boolean | null;
|
|
255
255
|
/**
|
|
256
256
|
* Optional explicit type annotation.
|
|
257
257
|
* @example 'Pet'
|
|
258
258
|
*/
|
|
259
|
-
type?: string;
|
|
259
|
+
type?: string | null;
|
|
260
260
|
/**
|
|
261
261
|
* JSDoc documentation metadata.
|
|
262
262
|
*/
|
|
263
|
-
JSDoc?: JSDocNode;
|
|
263
|
+
JSDoc?: JSDocNode | null;
|
|
264
264
|
/**
|
|
265
265
|
* Whether to append `as const` to the declaration.
|
|
266
266
|
* @default false
|
|
267
267
|
*/
|
|
268
|
-
asConst?: boolean;
|
|
268
|
+
asConst?: boolean | null;
|
|
269
269
|
/**
|
|
270
270
|
* Child nodes representing the value of the constant (children of the `Const` component).
|
|
271
271
|
* Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
|
|
@@ -297,11 +297,11 @@ type TypeNode = BaseNode & {
|
|
|
297
297
|
* Whether the declaration should be exported.
|
|
298
298
|
* @default false
|
|
299
299
|
*/
|
|
300
|
-
export?: boolean;
|
|
300
|
+
export?: boolean | null;
|
|
301
301
|
/**
|
|
302
302
|
* JSDoc documentation metadata.
|
|
303
303
|
*/
|
|
304
|
-
JSDoc?: JSDocNode;
|
|
304
|
+
JSDoc?: JSDocNode | null;
|
|
305
305
|
/**
|
|
306
306
|
* Child nodes representing the type body (children of the `Type` component).
|
|
307
307
|
* Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
|
|
@@ -338,35 +338,35 @@ type FunctionNode = BaseNode & {
|
|
|
338
338
|
* Whether the function is a default export.
|
|
339
339
|
* @default false
|
|
340
340
|
*/
|
|
341
|
-
default?: boolean;
|
|
341
|
+
default?: boolean | null;
|
|
342
342
|
/**
|
|
343
343
|
* Function parameter list rendered as a string (e.g. from `FunctionParams.toConstructor()`).
|
|
344
344
|
*/
|
|
345
|
-
params?: string;
|
|
345
|
+
params?: string | null;
|
|
346
346
|
/**
|
|
347
347
|
* Whether the function should be exported.
|
|
348
348
|
* @default false
|
|
349
349
|
*/
|
|
350
|
-
export?: boolean;
|
|
350
|
+
export?: boolean | null;
|
|
351
351
|
/**
|
|
352
352
|
* Whether the function is async. When `true`, the return type is wrapped in `Promise<>`.
|
|
353
353
|
* @default false
|
|
354
354
|
*/
|
|
355
|
-
async?: boolean;
|
|
355
|
+
async?: boolean | null;
|
|
356
356
|
/**
|
|
357
357
|
* TypeScript generic type parameters.
|
|
358
358
|
* @example ['T', 'U extends string']
|
|
359
359
|
*/
|
|
360
|
-
generics?: string | string[];
|
|
360
|
+
generics?: string | string[] | null;
|
|
361
361
|
/**
|
|
362
362
|
* Return type annotation.
|
|
363
363
|
* @example 'Pet'
|
|
364
364
|
*/
|
|
365
|
-
returnType?: string;
|
|
365
|
+
returnType?: string | null;
|
|
366
366
|
/**
|
|
367
367
|
* JSDoc documentation metadata.
|
|
368
368
|
*/
|
|
369
|
-
JSDoc?: JSDocNode;
|
|
369
|
+
JSDoc?: JSDocNode | null;
|
|
370
370
|
/**
|
|
371
371
|
* Child nodes representing the function body (children of the `Function` component).
|
|
372
372
|
* Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
|
|
@@ -398,40 +398,40 @@ type ArrowFunctionNode = BaseNode & {
|
|
|
398
398
|
* Whether the function is a default export.
|
|
399
399
|
* @default false
|
|
400
400
|
*/
|
|
401
|
-
default?: boolean;
|
|
401
|
+
default?: boolean | null;
|
|
402
402
|
/**
|
|
403
403
|
* Function parameter list rendered as a string (e.g. from `FunctionParams.toConstructor()`).
|
|
404
404
|
*/
|
|
405
|
-
params?: string;
|
|
405
|
+
params?: string | null;
|
|
406
406
|
/**
|
|
407
407
|
* Whether the arrow function should be exported.
|
|
408
408
|
* @default false
|
|
409
409
|
*/
|
|
410
|
-
export?: boolean;
|
|
410
|
+
export?: boolean | null;
|
|
411
411
|
/**
|
|
412
412
|
* Whether the arrow function is async. When `true`, the return type is wrapped in `Promise<>`.
|
|
413
413
|
* @default false
|
|
414
414
|
*/
|
|
415
|
-
async?: boolean;
|
|
415
|
+
async?: boolean | null;
|
|
416
416
|
/**
|
|
417
417
|
* TypeScript generic type parameters.
|
|
418
418
|
* @example ['T', 'U extends string']
|
|
419
419
|
*/
|
|
420
|
-
generics?: string | string[];
|
|
420
|
+
generics?: string | string[] | null;
|
|
421
421
|
/**
|
|
422
422
|
* Return type annotation.
|
|
423
423
|
* @example 'Pet'
|
|
424
424
|
*/
|
|
425
|
-
returnType?: string;
|
|
425
|
+
returnType?: string | null;
|
|
426
426
|
/**
|
|
427
427
|
* JSDoc documentation metadata.
|
|
428
428
|
*/
|
|
429
|
-
JSDoc?: JSDocNode;
|
|
429
|
+
JSDoc?: JSDocNode | null;
|
|
430
430
|
/**
|
|
431
431
|
* Render the arrow function body as a single-line expression.
|
|
432
432
|
* @default false
|
|
433
433
|
*/
|
|
434
|
-
singleLine?: boolean;
|
|
434
|
+
singleLine?: boolean | null;
|
|
435
435
|
/**
|
|
436
436
|
* Child nodes representing the function body (children of the `Function.Arrow` component).
|
|
437
437
|
* Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
|
|
@@ -561,18 +561,18 @@ type ImportNode = BaseNode & {
|
|
|
561
561
|
* - `false` generates `import { Type } from './path'`
|
|
562
562
|
* @default false
|
|
563
563
|
*/
|
|
564
|
-
isTypeOnly?: boolean;
|
|
564
|
+
isTypeOnly?: boolean | null;
|
|
565
565
|
/**
|
|
566
566
|
* Import entire module as namespace.
|
|
567
567
|
* - `true` generates `import * as Name from './path'`
|
|
568
568
|
* - `false` generates standard import
|
|
569
569
|
* @default false
|
|
570
570
|
*/
|
|
571
|
-
isNameSpace?: boolean;
|
|
571
|
+
isNameSpace?: boolean | null;
|
|
572
572
|
/**
|
|
573
573
|
* When set, the import path is resolved relative to this root.
|
|
574
574
|
*/
|
|
575
|
-
root?: string;
|
|
575
|
+
root?: string | null;
|
|
576
576
|
};
|
|
577
577
|
/**
|
|
578
578
|
* Represents a language-agnostic export/public API declaration.
|
|
@@ -604,7 +604,7 @@ type ExportNode = BaseNode & {
|
|
|
604
604
|
* @example ['useState']
|
|
605
605
|
* @example 'React'
|
|
606
606
|
*/
|
|
607
|
-
name?: string | Array<string
|
|
607
|
+
name?: string | Array<string> | null;
|
|
608
608
|
/**
|
|
609
609
|
* Path for the export.
|
|
610
610
|
* @example '@kubb/core'
|
|
@@ -616,14 +616,14 @@ type ExportNode = BaseNode & {
|
|
|
616
616
|
* - `false` generates `export { Type } from './path'`
|
|
617
617
|
* @default false
|
|
618
618
|
*/
|
|
619
|
-
isTypeOnly?: boolean;
|
|
619
|
+
isTypeOnly?: boolean | null;
|
|
620
620
|
/**
|
|
621
621
|
* Export as an aliased namespace.
|
|
622
622
|
* - `true` generates `export * as aliasName from './path'`
|
|
623
623
|
* - `false` generates a standard export
|
|
624
624
|
* @default false
|
|
625
625
|
*/
|
|
626
|
-
asAlias?: boolean;
|
|
626
|
+
asAlias?: boolean | null;
|
|
627
627
|
};
|
|
628
628
|
/**
|
|
629
629
|
* Represents a fragment of source code within a file.
|
|
@@ -643,22 +643,22 @@ type SourceNode = BaseNode & {
|
|
|
643
643
|
/**
|
|
644
644
|
* Optional name identifying this source (used for deduplication and barrel generation).
|
|
645
645
|
*/
|
|
646
|
-
name?: string;
|
|
646
|
+
name?: string | null;
|
|
647
647
|
/**
|
|
648
648
|
* Mark this source as a type-only export.
|
|
649
649
|
* @default false
|
|
650
650
|
*/
|
|
651
|
-
isTypeOnly?: boolean;
|
|
651
|
+
isTypeOnly?: boolean | null;
|
|
652
652
|
/**
|
|
653
653
|
* Include `export` keyword in the generated source.
|
|
654
654
|
* @default false
|
|
655
655
|
*/
|
|
656
|
-
isExportable?: boolean;
|
|
656
|
+
isExportable?: boolean | null;
|
|
657
657
|
/**
|
|
658
658
|
* Include this source in barrel/index file generation.
|
|
659
659
|
* @default false
|
|
660
660
|
*/
|
|
661
|
-
isIndexable?: boolean;
|
|
661
|
+
isIndexable?: boolean | null;
|
|
662
662
|
/**
|
|
663
663
|
* Structured child nodes representing the content of this source fragment, in DOM order.
|
|
664
664
|
* Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
|
|
@@ -688,8 +688,8 @@ type SourceNode = BaseNode & {
|
|
|
688
688
|
type FileNode<TMeta extends object = object> = BaseNode & {
|
|
689
689
|
kind: 'File';
|
|
690
690
|
/**
|
|
691
|
-
* Unique identifier derived from a SHA256 hash of the file path.
|
|
692
|
-
*
|
|
691
|
+
* Unique identifier derived from a SHA256 hash of the file path. Computed
|
|
692
|
+
* by `createFile`; callers do not need to provide it.
|
|
693
693
|
*/
|
|
694
694
|
id: string;
|
|
695
695
|
/**
|
|
@@ -729,12 +729,14 @@ type FileNode<TMeta extends object = object> = BaseNode & {
|
|
|
729
729
|
meta?: TMeta;
|
|
730
730
|
/**
|
|
731
731
|
* Optional banner prepended to the generated file content.
|
|
732
|
+
* Accepts `null` so `resolver.resolveBanner()` results can be passed directly.
|
|
732
733
|
*/
|
|
733
|
-
banner?: string;
|
|
734
|
+
banner?: string | null;
|
|
734
735
|
/**
|
|
735
736
|
* Optional footer appended to the generated file content.
|
|
737
|
+
* Accepts `null` so `resolver.resolveFooter()` results can be passed directly.
|
|
736
738
|
*/
|
|
737
|
-
footer?: string;
|
|
739
|
+
footer?: string | null;
|
|
738
740
|
};
|
|
739
741
|
//#endregion
|
|
740
742
|
//#region src/nodes/function.d.ts
|
|
@@ -1980,15 +1982,25 @@ type Node = InputNode | OutputNode | OperationNode | SchemaNode | PropertyNode |
|
|
|
1980
1982
|
*/
|
|
1981
1983
|
type ParserOptions = {
|
|
1982
1984
|
/**
|
|
1983
|
-
* How `format: 'date-time'` schemas are represented
|
|
1985
|
+
* How `format: 'date-time'` schemas are represented downstream.
|
|
1986
|
+
* - `false` falls through to a plain `string` (no validation).
|
|
1987
|
+
* - `'string'` emits a datetime string node.
|
|
1988
|
+
* - `'stringOffset'` emits a datetime node with timezone offset.
|
|
1989
|
+
* - `'stringLocal'` emits a local datetime node.
|
|
1990
|
+
* - `'date'` emits a `date` node (JavaScript `Date` object).
|
|
1984
1991
|
*/
|
|
1985
1992
|
dateType: false | 'string' | 'stringOffset' | 'stringLocal' | 'date';
|
|
1986
1993
|
/**
|
|
1987
|
-
*
|
|
1994
|
+
* How `type: 'integer'` (and `format: 'int64'`) maps to TypeScript.
|
|
1995
|
+
* - `'number'` fits most JSON APIs; loses precision above `Number.MAX_SAFE_INTEGER`.
|
|
1996
|
+
* - `'bigint'` is exact for 64-bit IDs, but does not round-trip through JSON.
|
|
1997
|
+
*
|
|
1998
|
+
* @default 'number'
|
|
1988
1999
|
*/
|
|
1989
2000
|
integerType?: 'number' | 'bigint';
|
|
1990
2001
|
/**
|
|
1991
|
-
* AST type used when
|
|
2002
|
+
* AST type used when a schema's type cannot be inferred from the spec
|
|
2003
|
+
* (`additionalProperties: true`, missing `type`, ...).
|
|
1992
2004
|
*/
|
|
1993
2005
|
unknownType: 'any' | 'unknown' | 'void';
|
|
1994
2006
|
/**
|
|
@@ -1996,7 +2008,8 @@ type ParserOptions = {
|
|
|
1996
2008
|
*/
|
|
1997
2009
|
emptySchemaType: 'any' | 'unknown' | 'void';
|
|
1998
2010
|
/**
|
|
1999
|
-
* Suffix appended to derived enum names when
|
|
2011
|
+
* Suffix appended to derived enum names when Kubb has to invent one
|
|
2012
|
+
* (typically for inline enums on object properties).
|
|
2000
2013
|
*/
|
|
2001
2014
|
enumSuffix: 'enum' | (string & {});
|
|
2002
2015
|
};
|
|
@@ -2117,10 +2130,13 @@ type InferSchema<TSchema extends object, TDateType extends ParserOptions['dateTy
|
|
|
2117
2130
|
//#endregion
|
|
2118
2131
|
//#region src/factory.d.ts
|
|
2119
2132
|
/**
|
|
2120
|
-
*
|
|
2133
|
+
* Updates a schema's `optional` and `nullish` flags from a parent's `required`
|
|
2134
|
+
* value and the schema's own `nullable`. Mirrors how OpenAPI parameters and
|
|
2135
|
+
* object properties combine "required" and "nullable" into a single AST.
|
|
2121
2136
|
*
|
|
2122
|
-
* -
|
|
2123
|
-
* -
|
|
2137
|
+
* - Non-required + non-nullable → `optional: true`.
|
|
2138
|
+
* - Non-required + nullable → `nullish: true`.
|
|
2139
|
+
* - Required → both flags cleared.
|
|
2124
2140
|
*/
|
|
2125
2141
|
declare function syncOptionality(schema: SchemaNode, required: boolean): SchemaNode;
|
|
2126
2142
|
/**
|
|
@@ -2845,22 +2861,27 @@ type PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) =
|
|
|
2845
2861
|
print?: (this: PrinterHandlerContext<T['output'], T['options']>, node: SchemaNode) => T['printOutput'] | null;
|
|
2846
2862
|
};
|
|
2847
2863
|
/**
|
|
2848
|
-
*
|
|
2849
|
-
*
|
|
2850
|
-
*
|
|
2864
|
+
* Defines a schema printer: a function that takes a `SchemaNode` and emits
|
|
2865
|
+
* code in your target language. Each plugin that produces code from schemas
|
|
2866
|
+
* (TypeScript types, Zod schemas, Faker factories) ships a printer built
|
|
2867
|
+
* with this helper.
|
|
2851
2868
|
*
|
|
2852
2869
|
* The builder receives resolved options and returns:
|
|
2853
|
-
* - `name` — a unique identifier for the printer
|
|
2854
|
-
* - `options` — options stored on the returned printer instance
|
|
2855
|
-
* - `nodes` — a map of `SchemaType` → handler functions that convert a `SchemaNode` to `TOutput`
|
|
2856
|
-
* - `print` _(optional)_ — top-level override exposed as `printer.print`
|
|
2857
|
-
* - Inside this function, use `this.transform(node)` to dispatch to the `nodes` map
|
|
2858
|
-
* - This keeps recursion safe and avoids self-calls
|
|
2859
2870
|
*
|
|
2860
|
-
*
|
|
2871
|
+
* - `name` — unique identifier for the printer.
|
|
2872
|
+
* - `options` — stored on the returned printer instance.
|
|
2873
|
+
* - `nodes` — map of `SchemaType` → handler. Handlers return the rendered
|
|
2874
|
+
* output (a string, a TypeScript AST node, ...) for that schema type.
|
|
2875
|
+
* - `print` (optional) — top-level override exposed as `printer.print`.
|
|
2876
|
+
* Use `this.transform(node)` inside it to dispatch to `nodes` recursively.
|
|
2877
|
+
*
|
|
2878
|
+
* Without a `print` override, `printer.print` falls back to `printer.transform`
|
|
2879
|
+
* (the node-level dispatcher).
|
|
2861
2880
|
*
|
|
2862
|
-
* @example
|
|
2881
|
+
* @example Tiny Zod printer
|
|
2863
2882
|
* ```ts
|
|
2883
|
+
* import { definePrinter, type PrinterFactoryOptions } from '@kubb/ast'
|
|
2884
|
+
*
|
|
2864
2885
|
* type PrinterZod = PrinterFactoryOptions<'zod', { strict?: boolean }, string>
|
|
2865
2886
|
*
|
|
2866
2887
|
* export const zodPrinter = definePrinter<PrinterZod>((options) => ({
|
|
@@ -2869,7 +2890,9 @@ type PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) =
|
|
|
2869
2890
|
* nodes: {
|
|
2870
2891
|
* string: () => 'z.string()',
|
|
2871
2892
|
* object(node) {
|
|
2872
|
-
* const props = node.properties
|
|
2893
|
+
* const props = node.properties
|
|
2894
|
+
* .map((p) => `${p.name}: ${this.transform(p.schema)}`)
|
|
2895
|
+
* .join(', ')
|
|
2873
2896
|
* return `z.object({ ${props} })`
|
|
2874
2897
|
* },
|
|
2875
2898
|
* },
|
|
@@ -3047,25 +3070,40 @@ type VisitorContext<T extends Node = Node> = {
|
|
|
3047
3070
|
parent?: ParentOf<T>;
|
|
3048
3071
|
};
|
|
3049
3072
|
/**
|
|
3050
|
-
* Synchronous visitor
|
|
3073
|
+
* Synchronous visitor consumed by `transform`. Each optional callback runs
|
|
3074
|
+
* for the matching node type. Return a new node to replace it, or `undefined`
|
|
3075
|
+
* to leave it untouched.
|
|
3051
3076
|
*
|
|
3052
|
-
*
|
|
3077
|
+
* Plugins typically expose `transformer` so users can supply a `Visitor` that
|
|
3078
|
+
* rewrites operation IDs, drops descriptions, or otherwise tweaks the AST
|
|
3079
|
+
* before printing.
|
|
3080
|
+
*
|
|
3081
|
+
* @example Prefix every operationId
|
|
3053
3082
|
* ```ts
|
|
3054
3083
|
* const visitor: Visitor = {
|
|
3055
3084
|
* operation(node) {
|
|
3056
|
-
* return { ...node, operationId: `
|
|
3085
|
+
* return { ...node, operationId: `api_${node.operationId}` }
|
|
3086
|
+
* },
|
|
3087
|
+
* }
|
|
3088
|
+
* ```
|
|
3089
|
+
*
|
|
3090
|
+
* @example Strip schema descriptions
|
|
3091
|
+
* ```ts
|
|
3092
|
+
* const visitor: Visitor = {
|
|
3093
|
+
* schema(node) {
|
|
3094
|
+
* return { ...node, description: undefined }
|
|
3057
3095
|
* },
|
|
3058
3096
|
* }
|
|
3059
3097
|
* ```
|
|
3060
3098
|
*/
|
|
3061
3099
|
type Visitor = {
|
|
3062
|
-
input?(node: InputNode, context: VisitorContext<InputNode>):
|
|
3063
|
-
output?(node: OutputNode, context: VisitorContext<OutputNode>):
|
|
3064
|
-
operation?(node: OperationNode, context: VisitorContext<OperationNode>):
|
|
3065
|
-
schema?(node: SchemaNode, context: VisitorContext<SchemaNode>):
|
|
3066
|
-
property?(node: PropertyNode, context: VisitorContext<PropertyNode>):
|
|
3067
|
-
parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>):
|
|
3068
|
-
response?(node: ResponseNode, context: VisitorContext<ResponseNode>):
|
|
3100
|
+
input?(node: InputNode, context: VisitorContext<InputNode>): undefined | null | InputNode;
|
|
3101
|
+
output?(node: OutputNode, context: VisitorContext<OutputNode>): undefined | null | OutputNode;
|
|
3102
|
+
operation?(node: OperationNode, context: VisitorContext<OperationNode>): undefined | null | OperationNode;
|
|
3103
|
+
schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): undefined | null | SchemaNode;
|
|
3104
|
+
property?(node: PropertyNode, context: VisitorContext<PropertyNode>): undefined | null | PropertyNode;
|
|
3105
|
+
parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): undefined | null | ParameterNode;
|
|
3106
|
+
response?(node: ResponseNode, context: VisitorContext<ResponseNode>): undefined | null | ResponseNode;
|
|
3069
3107
|
};
|
|
3070
3108
|
/**
|
|
3071
3109
|
* Utility type for values that can be returned directly or asynchronously.
|
|
@@ -3084,13 +3122,13 @@ type MaybePromise<T> = T | Promise<T>;
|
|
|
3084
3122
|
* ```
|
|
3085
3123
|
*/
|
|
3086
3124
|
type AsyncVisitor = {
|
|
3087
|
-
input?(node: InputNode, context: VisitorContext<InputNode>): MaybePromise<
|
|
3088
|
-
output?(node: OutputNode, context: VisitorContext<OutputNode>): MaybePromise<
|
|
3089
|
-
operation?(node: OperationNode, context: VisitorContext<OperationNode>): MaybePromise<
|
|
3090
|
-
schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): MaybePromise<
|
|
3091
|
-
property?(node: PropertyNode, context: VisitorContext<PropertyNode>): MaybePromise<
|
|
3092
|
-
parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): MaybePromise<
|
|
3093
|
-
response?(node: ResponseNode, context: VisitorContext<ResponseNode>): MaybePromise<
|
|
3125
|
+
input?(node: InputNode, context: VisitorContext<InputNode>): MaybePromise<undefined | null | InputNode>;
|
|
3126
|
+
output?(node: OutputNode, context: VisitorContext<OutputNode>): MaybePromise<undefined | null | OutputNode>;
|
|
3127
|
+
operation?(node: OperationNode, context: VisitorContext<OperationNode>): MaybePromise<undefined | null | OperationNode>;
|
|
3128
|
+
schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): MaybePromise<undefined | null | SchemaNode>;
|
|
3129
|
+
property?(node: PropertyNode, context: VisitorContext<PropertyNode>): MaybePromise<undefined | null | PropertyNode>;
|
|
3130
|
+
parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): MaybePromise<undefined | null | ParameterNode>;
|
|
3131
|
+
response?(node: ResponseNode, context: VisitorContext<ResponseNode>): MaybePromise<undefined | null | ResponseNode>;
|
|
3094
3132
|
};
|
|
3095
3133
|
/**
|
|
3096
3134
|
* Visitor used by `collect`.
|
|
@@ -3178,11 +3216,14 @@ type CollectOptions<T> = CollectVisitor<T> & {
|
|
|
3178
3216
|
parent?: Node;
|
|
3179
3217
|
};
|
|
3180
3218
|
/**
|
|
3181
|
-
*
|
|
3182
|
-
*
|
|
3183
|
-
* (default: `WALK_CONCURRENCY`).
|
|
3219
|
+
* Async depth-first traversal for side effects. Visitor return values are
|
|
3220
|
+
* ignored. Use `transform` when you want to rewrite nodes.
|
|
3184
3221
|
*
|
|
3185
|
-
*
|
|
3222
|
+
* Sibling nodes at each depth run concurrently up to `options.concurrency`
|
|
3223
|
+
* (defaults to `WALK_CONCURRENCY`). Higher values overlap I/O-bound visitor
|
|
3224
|
+
* work; lower values reduce memory pressure.
|
|
3225
|
+
*
|
|
3226
|
+
* @example Log every operation
|
|
3186
3227
|
* ```ts
|
|
3187
3228
|
* await walk(root, {
|
|
3188
3229
|
* operation(node) {
|
|
@@ -3191,20 +3232,20 @@ type CollectOptions<T> = CollectVisitor<T> & {
|
|
|
3191
3232
|
* })
|
|
3192
3233
|
* ```
|
|
3193
3234
|
*
|
|
3194
|
-
* @example
|
|
3235
|
+
* @example Only visit the root node
|
|
3195
3236
|
* ```ts
|
|
3196
|
-
*
|
|
3197
|
-
* await walk(root, { depth: 'shallow', root: () => {} })
|
|
3237
|
+
* await walk(root, { depth: 'shallow', input: () => {} })
|
|
3198
3238
|
* ```
|
|
3199
3239
|
*/
|
|
3200
3240
|
declare function walk(node: Node, options: WalkOptions): Promise<void>;
|
|
3201
3241
|
/**
|
|
3202
|
-
*
|
|
3242
|
+
* Synchronous depth-first transform. Each visitor callback gets a chance to
|
|
3243
|
+
* return a replacement node; `undefined` keeps the original.
|
|
3203
3244
|
*
|
|
3204
|
-
*
|
|
3205
|
-
*
|
|
3245
|
+
* The transform is immutable. The original tree is not mutated; a new tree
|
|
3246
|
+
* is returned. Use `depth: 'shallow'` to skip recursion into children.
|
|
3206
3247
|
*
|
|
3207
|
-
* @example
|
|
3248
|
+
* @example Prefix every operationId
|
|
3208
3249
|
* ```ts
|
|
3209
3250
|
* const next = transform(root, {
|
|
3210
3251
|
* operation(node) {
|
|
@@ -3213,10 +3254,12 @@ declare function walk(node: Node, options: WalkOptions): Promise<void>;
|
|
|
3213
3254
|
* })
|
|
3214
3255
|
* ```
|
|
3215
3256
|
*
|
|
3216
|
-
* @example
|
|
3257
|
+
* @example Replace only the root node
|
|
3217
3258
|
* ```ts
|
|
3218
|
-
*
|
|
3219
|
-
*
|
|
3259
|
+
* const next = transform(root, {
|
|
3260
|
+
* depth: 'shallow',
|
|
3261
|
+
* input: (node) => ({ ...node, meta: { ...node.meta, title: 'Rewritten' } }),
|
|
3262
|
+
* })
|
|
3220
3263
|
* ```
|
|
3221
3264
|
*/
|
|
3222
3265
|
declare function transform(node: InputNode, options: TransformOptions): InputNode;
|
|
@@ -3228,26 +3271,35 @@ declare function transform(node: ParameterNode, options: TransformOptions): Para
|
|
|
3228
3271
|
declare function transform(node: ResponseNode, options: TransformOptions): ResponseNode;
|
|
3229
3272
|
declare function transform(node: Node, options: TransformOptions): Node;
|
|
3230
3273
|
/**
|
|
3231
|
-
*
|
|
3232
|
-
*
|
|
3233
|
-
* Non-`null` values returned by visitor callbacks are appended to the result.
|
|
3274
|
+
* Lazy depth-first collection pass. Yields every non-null value returned by
|
|
3275
|
+
* the visitor callbacks. Use `collect` for the eager array form.
|
|
3234
3276
|
*
|
|
3235
|
-
* @example
|
|
3277
|
+
* @example Collect every operationId
|
|
3236
3278
|
* ```ts
|
|
3237
|
-
* const ids =
|
|
3279
|
+
* const ids: string[] = []
|
|
3280
|
+
* for (const id of collectLazy<string>(root, {
|
|
3238
3281
|
* operation(node) {
|
|
3239
3282
|
* return node.operationId
|
|
3240
3283
|
* },
|
|
3241
|
-
* })
|
|
3284
|
+
* })) {
|
|
3285
|
+
* ids.push(id)
|
|
3286
|
+
* }
|
|
3242
3287
|
* ```
|
|
3288
|
+
*/
|
|
3289
|
+
declare function collectLazy<T>(node: Node, options: CollectOptions<T>): Generator<T, void, undefined>;
|
|
3290
|
+
/**
|
|
3291
|
+
* Eager depth-first collection pass. Returns an array of every non-null value
|
|
3292
|
+
* the visitor callbacks return.
|
|
3243
3293
|
*
|
|
3244
|
-
* @example
|
|
3294
|
+
* @example Collect every operationId
|
|
3245
3295
|
* ```ts
|
|
3246
|
-
*
|
|
3247
|
-
*
|
|
3296
|
+
* const ids = collect<string>(root, {
|
|
3297
|
+
* operation(node) {
|
|
3298
|
+
* return node.operationId
|
|
3299
|
+
* },
|
|
3300
|
+
* })
|
|
3248
3301
|
* ```
|
|
3249
3302
|
*/
|
|
3250
|
-
declare function collectLazy<T>(node: Node, options: CollectOptions<T>): Generator<T, void, undefined>;
|
|
3251
3303
|
declare function collect<T>(node: Node, options: CollectOptions<T>): Array<T>;
|
|
3252
3304
|
//#endregion
|
|
3253
3305
|
//#region src/utils.d.ts
|
package/dist/index.js
CHANGED
|
@@ -587,11 +587,14 @@ function* getChildren(node, recurse) {
|
|
|
587
587
|
}
|
|
588
588
|
}
|
|
589
589
|
/**
|
|
590
|
-
*
|
|
591
|
-
*
|
|
592
|
-
* (default: `WALK_CONCURRENCY`).
|
|
590
|
+
* Async depth-first traversal for side effects. Visitor return values are
|
|
591
|
+
* ignored. Use `transform` when you want to rewrite nodes.
|
|
593
592
|
*
|
|
594
|
-
*
|
|
593
|
+
* Sibling nodes at each depth run concurrently up to `options.concurrency`
|
|
594
|
+
* (defaults to `WALK_CONCURRENCY`). Higher values overlap I/O-bound visitor
|
|
595
|
+
* work; lower values reduce memory pressure.
|
|
596
|
+
*
|
|
597
|
+
* @example Log every operation
|
|
595
598
|
* ```ts
|
|
596
599
|
* await walk(root, {
|
|
597
600
|
* operation(node) {
|
|
@@ -600,10 +603,9 @@ function* getChildren(node, recurse) {
|
|
|
600
603
|
* })
|
|
601
604
|
* ```
|
|
602
605
|
*
|
|
603
|
-
* @example
|
|
606
|
+
* @example Only visit the root node
|
|
604
607
|
* ```ts
|
|
605
|
-
*
|
|
606
|
-
* await walk(root, { depth: 'shallow', root: () => {} })
|
|
608
|
+
* await walk(root, { depth: 'shallow', input: () => {} })
|
|
607
609
|
* ```
|
|
608
610
|
*/
|
|
609
611
|
async function walk(node, options) {
|
|
@@ -725,23 +727,19 @@ function transform(node, options) {
|
|
|
725
727
|
return node;
|
|
726
728
|
}
|
|
727
729
|
/**
|
|
728
|
-
*
|
|
730
|
+
* Lazy depth-first collection pass. Yields every non-null value returned by
|
|
731
|
+
* the visitor callbacks. Use `collect` for the eager array form.
|
|
729
732
|
*
|
|
730
|
-
*
|
|
731
|
-
*
|
|
732
|
-
* @example
|
|
733
|
+
* @example Collect every operationId
|
|
733
734
|
* ```ts
|
|
734
|
-
* const ids =
|
|
735
|
+
* const ids: string[] = []
|
|
736
|
+
* for (const id of collectLazy<string>(root, {
|
|
735
737
|
* operation(node) {
|
|
736
738
|
* return node.operationId
|
|
737
739
|
* },
|
|
738
|
-
* })
|
|
739
|
-
*
|
|
740
|
-
*
|
|
741
|
-
* @example
|
|
742
|
-
* ```ts
|
|
743
|
-
* // Collect from only the current node
|
|
744
|
-
* const values = collect(root, { depth: 'shallow', root: () => 'root' })
|
|
740
|
+
* })) {
|
|
741
|
+
* ids.push(id)
|
|
742
|
+
* }
|
|
745
743
|
* ```
|
|
746
744
|
*/
|
|
747
745
|
function* collectLazy(node, options) {
|
|
@@ -777,6 +775,19 @@ function* collectLazy(node, options) {
|
|
|
777
775
|
parent: node
|
|
778
776
|
});
|
|
779
777
|
}
|
|
778
|
+
/**
|
|
779
|
+
* Eager depth-first collection pass. Returns an array of every non-null value
|
|
780
|
+
* the visitor callbacks return.
|
|
781
|
+
*
|
|
782
|
+
* @example Collect every operationId
|
|
783
|
+
* ```ts
|
|
784
|
+
* const ids = collect<string>(root, {
|
|
785
|
+
* operation(node) {
|
|
786
|
+
* return node.operationId
|
|
787
|
+
* },
|
|
788
|
+
* })
|
|
789
|
+
* ```
|
|
790
|
+
*/
|
|
780
791
|
function collect(node, options) {
|
|
781
792
|
return Array.from(collectLazy(node, options));
|
|
782
793
|
}
|
|
@@ -1402,10 +1413,13 @@ function containsCircularRef(node, { circularSchemas, excludeName }) {
|
|
|
1402
1413
|
//#endregion
|
|
1403
1414
|
//#region src/factory.ts
|
|
1404
1415
|
/**
|
|
1405
|
-
*
|
|
1416
|
+
* Updates a schema's `optional` and `nullish` flags from a parent's `required`
|
|
1417
|
+
* value and the schema's own `nullable`. Mirrors how OpenAPI parameters and
|
|
1418
|
+
* object properties combine "required" and "nullable" into a single AST.
|
|
1406
1419
|
*
|
|
1407
|
-
* -
|
|
1408
|
-
* -
|
|
1420
|
+
* - Non-required + non-nullable → `optional: true`.
|
|
1421
|
+
* - Non-required + nullable → `nullish: true`.
|
|
1422
|
+
* - Required → both flags cleared.
|
|
1409
1423
|
*/
|
|
1410
1424
|
function syncOptionality(schema, required) {
|
|
1411
1425
|
const nullable = schema.nullable ?? false;
|
|
@@ -2045,22 +2059,27 @@ function createJsx(value) {
|
|
|
2045
2059
|
//#endregion
|
|
2046
2060
|
//#region src/printer.ts
|
|
2047
2061
|
/**
|
|
2048
|
-
*
|
|
2049
|
-
*
|
|
2050
|
-
*
|
|
2062
|
+
* Defines a schema printer: a function that takes a `SchemaNode` and emits
|
|
2063
|
+
* code in your target language. Each plugin that produces code from schemas
|
|
2064
|
+
* (TypeScript types, Zod schemas, Faker factories) ships a printer built
|
|
2065
|
+
* with this helper.
|
|
2051
2066
|
*
|
|
2052
2067
|
* The builder receives resolved options and returns:
|
|
2053
|
-
* - `name` — a unique identifier for the printer
|
|
2054
|
-
* - `options` — options stored on the returned printer instance
|
|
2055
|
-
* - `nodes` — a map of `SchemaType` → handler functions that convert a `SchemaNode` to `TOutput`
|
|
2056
|
-
* - `print` _(optional)_ — top-level override exposed as `printer.print`
|
|
2057
|
-
* - Inside this function, use `this.transform(node)` to dispatch to the `nodes` map
|
|
2058
|
-
* - This keeps recursion safe and avoids self-calls
|
|
2059
2068
|
*
|
|
2060
|
-
*
|
|
2069
|
+
* - `name` — unique identifier for the printer.
|
|
2070
|
+
* - `options` — stored on the returned printer instance.
|
|
2071
|
+
* - `nodes` — map of `SchemaType` → handler. Handlers return the rendered
|
|
2072
|
+
* output (a string, a TypeScript AST node, ...) for that schema type.
|
|
2073
|
+
* - `print` (optional) — top-level override exposed as `printer.print`.
|
|
2074
|
+
* Use `this.transform(node)` inside it to dispatch to `nodes` recursively.
|
|
2061
2075
|
*
|
|
2062
|
-
*
|
|
2076
|
+
* Without a `print` override, `printer.print` falls back to `printer.transform`
|
|
2077
|
+
* (the node-level dispatcher).
|
|
2078
|
+
*
|
|
2079
|
+
* @example Tiny Zod printer
|
|
2063
2080
|
* ```ts
|
|
2081
|
+
* import { definePrinter, type PrinterFactoryOptions } from '@kubb/ast'
|
|
2082
|
+
*
|
|
2064
2083
|
* type PrinterZod = PrinterFactoryOptions<'zod', { strict?: boolean }, string>
|
|
2065
2084
|
*
|
|
2066
2085
|
* export const zodPrinter = definePrinter<PrinterZod>((options) => ({
|
|
@@ -2069,7 +2088,9 @@ function createJsx(value) {
|
|
|
2069
2088
|
* nodes: {
|
|
2070
2089
|
* string: () => 'z.string()',
|
|
2071
2090
|
* object(node) {
|
|
2072
|
-
* const props = node.properties
|
|
2091
|
+
* const props = node.properties
|
|
2092
|
+
* .map((p) => `${p.name}: ${this.transform(p.schema)}`)
|
|
2093
|
+
* .join(', ')
|
|
2073
2094
|
* return `z.object({ ${props} })`
|
|
2074
2095
|
* },
|
|
2075
2096
|
* },
|