@kubb/ast 5.0.0-alpha.12 → 5.0.0-alpha.14

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.
@@ -529,6 +529,10 @@ type OperationNode = BaseNode & {
529
529
  * Request body for OAS operations. Bundles the schema with optional keys to exclude.
530
530
  */
531
531
  requestBody?: {
532
+ /**
533
+ * Human-readable description of the request body (maps to `requestBody.description` in OAS).
534
+ */
535
+ description?: string;
532
536
  /**
533
537
  * The request body schema. For OAS, this is the schema of the first content entry.
534
538
  */
@@ -619,12 +623,19 @@ declare function createSchema<T extends DistributiveOmit<Exclude<SchemaNode, Obj
619
623
  kind: 'Schema';
620
624
  };
621
625
  declare function createSchema(props: DistributiveOmit<SchemaNode, 'kind'>): SchemaNode;
626
+ /**
627
+ * Derives `schema.optional` and `schema.nullish` from `required` and `schema.nullable`.
628
+ * This keeps `PropertyNode.required` as the single source of truth for optionality.
629
+ */
630
+ declare function syncPropertySchema(required: boolean, schema: SchemaNode): SchemaNode;
622
631
  /**
623
632
  * Creates a `PropertyNode`. `required` defaults to `false`.
633
+ * `schema.optional` and `schema.nullish` are auto-derived from `required` and `schema.nullable`.
624
634
  */
625
635
  declare function createProperty(props: Pick<PropertyNode, 'name' | 'schema'> & Partial<Omit<PropertyNode, 'kind' | 'name' | 'schema'>>): PropertyNode;
626
636
  /**
627
637
  * Creates a `ParameterNode`. `required` defaults to `false`.
638
+ * `schema.optional` is auto-derived from `required` and `schema.nullable`.
628
639
  */
629
640
  declare function createParameter(props: Pick<ParameterNode, 'name' | 'in' | 'schema'> & Partial<Omit<ParameterNode, 'kind' | 'name' | 'in' | 'schema'>>): ParameterNode;
630
641
  /**
@@ -848,69 +859,103 @@ declare function refMapToObject(refMap: RefMap): Record<string, SchemaNode>;
848
859
  //#endregion
849
860
  //#region src/visitor.d.ts
850
861
  /**
851
- * Shared options for `walk`, `transform`, and `collect`.
862
+ * Single source of truth: ordered list of `[NodeType, ParentType]` pairs
863
+ * describing which node types can be the parent of a given node in the AST.
864
+ *
865
+ * `ParentOf` walks this tuple and returns the parent type of the first matching entry.
852
866
  */
853
- type VisitorOptions = {
854
- depth?: VisitorDepth;
855
- /**
856
- * Maximum number of sibling nodes visited concurrently inside `walk`.
857
- * @default 30
858
- */
859
- concurrency?: number;
867
+ type ParentNodeMap = [[RootNode, undefined], [OperationNode, RootNode], [SchemaNode, RootNode | OperationNode | SchemaNode | PropertyNode | ParameterNode | ResponseNode], [PropertyNode, SchemaNode], [ParameterNode, OperationNode], [ResponseNode, OperationNode]];
868
+ type ParentOf<T extends Node, TEntries extends ReadonlyArray<[Node, unknown]> = ParentNodeMap> = TEntries extends [infer TEntry extends [Node, unknown], ...infer TRest extends ReadonlyArray<[Node, unknown]>] ? T extends TEntry[0] ? TEntry[1] : ParentOf<T, TRest> : Node;
869
+ /**
870
+ * Traversal context passed as the second argument to every visitor callback.
871
+ * The `parent` field is narrowed based on the node type being visited.
872
+ */
873
+ type VisitorContext<T extends Node = Node> = {
874
+ parent?: ParentOf<T>;
860
875
  };
861
876
  /**
862
877
  * Synchronous visitor for `transform` and `walk`.
863
878
  */
864
879
  type Visitor = {
865
- root?(node: RootNode): void | RootNode;
866
- operation?(node: OperationNode): void | OperationNode;
867
- schema?(node: SchemaNode): void | SchemaNode;
868
- property?(node: PropertyNode): void | PropertyNode;
869
- parameter?(node: ParameterNode): void | ParameterNode;
870
- response?(node: ResponseNode): void | ResponseNode;
880
+ root?(node: RootNode, context: VisitorContext<RootNode>): void | RootNode;
881
+ operation?(node: OperationNode, context: VisitorContext<OperationNode>): void | OperationNode;
882
+ schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): void | SchemaNode;
883
+ property?(node: PropertyNode, context: VisitorContext<PropertyNode>): void | PropertyNode;
884
+ parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): void | ParameterNode;
885
+ response?(node: ResponseNode, context: VisitorContext<ResponseNode>): void | ResponseNode;
871
886
  };
