@kubb/ast 5.13.0 → 5.13.1

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
@@ -195,6 +195,7 @@ const VISITOR_KEYS = {
195
195
  "members",
196
196
  "additionalProperties",
197
197
  "patternProperties",
198
+ "propertyNames",
198
199
  "rest"
199
200
  ],
200
201
  Property: ["schema"],
@@ -242,25 +243,101 @@ function isNodeRecord(value) {
242
243
  * ```
243
244
  */
244
245
  function getChildren(node, recurse) {
246
+ if (node.kind === "Schema" && !recurse) return [];
245
247
  const children = [];
246
- const keys = node.kind === "Schema" && !recurse ? void 0 : VISITOR_KEYS[node.kind];
247
- if (!keys) return children;
248
+ visitChildNodes(node, (child) => {
249
+ children.push(child);
250
+ return false;
251
+ });
252
+ return children;
253
+ }
254
+ /**
255
+ * Visits each direct child node in the AST's traversal order.
256
+ *
257
+ * @example
258
+ * ```ts
259
+ * forEachChild(operationNode, (child) => {
260
+ * console.log(child.kind)
261
+ * })
262
+ * ```
263
+ */
264
+ function forEachChild(node, visit) {
265
+ visitChildNodes(node, (child) => {
266
+ visit(child);
267
+ return false;
268
+ });
269
+ }
270
+ function visitChildNodes(node, visit) {
271
+ const keys = VISITOR_KEYS[node.kind];
272
+ if (!keys) return false;
248
273
  const record = node;
249
274
  for (const key of keys) {
250
275
  const value = record[key];
251
276
  if (Array.isArray(value)) {
252
- for (const item of value) if (isNode(item)) children.push(item);
277
+ for (const item of value) if (isNode(item) && visit(item)) return true;
253
278
  continue;
254
279
  }
255
280
  if (isNode(value)) {
256
- children.push(value);
281
+ if (visit(value)) return true;
257
282
  continue;
258
283
  }
259
- if (isNodeRecord(value)) {
260
- for (const item of Object.values(value)) if (isNode(item)) children.push(item);
284
+ if (isNodeRecord(value)) for (const name in value) {
285
+ if (!Object.hasOwn(value, name)) continue;
286
+ const item = value[name];
287
+ if (isNode(item) && visit(item)) return true;
261
288
  }
262
289
  }
263
- return children;
290
+ return false;
291
+ }
292
+ /**
293
+ * Visits each schema in a node's child tree in depth-first order. Includes `node` when it is a schema.
294
+ *
295
+ * @example
296
+ * ```ts
297
+ * forEachSchema(operationNode, (schema) => {
298
+ * console.log(schema.type)
299
+ * })
300
+ * ```
301
+ */
302
+ function forEachSchema(node, visit) {
303
+ const walk = (current) => {
304
+ if (current.kind === "Schema") visit(current);
305
+ forEachChild(current, walk);
306
+ };
307
+ walk(node);
308
+ }
309
+ /**
310
+ * Finds the first schema that matches `predicate` in depth-first order. Set `followRefs` to include resolved ref targets.
311
+ *
312
+ * @example
313
+ * ```ts
314
+ * const firstString = findSchema(operationNode, {
315
+ * predicate: (schema) => schema.type === 'string',
316
+ * })
317
+ * ```
318
+ */
319
+ function findSchema(node, { predicate, followRefs = false }) {
320
+ const seen = followRefs ? /* @__PURE__ */ new WeakSet() : void 0;
321
+ const walk = (current) => {
322
+ if (current.kind === "Schema") {
323
+ if (predicate(current)) return current;
324
+ if (seen) {
325
+ if (seen.has(current)) return void 0;
326
+ seen.add(current);
327
+ if (current.type === "ref" && current.schema) {
328
+ const found = walk(current.schema);
329
+ if (found) return found;
330
+ }
331
+ }
332
+ }
333
+ let found;
334
+ visitChildNodes(current, (child) => {
335
+ found = walk(child);
336
+ return found !== void 0;
337
+ });
338
+ if (found) return found;
339
+ };
340
+ return walk(node);
264
341
  }
265
342
  /**
266
343
  * Runs the visitor callback that matches `node.kind` with the traversal
@@ -644,6 +721,25 @@ function resolveRefName(node) {
644
721
  if (node.ref) return refName(node.ref);
645
722
  return node.name ?? node.schema?.name ?? null;
646
723
  }
724
+ /**
725
+ * Follows a resolved ref chain to its target schema. Returns an unresolved or cyclic ref as is.
726
+ *
727
+ * @example
728
+ * ```ts
729
+ * const target = resolveRef(refSchema)
730
+ * ```
731
+ */
732
+ function resolveRef(node) {
733
+ if (node.type !== "ref" || !node.schema) return node;
734
+ const seen = /* @__PURE__ */ new WeakSet();
735
+ let current = node;
736
+ while (current.type === "ref" && current.schema) {
737
+ if (seen.has(current)) return current;
738
+ seen.add(current);
739
+ current = current.schema;
740
+ }
741
+ return current;
742
+ }
647
743
  /** Fields of a ref node that describe the ref itself, so they never override the resolved schema. */
648
744
  const REF_OWN_KEYS = /* @__PURE__ */ new Set([
649
745
  "kind",
@@ -1538,6 +1634,9 @@ var src_exports = /* @__PURE__ */ __exportAll({
1538
1634
  factory: () => nodes_exports,
1539
1635
  findCircularSchemas: () => findCircularSchemas,
1540
1636
  findCircularSchemasFromGraph: () => findCircularSchemasFromGraph,
1637
+ findSchema: () => findSchema,
1638
+ forEachChild: () => forEachChild,
1639
+ forEachSchema: () => forEachSchema,
1541
1640
  getSchemaLiteralValues: () => getSchemaLiteralValues,
1542
1641
  inferDiscriminatorPropertyName: () => inferDiscriminatorPropertyName,
1543
1642
  isBareRef: () => isBareRef,
@@ -1546,6 +1645,7 @@ var src_exports = /* @__PURE__ */ __exportAll({
1546
1645
  narrowSchema: () => narrowSchema,
1547
1646
  optionality: () => optionality,
1548
1647
  refName: () => refName,
1648
+ resolveRef: () => resolveRef,
1549
1649
  resolveRefName: () => resolveRefName,
1550
1650
  resolveSchemaProperties: () => resolveSchemaProperties,
1551
1651
  schemaTypes: () => schemaTypes,
@@ -1576,6 +1676,9 @@ Object.defineProperty(exports, "factory", {
1576
1676
  });
1577
1677
  exports.findCircularSchemas = findCircularSchemas;
1578
1678
  exports.findCircularSchemasFromGraph = findCircularSchemasFromGraph;
1679
+ exports.findSchema = findSchema;
1680
+ exports.forEachChild = forEachChild;
1681
+ exports.forEachSchema = forEachSchema;
1579
1682
  exports.getSchemaLiteralValues = getSchemaLiteralValues;
1580
1683
  exports.inferDiscriminatorPropertyName = inferDiscriminatorPropertyName;
1581
1684
  exports.isBareRef = isBareRef;
@@ -1584,6 +1687,7 @@ exports.mergeRefWithSchema = mergeRefWithSchema;
1584
1687
  exports.narrowSchema = narrowSchema;
1585
1688
  exports.optionality = optionality;
1586
1689
  exports.refName = refName;
1690
+ exports.resolveRef = resolveRef;
1587
1691
  exports.resolveRefName = resolveRefName;
1588
1692
  exports.resolveSchemaProperties = resolveSchemaProperties;
1589
1693
  exports.schemaTypes = schemaTypes;