@kubb/ast 5.18.6 → 5.18.8

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.d.cts CHANGED
@@ -616,7 +616,7 @@ type SourceNode = BaseNode & {
616
616
  */
617
617
  isTypeOnly?: boolean | null;
618
618
  /**
619
- * Include the `export` keyword in the generated source.
619
+ * Mark this source as an exported declaration. The source text carries its own `export` keyword.
620
620
  */
621
621
  isExportable?: boolean | null;
622
622
  /**
@@ -2414,9 +2414,15 @@ type CollectOptions<T> = VisitorOf<T> & TraversalOptions;
2414
2414
  * })
2415
2415
  * ```
2416
2416
  */
2417
- declare function findSchema$1(node: Node, { predicate, followRefs }: {
2417
+ declare function findSchema$1(node: Node, { predicate, followRefs, cache }: {
2418
2418
  predicate: (schema: SchemaNode) => boolean;
2419
2419
  followRefs?: boolean;
2420
+ /**
2421
+ * Remembers the match below each schema (`null` for none), so later calls skip the parts of the graph they share.
2422
+ * Keep one cache per `predicate` and `followRefs` value, for example one per build.
2423
+ * In a cyclic graph, a cached call can return a different match than the first one in depth-first order.
2424
+ */
2425
+ cache?: WeakMap<SchemaNode, SchemaNode | null>;
2420
2426
  }): SchemaNode | undefined;
2421
2427
  /**
2422
2428
  * Synchronous depth-first transform. Each visitor callback can return a
@@ -2502,7 +2508,8 @@ declare function resolveSchemaProperties$1({ node, propertyName }: {
2502
2508
  * // ['cat', 'dog']
2503
2509
  * ```
2504
2510
  */
2505
- declare function getSchemaLiteralValues$1(node: SchemaNode): ReadonlyArray<string | number | boolean | null>;
2511
+ declare function getSchemaLiteralValues$1(node: SchemaNode): ReadonlyArray<LiteralValue>;
2512
+ type LiteralValue = string | number | boolean | null;
2506
2513
  /**
2507
2514
  * Infers an implicit discriminator: a property every member exposes with a distinct single
2508
2515
  * literal value, the same shape a declared OpenAPI `discriminator` already narrows on.
@@ -3011,5 +3018,4 @@ type ParserOptions = {
3011
3018
  declare namespace index_d_exports {
3012
3019
  export { ArraySchemaNode, ArrowFunctionNode, AuthCredential, AuthRequirement, AuthScheme, BreakNode, CodeNode, ConstNode, ContentNode, DateOnlyTypeValue, DateSchemaNode, DateTimeTypeValue, DateTypeOptions, DatetimeSchemaNode, DistributiveOmit, EncodingNode, Enforce, EnumSchemaNode, ExampleNode, ExportNode, ExternalDocs, FileNode, FunctionNode, GenericOperationNode, HttpMethod, HttpOperationNode, ImportNode, InlineLanguage, InputMeta, InputNode, InputServer, InputTag, IntersectionSchemaNode, JSDocNode, JsxNode, Macro, Node, NodeKind, NotSchemaNode, NumberSchemaNode, OAuthFlow, ObjectSchemaNode, OperationNode, ParameterLocation, ParameterNode, ParameterStyle, ParserOptions, PrimitiveSchemaType, Printer, PrinterFactoryOptions, PrinterPartial, PropertyNode, RefSchemaNode, RequestBodyNode, ResponseLink, ResponseNode, ScalarSchemaNode, ScalarSchemaType, SchemaNode, SchemaNodeByType, SchemaType, SourceNode, StatusCode, StringSchemaNode, TextNode, TimeSchemaNode, TypeNode, UnionSchemaNode, UrlSchemaNode, UserFileNode, Visitor, VisitorContext, applyMacros, index_d_exports as ast, index_d_exports$1 as auth, collect, collectImportedRefNames, collectSchemaRefs, collectSync, collectUsedSchemaNames, compareEnforce, createPrinter, defineMacro, extractStringsFromNodes, index_d_exports$2 as factory, index_d_exports$3 as file, findCircularSchemas, findSchema, getSchemaLiteralValues, index_d_exports$4 as graph, index_d_exports$5 as http, inferDiscriminatorPropertyName, inlineFiles, isBareRef, isHttpOperationNode, index_d_exports$6 as macro, index_d_exports$7 as mediaType, mergeRefWithSchema, narrowSchema, index_d_exports$8 as node, nodeKinds, optionality, index_d_exports$9 as ref, refName, resolveRef, resolveRefName, resolveSchemaProperties, index_d_exports$10 as schema, schemaTypes, index_d_exports$11 as server, transform };
3013
3020
  }
3014
- export { type ArraySchemaNode, type ArrowFunctionNode, type AuthCredential, type AuthRequirement, type AuthScheme, type BreakNode, type CodeNode, type ConstNode, type ContentNode, type DateOnlyTypeValue, type DateSchemaNode, type DateTimeTypeValue, type DateTypeOptions, type DatetimeSchemaNode, type DistributiveOmit, type EncodingNode, type Enforce, type EnumSchemaNode, type ExampleNode, type ExportNode, type ExternalDocs, type FileNode, type FunctionNode, type GenericOperationNode, type HttpMethod, type HttpOperationNode, type ImportNode, type InlineLanguage, type InputMeta, type InputNode, type InputServer, type InputTag, type IntersectionSchemaNode, type JSDocNode, type JsxNode, type Macro, type Node, type NodeKind, type NotSchemaNode, type NumberSchemaNode, type OAuthFlow, type ObjectSchemaNode, type OperationNode, type ParameterLocation, type ParameterNode, type ParameterStyle, type ParserOptions, type PrimitiveSchemaType, type Printer, type PrinterFactoryOptions, type PrinterPartial, type PropertyNode, type RefSchemaNode, type RequestBodyNode, type ResponseLink, type ResponseNode, type ScalarSchemaNode, type ScalarSchemaType, type SchemaNode, type SchemaNodeByType, type SchemaType, type SourceNode, type StatusCode, type StringSchemaNode, type TextNode, type TimeSchemaNode, type TypeNode, type UnionSchemaNode, type UrlSchemaNode, type UserFileNode, type Visitor, type VisitorContext, index_d_exports as ast, index_d_exports$1 as auth, index_d_exports$2 as factory, index_d_exports$3 as file, index_d_exports$4 as graph, index_d_exports$5 as http, index_d_exports$6 as macro, index_d_exports$7 as mediaType, index_d_exports$8 as node, index_d_exports$9 as ref, index_d_exports$10 as schema, index_d_exports$11 as server };
3015
- //# sourceMappingURL=index.d.cts.map
3021
+ export { type ArraySchemaNode, type ArrowFunctionNode, type AuthCredential, type AuthRequirement, type AuthScheme, type BreakNode, type CodeNode, type ConstNode, type ContentNode, type DateOnlyTypeValue, type DateSchemaNode, type DateTimeTypeValue, type DateTypeOptions, type DatetimeSchemaNode, type DistributiveOmit, type EncodingNode, type Enforce, type EnumSchemaNode, type ExampleNode, type ExportNode, type ExternalDocs, type FileNode, type FunctionNode, type GenericOperationNode, type HttpMethod, type HttpOperationNode, type ImportNode, type InlineLanguage, type InputMeta, type InputNode, type InputServer, type InputTag, type IntersectionSchemaNode, type JSDocNode, type JsxNode, type Macro, type Node, type NodeKind, type NotSchemaNode, type NumberSchemaNode, type OAuthFlow, type ObjectSchemaNode, type OperationNode, type ParameterLocation, type ParameterNode, type ParameterStyle, type ParserOptions, type PrimitiveSchemaType, type Printer, type PrinterFactoryOptions, type PrinterPartial, type PropertyNode, type RefSchemaNode, type RequestBodyNode, type ResponseLink, type ResponseNode, type ScalarSchemaNode, type ScalarSchemaType, type SchemaNode, type SchemaNodeByType, type SchemaType, type SourceNode, type StatusCode, type StringSchemaNode, type TextNode, type TimeSchemaNode, type TypeNode, type UnionSchemaNode, type UrlSchemaNode, type UserFileNode, type Visitor, type VisitorContext, index_d_exports as ast, index_d_exports$1 as auth, index_d_exports$2 as factory, index_d_exports$3 as file, index_d_exports$4 as graph, index_d_exports$5 as http, index_d_exports$6 as macro, index_d_exports$7 as mediaType, index_d_exports$8 as node, index_d_exports$9 as ref, index_d_exports$10 as schema, index_d_exports$11 as server };
package/dist/index.d.ts CHANGED
@@ -616,7 +616,7 @@ type SourceNode = BaseNode & {
616
616
  */
617
617
  isTypeOnly?: boolean | null;
618
618
  /**
619
- * Include the `export` keyword in the generated source.
619
+ * Mark this source as an exported declaration. The source text carries its own `export` keyword.
620
620
  */
621
621
  isExportable?: boolean | null;
622
622
  /**
@@ -2414,9 +2414,15 @@ type CollectOptions<T> = VisitorOf<T> & TraversalOptions;
2414
2414
  * })
2415
2415
  * ```
2416
2416
  */
2417
- declare function findSchema$1(node: Node, { predicate, followRefs }: {
2417
+ declare function findSchema$1(node: Node, { predicate, followRefs, cache }: {
2418
2418
  predicate: (schema: SchemaNode) => boolean;
2419
2419
  followRefs?: boolean;
2420
+ /**
2421
+ * Remembers the match below each schema (`null` for none), so later calls skip the parts of the graph they share.
2422
+ * Keep one cache per `predicate` and `followRefs` value, for example one per build.
2423
+ * In a cyclic graph, a cached call can return a different match than the first one in depth-first order.
2424
+ */
2425
+ cache?: WeakMap<SchemaNode, SchemaNode | null>;
2420
2426
  }): SchemaNode | undefined;
2421
2427
  /**
2422
2428
  * Synchronous depth-first transform. Each visitor callback can return a
@@ -2502,7 +2508,8 @@ declare function resolveSchemaProperties$1({ node, propertyName }: {
2502
2508
  * // ['cat', 'dog']
2503
2509
  * ```
2504
2510
  */
2505
- declare function getSchemaLiteralValues$1(node: SchemaNode): ReadonlyArray<string | number | boolean | null>;
2511
+ declare function getSchemaLiteralValues$1(node: SchemaNode): ReadonlyArray<LiteralValue>;
2512
+ type LiteralValue = string | number | boolean | null;
2506
2513
  /**
2507
2514
  * Infers an implicit discriminator: a property every member exposes with a distinct single
2508
2515
  * literal value, the same shape a declared OpenAPI `discriminator` already narrows on.
@@ -3011,5 +3018,4 @@ type ParserOptions = {
3011
3018
  declare namespace index_d_exports {
3012
3019
  export { ArraySchemaNode, ArrowFunctionNode, AuthCredential, AuthRequirement, AuthScheme, BreakNode, CodeNode, ConstNode, ContentNode, DateOnlyTypeValue, DateSchemaNode, DateTimeTypeValue, DateTypeOptions, DatetimeSchemaNode, DistributiveOmit, EncodingNode, Enforce, EnumSchemaNode, ExampleNode, ExportNode, ExternalDocs, FileNode, FunctionNode, GenericOperationNode, HttpMethod, HttpOperationNode, ImportNode, InlineLanguage, InputMeta, InputNode, InputServer, InputTag, IntersectionSchemaNode, JSDocNode, JsxNode, Macro, Node, NodeKind, NotSchemaNode, NumberSchemaNode, OAuthFlow, ObjectSchemaNode, OperationNode, ParameterLocation, ParameterNode, ParameterStyle, ParserOptions, PrimitiveSchemaType, Printer, PrinterFactoryOptions, PrinterPartial, PropertyNode, RefSchemaNode, RequestBodyNode, ResponseLink, ResponseNode, ScalarSchemaNode, ScalarSchemaType, SchemaNode, SchemaNodeByType, SchemaType, SourceNode, StatusCode, StringSchemaNode, TextNode, TimeSchemaNode, TypeNode, UnionSchemaNode, UrlSchemaNode, UserFileNode, Visitor, VisitorContext, applyMacros, index_d_exports as ast, index_d_exports$1 as auth, collect, collectImportedRefNames, collectSchemaRefs, collectSync, collectUsedSchemaNames, compareEnforce, createPrinter, defineMacro, extractStringsFromNodes, index_d_exports$2 as factory, index_d_exports$3 as file, findCircularSchemas, findSchema, getSchemaLiteralValues, index_d_exports$4 as graph, index_d_exports$5 as http, inferDiscriminatorPropertyName, inlineFiles, isBareRef, isHttpOperationNode, index_d_exports$6 as macro, index_d_exports$7 as mediaType, mergeRefWithSchema, narrowSchema, index_d_exports$8 as node, nodeKinds, optionality, index_d_exports$9 as ref, refName, resolveRef, resolveRefName, resolveSchemaProperties, index_d_exports$10 as schema, schemaTypes, index_d_exports$11 as server, transform };
3013
3020
  }
3014
- export { type ArraySchemaNode, type ArrowFunctionNode, type AuthCredential, type AuthRequirement, type AuthScheme, type BreakNode, type CodeNode, type ConstNode, type ContentNode, type DateOnlyTypeValue, type DateSchemaNode, type DateTimeTypeValue, type DateTypeOptions, type DatetimeSchemaNode, type DistributiveOmit, type EncodingNode, type Enforce, type EnumSchemaNode, type ExampleNode, type ExportNode, type ExternalDocs, type FileNode, type FunctionNode, type GenericOperationNode, type HttpMethod, type HttpOperationNode, type ImportNode, type InlineLanguage, type InputMeta, type InputNode, type InputServer, type InputTag, type IntersectionSchemaNode, type JSDocNode, type JsxNode, type Macro, type Node, type NodeKind, type NotSchemaNode, type NumberSchemaNode, type OAuthFlow, type ObjectSchemaNode, type OperationNode, type ParameterLocation, type ParameterNode, type ParameterStyle, type ParserOptions, type PrimitiveSchemaType, type Printer, type PrinterFactoryOptions, type PrinterPartial, type PropertyNode, type RefSchemaNode, type RequestBodyNode, type ResponseLink, type ResponseNode, type ScalarSchemaNode, type ScalarSchemaType, type SchemaNode, type SchemaNodeByType, type SchemaType, type SourceNode, type StatusCode, type StringSchemaNode, type TextNode, type TimeSchemaNode, type TypeNode, type UnionSchemaNode, type UrlSchemaNode, type UserFileNode, type Visitor, type VisitorContext, index_d_exports as ast, index_d_exports$1 as auth, index_d_exports$2 as factory, index_d_exports$3 as file, index_d_exports$4 as graph, index_d_exports$5 as http, index_d_exports$6 as macro, index_d_exports$7 as mediaType, index_d_exports$8 as node, index_d_exports$9 as ref, index_d_exports$10 as schema, index_d_exports$11 as server };
3015
- //# sourceMappingURL=index.d.ts.map
3021
+ export { type ArraySchemaNode, type ArrowFunctionNode, type AuthCredential, type AuthRequirement, type AuthScheme, type BreakNode, type CodeNode, type ConstNode, type ContentNode, type DateOnlyTypeValue, type DateSchemaNode, type DateTimeTypeValue, type DateTypeOptions, type DatetimeSchemaNode, type DistributiveOmit, type EncodingNode, type Enforce, type EnumSchemaNode, type ExampleNode, type ExportNode, type ExternalDocs, type FileNode, type FunctionNode, type GenericOperationNode, type HttpMethod, type HttpOperationNode, type ImportNode, type InlineLanguage, type InputMeta, type InputNode, type InputServer, type InputTag, type IntersectionSchemaNode, type JSDocNode, type JsxNode, type Macro, type Node, type NodeKind, type NotSchemaNode, type NumberSchemaNode, type OAuthFlow, type ObjectSchemaNode, type OperationNode, type ParameterLocation, type ParameterNode, type ParameterStyle, type ParserOptions, type PrimitiveSchemaType, type Printer, type PrinterFactoryOptions, type PrinterPartial, type PropertyNode, type RefSchemaNode, type RequestBodyNode, type ResponseLink, type ResponseNode, type ScalarSchemaNode, type ScalarSchemaType, type SchemaNode, type SchemaNodeByType, type SchemaType, type SourceNode, type StatusCode, type StringSchemaNode, type TextNode, type TimeSchemaNode, type TypeNode, type UnionSchemaNode, type UrlSchemaNode, type UserFileNode, type Visitor, type VisitorContext, index_d_exports as ast, index_d_exports$1 as auth, index_d_exports$2 as factory, index_d_exports$3 as file, index_d_exports$4 as graph, index_d_exports$5 as http, index_d_exports$6 as macro, index_d_exports$7 as mediaType, index_d_exports$8 as node, index_d_exports$9 as ref, index_d_exports$10 as schema, index_d_exports$11 as server };
package/dist/index.js CHANGED
@@ -6,14 +6,14 @@ var __name = (target, value) => __defProp(target, "name", {
6
6
  value,
7
7
  configurable: true
8
8
  });
9
- var __exportAll = (all, no_symbols) => {
10
- let target = {};
9
+ var __exportAll = (all, flags) => {
10
+ let target = Object.setPrototypeOf({}, null);
11
11
  for (var name in all) __defProp(target, name, {
12
12
  get: all[name],
13
13
  enumerable: true
14
14
  });
15
- if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
16
- return target;
15
+ if (!(flags & 1)) __defProp(target, Symbol.toStringTag, { value: "Module" });
16
+ return flags & 2 ? target : Object.preventExtensions(target);
17
17
  };
18
18
  // ../../internals/utils/src/promise.ts
19
19
  /**
@@ -25,11 +25,32 @@ var __exportAll = (all, no_symbols) => {
25
25
  * `const refs = memo(refCache, node, () => collectRefs(node))`
26
26
  */
27
27
  function memo(store, key, compute) {
28
- if (store.has(key)) return store.get(key);
28
+ const cached = store.get(key);
29
+ if (cached !== void 0 || store.has(key)) return cached;
29
30
  const value = compute();
30
31
  store.set(key, value);
31
32
  return value;
32
33
  }
34
+ function createStore({ type }) {
35
+ if (type === "weak") return /* @__PURE__ */ new WeakMap();
36
+ const entry = /* @__PURE__ */ new Map();
37
+ if (type === "map") return entry;
38
+ const set = (key, value) => {
39
+ entry.clear();
40
+ entry.set(key, value);
41
+ };
42
+ const touch = (key) => {
43
+ if (!entry.has(key)) return false;
44
+ set(key, entry.get(key));
45
+ return true;
46
+ };
47
+ return {
48
+ has: touch,
49
+ get: (key) => touch(key) ? entry.get(key) : void 0,
50
+ set
51
+ };
52
+ }
53
+ memo.create = createStore;
33
54
  // src/constants.ts
34
55
  /**
35
56
  * Node kind discriminators used by every AST node (for example `node.kind === nodeKinds.text`).
@@ -300,14 +321,19 @@ function walkSchema(node, through, visit) {
300
321
  * ```
301
322
  */
302
323
  function getSchemaLiteralValues$1(node) {
324
+ const cached = literalValues.get(node);
325
+ if (cached) return cached;
303
326
  const values = /* @__PURE__ */ new Set();
304
327
  walkSchema(node, "union", (current) => {
305
328
  if (current.type !== "enum") return;
306
329
  for (const { value } of current.namedEnumValues ?? current.enumValues?.map((value) => ({ value })) ?? []) values.add(value);
307
330
  });
308
- return [...values];
331
+ const result = Object.freeze([...values]);
332
+ literalValues.set(node, result);
333
+ return result;
309
334
  }
310
335
  __name(getSchemaLiteralValues$1, "getSchemaLiteralValues");
336
+ const literalValues = /* @__PURE__ */ new WeakMap();
311
337
  function collectPropertyNames(node) {
312
338
  const names = /* @__PURE__ */ new Set();
313
339
  walkSchema(node, "intersection", (current) => {
@@ -456,24 +482,6 @@ function isNode(value) {
456
482
  function isNodeRecord(value) {
457
483
  return typeof value === "object" && value !== null && !Array.isArray(value);
458
484
  }
459
- /**
460
- * Returns the immediate traversable children of `node`.
461
- *
462
- * @example
463
- * ```ts
464
- * const children = getChildren(operationNode, true)
465
- * // returns parameters, the request body, and responses
466
- * ```
467
- */
468
- function getChildren(node, recurse) {
469
- if (node.kind === nodeKinds$1.schema && !recurse) return [];
470
- const children = [];
471
- visitChildNodes(node, (child) => {
472
- children.push(child);
473
- return false;
474
- });
475
- return children;
476
- }
477
485
  function isNeverPrinted({ node, key }) {
478
486
  if (node.kind !== nodeKinds$1.schema) return false;
479
487
  if (key === "contains" && (node.type === "array" || node.type === "tuple")) return node.contains?.min === 0 && node.contains.max === void 0;
@@ -481,41 +489,63 @@ function isNeverPrinted({ node, key }) {
481
489
  return false;
482
490
  }
483
491
  /**
492
+ * Child keys of a schema walked with `checks: true`: the shape keys, then {@link schemaCheckKeys}.
493
+ */
494
+ const SCHEMA_CHECK_VISITOR_KEYS = [...VISITOR_KEYS.Schema, ...schemaCheckKeys];
495
+ function visitOnce(child, seen, visit) {
496
+ if (seen.first === void 0) {
497
+ seen.first = child;
498
+ return visit(child);
499
+ }
500
+ if (seen.first === child || seen.rest?.has(child)) return false;
501
+ (seen.rest ??= /* @__PURE__ */ new Set()).add(child);
502
+ return visit(child);
503
+ }
504
+ function visitRecord(value, seen, visit) {
505
+ for (const name in value) {
506
+ if (!Object.hasOwn(value, name)) continue;
507
+ const item = value[name];
508
+ if (isNode(item) && visitOnce(item, seen, visit)) return true;
509
+ }
510
+ return false;
511
+ }
512
+ /**
484
513
  * Calls `visit` for each direct child node and stops at the first call that returns `true`.
485
514
  * With `checks: true`, a schema's {@link schemaCheckKeys} fields are walked too, except checks that cannot fail.
486
515
  */
487
516
  function visitChildNodes(node, visit, { checks = false } = {}) {
488
- const keys = checks && node.kind === nodeKinds$1.schema ? [...VISITOR_KEYS[node.kind] ?? [], ...schemaCheckKeys] : VISITOR_KEYS[node.kind];
517
+ const withChecks = checks && node.kind === nodeKinds$1.schema;
518
+ const keys = withChecks ? SCHEMA_CHECK_VISITOR_KEYS : VISITOR_KEYS[node.kind];
489
519
  if (!keys) return false;
490
520
  const record = node;
491
- const seen = /* @__PURE__ */ new Set();
492
- const visitOnce = (child) => !seen.has(child) && (seen.add(child), visit(child));
493
- const visitRecord = (value) => {
494
- for (const name in value) {
495
- if (!Object.hasOwn(value, name)) continue;
496
- const item = value[name];
497
- if (isNode(item) && visitOnce(item)) return true;
498
- }
499
- return false;
500
- };
521
+ let seen;
501
522
  for (const key of keys) {
502
- if (checks && isNeverPrinted({
523
+ const value = record[key];
524
+ if (value === void 0 || value === null) continue;
525
+ if (withChecks && isNeverPrinted({
503
526
  node,
504
527
  key
505
528
  })) continue;
506
- const value = record[key];
529
+ seen ??= {
530
+ first: void 0,
531
+ rest: void 0
532
+ };
507
533
  if (Array.isArray(value)) {
508
- for (const item of value) if (isNode(item) ? visitOnce(item) : isNodeRecord(item) && visitRecord(item)) return true;
534
+ for (const item of value) if (isNode(item) ? visitOnce(item, seen, visit) : isNodeRecord(item) && visitRecord(item, seen, visit)) return true;
509
535
  continue;
510
536
  }
511
537
  if (isNode(value)) {
512
- if (visitOnce(value)) return true;
538
+ if (visitOnce(value, seen, visit)) return true;
513
539
  continue;
514
540
  }
515
- if (isNodeRecord(value) && visitRecord(value)) return true;
541
+ if (isNodeRecord(value) && visitRecord(value, seen, visit)) return true;
516
542
  }
517
543
  return false;
518
544
  }
545
+ const notFound = {
546
+ found: void 0,
547
+ low: Number.POSITIVE_INFINITY
548
+ };
519
549
  /**
520
550
  * Finds the first schema that matches `predicate` in depth-first order. Set `followRefs` to include resolved ref targets.
521
551
  *
@@ -526,28 +556,68 @@ function visitChildNodes(node, visit, { checks = false } = {}) {
526
556
  * })
527
557
  * ```
528
558
  */
529
- function findSchema$1(node, { predicate, followRefs = false }) {
530
- const seen = followRefs ? /* @__PURE__ */ new WeakSet() : void 0;
531
- const walk = (current) => {
532
- if (current.kind === nodeKinds$1.schema) {
533
- if (predicate(current)) return current;
534
- if (seen) {
535
- if (seen.has(current)) return void 0;
536
- seen.add(current);
537
- if (current.type === "ref" && current.schema) {
538
- const found = walk(current.schema);
539
- if (found) return found;
540
- }
541
- }
542
- }
543
- let found;
559
+ function findSchema$1(node, { predicate, followRefs = false, cache }) {
560
+ const state = followRefs ? /* @__PURE__ */ new Map() : void 0;
561
+ const pending = [];
562
+ let order = 0;
563
+ const walkChildren = (current, initial) => {
564
+ let result = initial;
544
565
  visitChildNodes(current, (child) => {
545
- found = walk(child);
546
- return found !== void 0;
566
+ const next = walk(child);
567
+ result = next.found || next.low < result.low ? next : result;
568
+ return next.found !== void 0;
547
569
  });
548
- if (found) return found;
570
+ return result;
571
+ };
572
+ const walkSchema = (current) => {
573
+ const target = state && current.type === "ref" && current.schema ? walk(current.schema) : notFound;
574
+ if (target.found) return target;
575
+ return walkChildren(current, target);
549
576
  };
550
- return walk(node);
577
+ const walk = (current) => {
578
+ if (current.kind !== nodeKinds$1.schema) return walkChildren(current, notFound);
579
+ const cached = cache?.get(current);
580
+ if (cached === null) return notFound;
581
+ if (cached) return {
582
+ found: cached,
583
+ low: Number.POSITIVE_INFINITY
584
+ };
585
+ if (predicate(current)) {
586
+ cache?.set(current, current);
587
+ return {
588
+ found: current,
589
+ low: Number.POSITIVE_INFINITY
590
+ };
591
+ }
592
+ const known = state?.get(current);
593
+ if (known !== void 0) return {
594
+ found: void 0,
595
+ low: known
596
+ };
597
+ const index = order++;
598
+ const start = pending.length;
599
+ state?.set(current, index);
600
+ const result = walkSchema(current);
601
+ if (result.found) {
602
+ cache?.set(current, result.found);
603
+ return result;
604
+ }
605
+ if (!state) {
606
+ cache?.set(current, null);
607
+ return notFound;
608
+ }
609
+ if (result.low < index) {
610
+ state.set(current, result.low);
611
+ pending.push(current);
612
+ return result;
613
+ }
614
+ for (const done of [...pending.splice(start), current]) {
615
+ state.set(done, Number.POSITIVE_INFINITY);
616
+ cache?.set(done, null);
617
+ }
618
+ return notFound;
619
+ };
620
+ return walk(node).found;
551
621
  }
552
622
  __name(findSchema$1, "findSchema");
553
623
  /**
@@ -611,15 +681,16 @@ function transformChildren(node, visitor, recurse) {
611
681
  if (!keys) return node;
612
682
  const record = node;
613
683
  let updates;
614
- const done = /* @__PURE__ */ new Map();
684
+ let done;
615
685
  const transformOnce = (child) => {
686
+ done ??= /* @__PURE__ */ new Map();
616
687
  const next = done.get(child) ?? transformNode(child, visitor, recurse, node);
617
688
  done.set(child, next);
618
689
  return next;
619
690
  };
620
691
  for (const key of keys) {
621
- if (!(key in record)) continue;
622
692
  const value = record[key];
693
+ if (value === void 0 || value === null) continue;
623
694
  if (Array.isArray(value)) {
624
695
  let mapped;
625
696
  for (const [i, item] of value.entries()) {
@@ -676,7 +747,11 @@ __name(collect$1, "collect");
676
747
  function collectInto(node, visitor, recurse, parent, result) {
677
748
  const v = applyVisitor(node, visitor, parent);
678
749
  if (v != null) result.push(v);
679
- for (const child of getChildren(node, recurse)) collectInto(child, visitor, recurse, node, result);
750
+ if (node.kind === nodeKinds$1.schema && !recurse) return;
751
+ visitChildNodes(node, (child) => {
752
+ collectInto(child, visitor, recurse, node, result);
753
+ return false;
754
+ });
680
755
  }
681
756
  // src/utils/refs.ts
682
757
  /**