872
887
  type MaybePromise<T> = T | Promise<T>;
873
888
  /**
874
889
  * Async visitor for `walk`. Synchronous `Visitor` objects are compatible.
875
890
  */
876
891
  type AsyncVisitor = {
877
- root?(node: RootNode): MaybePromise<void | RootNode>;
878
- operation?(node: OperationNode): MaybePromise<void | OperationNode>;
879
- schema?(node: SchemaNode): MaybePromise<void | SchemaNode>;
880
- property?(node: PropertyNode): MaybePromise<void | PropertyNode>;
881
- parameter?(node: ParameterNode): MaybePromise<void | ParameterNode>;
882
- response?(node: ResponseNode): MaybePromise<void | ResponseNode>;
892
+ root?(node: RootNode, context: VisitorContext<RootNode>): MaybePromise<void | RootNode>;
893
+ operation?(node: OperationNode, context: VisitorContext<OperationNode>): MaybePromise<void | OperationNode>;
894
+ schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): MaybePromise<void | SchemaNode>;
895
+ property?(node: PropertyNode, context: VisitorContext<PropertyNode>): MaybePromise<void | PropertyNode>;
896
+ parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): MaybePromise<void | ParameterNode>;
897
+ response?(node: ResponseNode, context: VisitorContext<ResponseNode>): MaybePromise<void | ResponseNode>;
883
898
  };
884
899
  /**
885
900
  * Visitor for `collect`.
886
901
  */
887
902
  type CollectVisitor<T> = {
888
- root?(node: RootNode): T | undefined;
889
- operation?(node: OperationNode): T | undefined;
890
- schema?(node: SchemaNode): T | undefined;
891
- property?(node: PropertyNode): T | undefined;
892
- parameter?(node: ParameterNode): T | undefined;
893
- response?(node: ResponseNode): T | undefined;
903
+ root?(node: RootNode, context: VisitorContext<RootNode>): T | undefined;
904
+ operation?(node: OperationNode, context: VisitorContext<OperationNode>): T | undefined;
905
+ schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): T | undefined;
906
+ property?(node: PropertyNode, context: VisitorContext<PropertyNode>): T | undefined;
907
+ parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): T | undefined;
908
+ response?(node: ResponseNode, context: VisitorContext<ResponseNode>): T | undefined;
909
+ };
910
+ /**
911
+ * Options for `transform` and `collect`. Extends `Visitor` with traversal settings.
912
+ */
913
+ type TransformOptions = Visitor & {
914
+ depth?: VisitorDepth;
915
+ parent?: Node;
916
+ };
917
+ /**
918
+ * Options for `walk`. Extends `AsyncVisitor` with traversal settings.
919
+ */
920
+ type WalkOptions = AsyncVisitor & {
921
+ depth?: VisitorDepth;
922
+ /**
923
+ * Maximum number of sibling nodes visited concurrently.
924
+ * @default 30
925
+ */
926
+ concurrency?: number;
927
+ };
928
+ /**
929
+ * Options for `collect`. Extends `CollectVisitor` with traversal settings.
930
+ */
931
+ type CollectOptions<T> = CollectVisitor<T> & {
932
+ depth?: VisitorDepth;
933
+ parent?: Node;
894
934
  };
895
935
  /**
896
936
  * Depth-first traversal for side effects. Visitor return values are ignored.
897
937
  * Sibling nodes at each level are visited concurrently up to `options.concurrency` (default: 30).
898
938
  */
899
- declare function walk(node: Node, visitor: AsyncVisitor, options?: VisitorOptions): Promise<void>;
939
+ declare function walk(node: Node, options: WalkOptions): Promise<void>;
900
940
  /**
901
941
  * Depth-first immutable transformation. Visitor return values replace nodes; `undefined` keeps the original.
902
942
  */
