@kubb/ast 5.0.0-alpha.13 → 5.0.0-alpha.15

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 CHANGED
@@ -112,23 +112,41 @@ function createSchema(props) {
112
112
  };
113
113
  }
114
114
  /**
115
+ * Derives `schema.optional` and `schema.nullish` from `required` and `schema.nullable`.
116
+ * This keeps `PropertyNode.required` as the single source of truth for optionality.
117
+ */
118
+ function syncPropertySchema(required, schema) {
119
+ const nullable = schema.nullable ?? false;
120
+ return {
121
+ ...schema,
122
+ optional: !required && !nullable ? true : void 0,
123
+ nullish: !required && nullable ? true : void 0
124
+ };
125
+ }
126
+ /**
115
127
  * Creates a `PropertyNode`. `required` defaults to `false`.
128
+ * `schema.optional` and `schema.nullish` are auto-derived from `required` and `schema.nullable`.
116
129
  */
117
130
  function createProperty(props) {
131
+ const required = props.required ?? false;
118
132
  return {
119
- required: false,
120
133
  ...props,
121
- kind: "Property"
134
+ kind: "Property",
135
+ required,
136
+ schema: syncPropertySchema(required, props.schema)
122
137
  };
123
138
  }
124
139
  /**
125
140
  * Creates a `ParameterNode`. `required` defaults to `false`.
141
+ * `schema.optional` is auto-derived from `required` and `schema.nullable`.
126
142
  */
127
143
  function createParameter(props) {
144
+ const required = props.required ?? false;
128
145
  return {
129
- required: false,
130
146
  ...props,
131
- kind: "Parameter"
147
+ kind: "Parameter",
148
+ required,
149
+ schema: syncPropertySchema(required, props.schema)
132
150
  };
133
151
  }
134
152
  /**
@@ -854,103 +872,129 @@ function getChildren(node, recurse) {
854
872
  * Depth-first traversal for side effects. Visitor return values are ignored.
855
873
  * Sibling nodes at each level are visited concurrently up to `options.concurrency` (default: 30).
856
874
  */