903
- declare function transform(node: RootNode, visitor: Visitor, options?: VisitorOptions): RootNode;
904
- declare function transform(node: OperationNode, visitor: Visitor, options?: VisitorOptions): OperationNode;
905
- declare function transform(node: SchemaNode, visitor: Visitor, options?: VisitorOptions): SchemaNode;
906
- declare function transform(node: PropertyNode, visitor: Visitor, options?: VisitorOptions): PropertyNode;
907
- declare function transform(node: ParameterNode, visitor: Visitor, options?: VisitorOptions): ParameterNode;
908
- declare function transform(node: ResponseNode, visitor: Visitor, options?: VisitorOptions): ResponseNode;
909
- declare function transform(node: Node, visitor: Visitor, options?: VisitorOptions): Node;
943
+ declare function transform(node: RootNode, options: TransformOptions): RootNode;
944
+ declare function transform(node: OperationNode, options: TransformOptions): OperationNode;
945
+ declare function transform(node: SchemaNode, options: TransformOptions): SchemaNode;
946
+ declare function transform(node: PropertyNode, options: TransformOptions): PropertyNode;
947
+ declare function transform(node: ParameterNode, options: TransformOptions): ParameterNode;
948
+ declare function transform(node: ResponseNode, options: TransformOptions): ResponseNode;
949
+ declare function transform(node: Node, options: TransformOptions): Node;
950
+ /**
951
+ * Combines multiple visitors into a single visitor that applies them sequentially (left to right).
952
+ * For each node kind, the output of one visitor becomes the input of the next.
953
+ */
954
+ declare function composeTransformers(...visitors: Array<Visitor>): Visitor;
910
955
  /**
911
956
  * Depth-first synchronous reduction. Collects non-`undefined` visitor return values into an array.
912
957
  */
913
- declare function collect<T>(node: Node, visitor: CollectVisitor<T>, options?: VisitorOptions): Array<T>;
958
+ declare function collect<T>(node: Node, options: CollectOptions<T>): Array<T>;
914
959
  //#endregion
915
- export { TimeSchemaNode as $, HttpStatusCode as A, EnumValueNode as B, createSchema as C, HttpMethod as D, RootNode as E, ArraySchemaNode as F, RefSchemaNode as G, NumberSchemaNode as H, ComplexSchemaType as I, SchemaNode as J, ScalarSchemaNode as K, DateSchemaNode as L, StatusCode as M, ParameterLocation as N, OperationNode as O, ParameterNode as P, StringSchemaNode as Q, DatetimeSchemaNode as R, createRoot as S, RootMeta as T, ObjectSchemaNode as U, IntersectionSchemaNode as V, PrimitiveSchemaType as W, SchemaType as X, SchemaNodeByType as Y, SpecialSchemaType as Z, createObjectBindingParameter as _, transform as a, FunctionParameterNode as at, createProperty as b, buildRefMap as c, BaseNode as ct, Printer as d, httpMethods as dt, UnionSchemaNode as et, PrinterFactoryOptions as f, mediaTypes as ft, createFunctionParameters as g, createFunctionParameter as h, collect as i, FunctionNodeType as it, MediaType as j, ResponseNode as k, refMapToObject as l, NodeKind as lt, DistributiveOmit as m, schemaTypes as mt, CollectVisitor as n, PropertyNode as nt, walk as o, FunctionParametersNode as ot, definePrinter as p, nodeKinds as pt, ScalarSchemaType as q, Visitor as r, FunctionNode as rt, RefMap as s, ObjectBindingParameterNode as st, AsyncVisitor as t, UrlSchemaNode as tt, resolveRef as u, VisitorDepth as ut, createOperation as v, Node as w, createResponse as x, createParameter as y, EnumSchemaNode as z };
916
- //# sourceMappingURL=visitor-C73H2CCg.d.ts.map
960
+ export { ScalarSchemaNode as $, syncPropertySchema as A, ParameterLocation as B, createObjectBindingParameter as C, createResponse as D, createProperty as E, OperationNode as F, DatetimeSchemaNode as G, ArraySchemaNode as H, ResponseNode as I, IntersectionSchemaNode as J, EnumSchemaNode as K, HttpStatusCode as L, RootMeta as M, RootNode as N, createRoot as O, HttpMethod as P, RefSchemaNode as Q, MediaType as R, createFunctionParameters as S, createParameter as T, ComplexSchemaType as U, ParameterNode as V, DateSchemaNode as W, ObjectSchemaNode as X, NumberSchemaNode as Y, PrimitiveSchemaType as Z, Printer as _, VisitorDepth as _t, TransformOptions as a, StringSchemaNode as at, DistributiveOmit as b, nodeKinds as bt, WalkOptions as c, UrlSchemaNode as ct, transform as d, FunctionNodeType as dt, ScalarSchemaType as et, walk as f, FunctionParameterNode as ft, resolveRef as g, NodeKind as gt, refMapToObject as h, BaseNode as ht, ParentOf as i, SpecialSchemaType as it, Node as j, createSchema as k, collect as l, PropertyNode as lt, buildRefMap as m, ObjectBindingParameterNode as mt, CollectOptions as n, SchemaNodeByType as nt, Visitor as o, TimeSchemaNode as ot, RefMap as p, FunctionParametersNode as pt, EnumValueNode as q, CollectVisitor as r, SchemaType as rt, VisitorContext as s, UnionSchemaNode as st, AsyncVisitor as t, SchemaNode as tt, composeTransformers as u, FunctionNode as ut, PrinterFactoryOptions as v, httpMethods as vt, createOperation as w, createFunctionParameter as x, schemaTypes as xt, definePrinter as y, mediaTypes as yt, StatusCode as z };
961
+ //# sourceMappingURL=visitor-UlWOe-In.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/ast",
3
- "version": "5.0.0-alpha.12",
3
+ "version": "5.0.0-alpha.14",
4
4
  "description": "Spec-agnostic AST layer for Kubb. Defines nodes, visitor pattern, and factory functions used across codegen plugins.",
5
5
  "keywords": [
6
6
  "kubb",
package/src/factory.ts CHANGED
@@ -60,27 +60,48 @@ export function createSchema(props: Record<string, unknown>): Record<string, unk
60
60
  return { ...props, kind: 'Schema' }
61
61
  }
62
62
 
63
+ /**
64
+ * Derives `schema.optional` and `schema.nullish` from `required` and `schema.nullable`.
65
+ * This keeps `PropertyNode.required` as the single source of truth for optionality.
66
+ */
67
+ export function syncPropertySchema(required: boolean, schema: SchemaNode): SchemaNode {
68
+ const nullable = schema.nullable ?? false
69
+
70
+ return {
71
+ ...schema,
72
+ optional: !required && !nullable ? true : undefined,
73
+ nullish: !required && nullable ? true : undefined,
74
+ }
75
+ }
76
+
63
77
  /**
64
78
  * Creates a `PropertyNode`. `required` defaults to `false`.
79
+ * `schema.optional` and `schema.nullish` are auto-derived from `required` and `schema.nullable`.
65
80
  */
66
81
  export function createProperty(props: Pick<PropertyNode, 'name' | 'schema'> & Partial<Omit<PropertyNode, 'kind' | 'name' | 'schema'>>): PropertyNode {
82
+ const required = props.required ?? false
83
+
67
84
  return {
68
- required: false,
69
85
  ...props,
70
86
  kind: 'Property',
87
+ required,
88
+ schema: syncPropertySchema(required, props.schema),
71
89
  }
72
90
  }
73
91
 
74
92
  /**
75
93
  * Creates a `ParameterNode`. `required` defaults to `false`.
94
+ * `schema.optional` is auto-derived from `required` and `schema.nullable`.
76
95
  */
77
96
  export function createParameter(
78
97
  props: Pick<ParameterNode, 'name' | 'in' | 'schema'> & Partial<Omit<ParameterNode, 'kind' | 'name' | 'in' | 'schema'>>,
79
98
  ): ParameterNode {
99
+ const required = props.required ?? false
80
100
  return {
81
- required: false,
82
101
  ...props,
83
102
  kind: 'Parameter',
103
+ required,
104
+ schema: syncPropertySchema(required, props.schema),
84
105
  }
85
106
  }
86
107
 
package/src/index.ts CHANGED
@@ -9,6 +9,7 @@ export {
9
9
  createResponse,
10
10
  createRoot,
11
11
  createSchema,
12
+ syncPropertySchema,
12
13
  } from './factory.ts'
13
14
  export { functionPrinter } from './functionPrinter.ts'
14
15
  export {
@@ -26,4 +27,4 @@ export {
26
27
  export { definePrinter } from './printer.ts'
27
28
  export { buildRefMap, refMapToObject, resolveRef } from './refs.ts'
28
29
  export { applyParamsCasing, isPlainStringType } from './utils.ts'
29
- export { collect, transform, walk } from './visitor.ts'
30
+ export { collect, composeTransformers, transform, walk } from './visitor.ts'
@@ -29,6 +29,10 @@ export type OperationNode = BaseNode & {
29
29
  * Request body for OAS operations. Bundles the schema with optional keys to exclude.
30
30
  */
31
31
  requestBody?: {
32
+ /**
33
+ * Human-readable description of the request body (maps to `requestBody.description` in OAS).
34
+ */
35
+ description?: string
32
36
  /**
33
37
  * The request body schema. For OAS, this is the schema of the first content entry.
34
38
  */
package/src/types.ts CHANGED
@@ -44,4 +44,4 @@ export type {
44
44
  } from './nodes/index.ts'
45
45
  export type { Printer, PrinterFactoryOptions } from './printer.ts'
46
46
  export type { RefMap } from './refs.ts'
47
- export type { AsyncVisitor, CollectVisitor, Visitor } from './visitor.ts'
47
+ export type { AsyncVisitor, CollectOptions, CollectVisitor, ParentOf, TransformOptions, Visitor, VisitorContext, WalkOptions } from './visitor.ts'