857
- async function walk(node, visitor, options = {}) {
858
- return _walk(node, visitor, (options.depth ?? visitorDepths.deep) === visitorDepths.deep, createLimit(options.concurrency ?? 30));
875
+ async function walk(node, options) {
876
+ return _walk(node, options, (options.depth ?? visitorDepths.deep) === visitorDepths.deep, createLimit(options.concurrency ?? 30), void 0);
859
877
  }
860
- /**
861
- * Internal recursive walk implementation — calls visitor then recurses into children.
862
- */
863
- async function _walk(node, visitor, recurse, limit) {
878
+ async function _walk(node, visitor, recurse, limit, parent) {
864
879
  switch (node.kind) {
865
880
  case "Root":
866
- await limit(() => visitor.root?.(node));
881
+ await limit(() => visitor.root?.(node, { parent }));
867
882
  break;
868
883
  case "Operation":
869
- await limit(() => visitor.operation?.(node));
884
+ await limit(() => visitor.operation?.(node, { parent }));
870
885
  break;
871
886
  case "Schema":
872
- await limit(() => visitor.schema?.(node));
887
+ await limit(() => visitor.schema?.(node, { parent }));
873
888
  break;
874
889
  case "Property":
875
- await limit(() => visitor.property?.(node));
890
+ await limit(() => visitor.property?.(node, { parent }));
876
891
  break;
877
892
  case "Parameter":
878
- await limit(() => visitor.parameter?.(node));
893
+ await limit(() => visitor.parameter?.(node, { parent }));
879
894
  break;
880
895
  case "Response":
881
- await limit(() => visitor.response?.(node));
896
+ await limit(() => visitor.response?.(node, { parent }));
882
897
  break;
883
898
  case "FunctionParameter":
884
899
  case "ObjectBindingParameter":
885
900
  case "FunctionParameters": break;
886
901
  }
887
902
  const children = getChildren(node, recurse);
888
- await Promise.all(children.map((child) => _walk(child, visitor, recurse, limit)));
903
+ await Promise.all(children.map((child) => _walk(child, visitor, recurse, limit, node)));
889
904
  }
890
- function transform(node, visitor, options = {}) {
891
- const recurse = (options.depth ?? visitorDepths.deep) === visitorDepths.deep;
905
+ function transform(node, options) {
906
+ const { depth, parent, ...visitor } = options;
907
+ const recurse = (depth ?? visitorDepths.deep) === visitorDepths.deep;
892
908
  switch (node.kind) {
893
909
  case "Root": {
894
910
  let root = node;
895
- const replaced = visitor.root?.(root);
911
+ const replaced = visitor.root?.(root, { parent });
896
912
  if (replaced) root = replaced;
897
913
  return {
898
914
  ...root,
899
- schemas: root.schemas.map((s) => transform(s, visitor, options)),
900
- operations: root.operations.map((op) => transform(op, visitor, options))
915
+ schemas: root.schemas.map((s) => transform(s, {
916
+ ...options,
917
+ parent: root
918
+ })),
919
+ operations: root.operations.map((op) => transform(op, {
920
+ ...options,
921
+ parent: root
922
+ }))
901
923
  };
902
924
  }
903
925
  case "Operation": {
904
926
  let op = node;
905
- const replaced = visitor.operation?.(op);
927
+ const replaced = visitor.operation?.(op, { parent });
906
928
  if (replaced) op = replaced;
907
929
  return {
908
930
  ...op,
909
- parameters: op.parameters.map((p) => transform(p, visitor, options)),
931
+ parameters: op.parameters.map((p) => transform(p, {
932
+ ...options,
933
+ parent: op
934
+ })),
910
935
  requestBody: op.requestBody ? {
911
936
  ...op.requestBody,
912
- schema: op.requestBody.schema ? transform(op.requestBody.schema, visitor, options) : void 0
937
+ schema: op.requestBody.schema ? transform(op.requestBody.schema, {
938
+ ...options,
939
+ parent: op
940
+ }) : void 0
913
941
  } : void 0,
914
- responses: op.responses.map((r) => transform(r, visitor, options))
942
+ responses: op.responses.map((r) => transform(r, {
943
+ ...options,
944
+ parent: op
945
+ }))
915
946
  };
916
947
  }
917
948
  case "Schema": {
918
949
  let schema = node;
919
- const replaced = visitor.schema?.(schema);
950
+ const replaced = visitor.schema?.(schema, { parent });
920
951
  if (replaced) schema = replaced;
952
+ const childOptions = {
953
+ ...options,
954
+ parent: schema
955
+ };
921
956
  return {
922
957
  ...schema,
923
- ..."properties" in schema && recurse ? { properties: schema.properties.map((p) => transform(p, visitor, options)) } : {},
924
- ..."items" in schema && recurse ? { items: schema.items?.map((i) => transform(i, visitor, options)) } : {},
925
- ..."members" in schema && recurse ? { members: schema.members?.map((m) => transform(m, visitor, options)) } : {},
926
- ..."additionalProperties" in schema && recurse && schema.additionalProperties && schema.additionalProperties !== true ? { additionalProperties: transform(schema.additionalProperties, visitor, options) } : {}
958
+ ..."properties" in schema && recurse ? { properties: schema.properties.map((p) => transform(p, childOptions)) } : {},
959
+ ..."items" in schema && recurse ? { items: schema.items?.map((i) => transform(i, childOptions)) } : {},
960
+ ..."members" in schema && recurse ? { members: schema.members?.map((m) => transform(m, childOptions)) } : {},
961
+ ..."additionalProperties" in schema && recurse && schema.additionalProperties && schema.additionalProperties !== true ? { additionalProperties: transform(schema.additionalProperties, childOptions) } : {}
927
962
  };
928
963
  }
929
964
  case "Property": {
930
965
  let prop = node;
931
- const replaced = visitor.property?.(prop);
966
+ const replaced = visitor.property?.(prop, { parent });
932
967
  if (replaced) prop = replaced;
933
- return {
968
+ return createProperty({
934
969
  ...prop,
935
- schema: transform(prop.schema, visitor, options)
936
- };
970
+ schema: transform(prop.schema, {
971
+ ...options,
972
+ parent: prop
973
+ })
974
+ });
937
975
  }
938
976
  case "Parameter": {
939
977
  let param = node;
940
- const replaced = visitor.parameter?.(param);
978
+ const replaced = visitor.parameter?.(param, { parent });
941
979
  if (replaced) param = replaced;
942
- return {
980
+ return createParameter({
943
981
  ...param,
944
- schema: transform(param.schema, visitor, options)
945
- };
982
+ schema: transform(param.schema, {
983
+ ...options,
984
+ parent: param
985
+ })
986
+ });
946
987
  }
947
988
  case "Response": {
948
989
  let response = node;
949
- const replaced = visitor.response?.(response);
990
+ const replaced = visitor.response?.(response, { parent });
950
991
  if (replaced) response = replaced;
951
992
  return {
952
993
  ...response,
953
- schema: transform(response.schema, visitor, options)
994
+ schema: transform(response.schema, {
995
+ ...options,
996
+ parent: response
997
+ })
954
998
  };
955
999
  }
956
1000
  case "FunctionParameter":
@@ -959,43 +1003,74 @@ function transform(node, visitor, options = {}) {
959
1003
  }
960
1004
  }
961
1005
  /**
1006
+ * Combines multiple visitors into a single visitor that applies them sequentially (left to right).
1007
+ * For each node kind, the output of one visitor becomes the input of the next.
1008
+ */
1009
+ function composeTransformers(...visitors) {
1010
+ return {
1011
+ root(node, context) {
1012
+ return visitors.reduce((acc, v) => v.root?.(acc, context) ?? acc, node);
1013
+ },
1014
+ operation(node, context) {
1015
+ return visitors.reduce((acc, v) => v.operation?.(acc, context) ?? acc, node);
1016
+ },
1017
+ schema(node, context) {
1018
+ return visitors.reduce((acc, v) => v.schema?.(acc, context) ?? acc, node);
1019
+ },
1020
+ property(node, context) {
1021
+ return visitors.reduce((acc, v) => v.property?.(acc, context) ?? acc, node);
1022
+ },
1023
+ parameter(node, context) {
1024
+ return visitors.reduce((acc, v) => v.parameter?.(acc, context) ?? acc, node);
1025
+ },
1026
+ response(node, context) {
1027
+ return visitors.reduce((acc, v) => v.response?.(acc, context) ?? acc, node);
1028
+ }
1029
+ };
1030
+ }
1031
+ /**
962
1032
  * Depth-first synchronous reduction. Collects non-`undefined` visitor return values into an array.
963
1033
  */
964
- function collect(node, visitor, options = {}) {
965
- const recurse = (options.depth ?? visitorDepths.deep) === visitorDepths.deep;
1034
+ function collect(node, options) {
1035
+ const { depth, parent, ...visitor } = options;
1036
+ const recurse = (depth ?? visitorDepths.deep) === visitorDepths.deep;
966
1037
  const results = [];
967
1038
  let v;
968
1039
  switch (node.kind) {
969
1040
  case "Root":
970
- v = visitor.root?.(node);
1041
+ v = visitor.root?.(node, { parent });
971
1042
  break;
972
1043
  case "Operation":
973
- v = visitor.operation?.(node);
1044
+ v = visitor.operation?.(node, { parent });
974
1045
  break;
975
1046
  case "Schema":
976
- v = visitor.schema?.(node);
1047
+ v = visitor.schema?.(node, { parent });
977
1048
  break;
978
1049
  case "Property":
979
- v = visitor.property?.(node);
1050
+ v = visitor.property?.(node, { parent });
980
1051
  break;
981
1052
  case "Parameter":
982
- v = visitor.parameter?.(node);
1053
+ v = visitor.parameter?.(node, { parent });
983
1054
  break;
984
1055
  case "Response":
985
- v = visitor.response?.(node);
1056
+ v = visitor.response?.(node, { parent });
986
1057
  break;
987
1058
  case "FunctionParameter":
988
1059
  case "ObjectBindingParameter":
989
1060
  case "FunctionParameters": break;
990
1061
  }
991
1062
  if (v !== void 0) results.push(v);
992
- for (const child of getChildren(node, recurse)) for (const item of collect(child, visitor, options)) results.push(item);
1063
+ for (const child of getChildren(node, recurse)) for (const item of collect(child, {
1064
+ ...options,
1065
+ parent: node
1066
+ })) results.push(item);
993
1067
  return results;
994
1068
  }
995
1069
  //#endregion
996
1070
  exports.applyParamsCasing = applyParamsCasing;
997
1071
  exports.buildRefMap = buildRefMap;
998
1072
  exports.collect = collect;
1073
+ exports.composeTransformers = composeTransformers;
999
1074
  exports.createFunctionParameter = createFunctionParameter;
1000
1075
  exports.createFunctionParameters = createFunctionParameters;
1001
1076
  exports.createObjectBindingParameter = createObjectBindingParameter;
@@ -1024,6 +1099,7 @@ exports.nodeKinds = nodeKinds;
1024
1099
  exports.refMapToObject = refMapToObject;
1025
1100
  exports.resolveRef = resolveRef;
1026
1101
  exports.schemaTypes = schemaTypes;
1102
+ exports.syncPropertySchema = syncPropertySchema;
1027
1103
  exports.transform = transform;
1028
1104
  exports.walk = walk;
1029
1105