@kubb/ast 5.0.0-alpha.72 → 5.0.0-alpha.74

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.ts CHANGED
@@ -2,7 +2,10 @@ import { t as __name } from "./chunk--u3MIqq1.js";
2
2
 
3
3
  //#region src/constants.d.ts
4
4
  /**
5
- * Traversal depth used by AST visitor utilities.
5
+ * Traversal depth for AST visitor utilities.
6
+ *
7
+ * - `'shallow'` — visits only the immediate node, skipping children.
8
+ * - `'deep'` — recursively visits all descendant nodes.
6
9
  */
7
10
  type VisitorDepth = 'shallow' | 'deep';
8
11
  declare const nodeKinds: {
@@ -25,15 +28,11 @@ declare const nodeKinds: {
25
28
  readonly break: "Break";
26
29
  };
27
30
  /**
28
- * Canonical schema type strings used by AST schema nodes.
29
- *
30
- * These values are used across the AST as stable discriminators
31
- * (for example `schema.type === schemaTypes.object`).
31
+ * Schema type discriminators used by all AST schema nodes.
32
32
  *
33
- * The map is grouped by intent:
34
- * - primitives (`string`, `number`, `boolean`, ...)
35
- * - structural/composite (`object`, `array`, `union`, ...)
36
- * - special OpenAPI-oriented types (`ref`, `datetime`, `uuid`, ...)
33
+ * These values serve as stable discriminators across the AST (e.g., `schema.type === schemaTypes.object`).
34
+ * Grouped by category: primitives (`string`, `number`, `boolean`), structural types (`object`, `array`, `union`),
35
+ * and format-specific types (`date`, `uuid`, `email`). Use `isScalarPrimitive()` to check for scalar types.
37
36
  */
38
37
  declare const schemaTypes: {
39
38
  /**
@@ -143,9 +142,16 @@ declare const schemaTypes: {
143
142
  };
144
143
  type ScalarPrimitive = 'string' | 'number' | 'integer' | 'bigint' | 'boolean';
145
144
  /**
146
- * Returns `true` when `type` is a scalar primitive schema type.
145
+ * Type guard that returns `true` when `type` is a scalar primitive schema type.
146
+ *
147
+ * Use this to check if a schema type can be directly assigned without wrapping (e.g., `string | number | boolean`).
147
148
  */
148
149
  declare function isScalarPrimitive(type: string): type is ScalarPrimitive;
150
+ /**
151
+ * HTTP method identifiers used by operation nodes.
152
+ *
153
+ * Includes all standard HTTP methods (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, TRACE).
154
+ */
149
155
  declare const httpMethods: {
150
156
  readonly get: "GET";
151
157
  readonly post: "POST";
@@ -156,6 +162,12 @@ declare const httpMethods: {
156
162
  readonly options: "OPTIONS";
157
163
  readonly trace: "TRACE";
158
164
  };
165
+ /**
166
+ * Common MIME types used in request/response content negotiation.
167
+ *
168
+ * Covers JSON, XML, form data, PDFs, images, audio, and video formats.
169
+ * Use these as keys when serializing request/response bodies.
170
+ */
159
171
  declare const mediaTypes: {
160
172
  readonly applicationJson: "application/json";
161
173
  readonly applicationXml: "application/xml";
@@ -3162,44 +3174,32 @@ declare function collect<T>(node: Node, options: CollectOptions<T>): Array<T>;
3162
3174
  //#endregion
3163
3175
  //#region src/utils.d.ts
3164
3176
  /**
3165
- * Returns a merged schema view for a ref node, combining the resolved `node.schema`
3166
- * (base from the referenced definition) with any usage-site sibling fields set directly
3167
- * on the ref node (description, readOnly, nullable, deprecated, etc.).
3177
+ * Merges a ref node with its resolved schema, giving usage-site fields precedence.
3168
3178
  *
3169
- * Usage-site fields take precedence over the resolved schema's own fields when both are defined.
3179
+ * Usage-site fields (`description`, `readOnly`, `nullable`, `deprecated`) on the ref node
3180
+ * override the same fields in the resolved `node.schema`. Non-ref nodes are returned unchanged.
3170
3181
  *
3171
- * For non-ref nodes the node itself is returned unchanged.
3182
+ * @example
3183
+ * ```ts
3184
+ * // Ref with description override
3185
+ * const ref = createSchema({ type: 'ref', ref: '#/components/schemas/Pet', description: 'A cute pet' })
3186
+ * const merged = syncSchemaRef(ref) // merges with resolved Pet schema
3187
+ * ```
3172
3188
  */
3173
3189
  declare function syncSchemaRef(node: SchemaNode): SchemaNode;
3174
3190
  /**
3175
- * Returns `true` when a schema is emitted as a plain `string` type.
3176
- *
3177
- * - `string`, `uuid`, `email`, `url`, `datetime` are always plain strings.
3178
- * - `date` and `time` are plain strings when their `representation` is `'string'` rather than `'date'`.
3191
+ * Type guard that returns `true` when a schema emits as a plain `string` type.
3179
3192
  *
3180
- * @example
3181
- * ```ts
3182
- * isStringType(createSchema({ type: 'uuid' })) // true
3183
- * isStringType(createSchema({ type: 'date', representation: 'date' })) // false
3184
- * ```
3193
+ * Covers `string`, `uuid`, `email`, `url`, and `datetime` types. For `date` and `time`
3194
+ * types, returns `true` only when `representation` is `'string'` rather than `'date'`.
3185
3195
  */
3186
3196
  declare function isStringType(node: SchemaNode): boolean;
3187
3197
  /**
3188
3198
  * Applies casing rules to parameter names and returns a new parameter array.
3189
3199
  *
3190
- * The input array is not mutated.
3191
- * If `casing` is not set, the original array is returned unchanged.
3192
- *
3193
- * Use this before passing parameters to schema builders so that property keys
3194
- * in generated output match the desired casing while preserving
3195
- * `OperationNode.parameters` for other consumers.
3196
- *
3197
- * @example
3198
- * ```ts
3199
- * const params = [createParameter({ name: 'pet_id', in: 'query', schema: createSchema({ type: 'string' }) })]
3200
- * const cased = caseParams(params, 'camelcase')
3201
- * // cased[0].name === 'petId'
3202
- * ```
3200
+ * Use this before passing parameters to schema builders so output property keys match
3201
+ * the desired casing while preserving `OperationNode.parameters` for other consumers.
3202
+ * The input array is not mutated. When `casing` is not set, the original array is returned unchanged.
3203
3203
  */
3204
3204
  declare function caseParams(params: Array<ParameterNode>, casing: 'camelcase' | undefined): Array<ParameterNode>;
3205
3205
  /**
@@ -3343,34 +3343,26 @@ type CreateOperationParamsOptions = {
3343
3343
  typeWrapper?: (type: string) => string;
3344
3344
  };
3345
3345
  /**
3346
- * Converts an {@link OperationNode} into a {@link FunctionParametersNode}.
3347
- *
3348
- * Centralizes the per-plugin `getParams()` pattern. Provide a `resolver` for
3349
- * type resolution and `extraParams` for plugin-specific trailing parameters.
3346
+ * Converts an `OperationNode` into function parameters for code generation.
3350
3347
  *
3351
- * @example
3352
- * ```ts
3353
- * const params = createOperationParams(node, {
3354
- * paramsType: 'inline',
3355
- * pathParamsType: 'inline',
3356
- * resolver: tsResolver,
3357
- * extraParams: [createFunctionParameter({ name: 'options', type: createParamsType({ variant: 'reference', name: 'Partial<RequestOptions>' }), default: '{}' })],
3358
- * })
3359
- * ```
3348
+ * Centralizes parameter grouping logic for all plugins. Provide a `resolver` for type name resolution
3349
+ * and `extraParams` for plugin-specific trailing parameters (e.g., `options` objects).
3350
+ * Supports three grouping modes: `object` (single destructured param), `inline` (separate params),
3351
+ * and `inlineSpread` (rest parameter). Use `CreateOperationParamsOptions` to fine-tune output.
3360
3352
  */
3361
3353
  declare function createOperationParams(node: OperationNode, options: CreateOperationParamsOptions): FunctionParametersNode;
3362
3354
  /**
3363
- * Recursively extracts all string content embedded in a {@link CodeNode} tree.
3355
+ * Extracts all string content from a `CodeNode` tree recursively.
3364
3356
  *
3365
- * Includes text node values, and string attribute fields (`params`, `generics`,
3366
- * `returnType`, `type`) that may reference identifiers needing imports.
3367
- * Used by `createFile` to build the full source string for import filtering.
3357
+ * Collects text node values, identifier references in string fields (`params`, `generics`, `returnType`, `type`),
3358
+ * and nested node content. Used internally to build the full source string for import filtering.
3368
3359
  */
3369
3360
  declare function extractStringsFromNodes(nodes: Array<CodeNode> | undefined): string;
3370
3361
  /**
3371
- * Resolves the referenced schema name of a `ref` node, falling back through
3372
- * `ref` → `name` → nested `schema.name`. Returns `undefined` for non-ref
3373
- * nodes or when no name can be resolved.
3362
+ * Resolves the schema name of a ref node, falling back through `ref` → `name` → nested `schema.name`.
3363
+ *
3364
+ * Returns `undefined` for non-ref nodes or when no name can be resolved. Use this to get a schema's
3365
+ * identifier for type definitions or error messages.
3374
3366
  *
3375
3367
  * @example
3376
3368
  * ```ts
@@ -3380,56 +3372,31 @@ declare function extractStringsFromNodes(nodes: Array<CodeNode> | undefined): st
3380
3372
  */
3381
3373
  declare function resolveRefName(node: SchemaNode | undefined): string | undefined;
3382
3374
  /**
3383
- * Recursively collects every named schema referenced (transitively) from
3384
- * `node` via `ref` edges. Refs are followed by name only — the resolved
3385
- * `node.schema` of a ref is not traversed inline.
3375
+ * Collects every named schema referenced (transitively) from a node via ref edges.
3386
3376
  *
3387
- * @example
3388
- * ```ts
3389
- * const refs = collectReferencedSchemaNames(petSchema)
3390
- * // => Set { 'Cat', 'Dog' }
3391
- * ```
3377
+ * Refs are followed by name only — the resolved `node.schema` is not traversed inline.
3378
+ * Use this to determine schema dependencies, build reference graphs, or detect what schemas need to be emitted.
3379
+ *
3380
+ * @note Returns a Set of schema names for efficient membership testing.
3392
3381
  */
3393
3382
  declare function collectReferencedSchemaNames(node: SchemaNode | undefined, out?: Set<string>): Set<string>;
3394
3383
  /**
3395
- * Identifies every named schema that participates in a circular dependency
3396
- * chain — including direct self-loops (e.g. `TreeNode → TreeNode`) and indirect
3397
- * cycles spanning multiple schemas (e.g. `Pet → Cat → Pet`).
3398
- *
3399
- * The returned set contains schema names. Plugins that translate schemas into
3400
- * a host language can use this to wrap recursive positions in a deferred
3401
- * construct (lazy getter, `z.lazy(() => …)`, etc.) and avoid runtime stack
3402
- * overflows when the generated code is executed.
3384
+ * Identifies all schemas that participate in circular dependency chains, including direct self-loops.
3403
3385
  *
3404
- * Refs are followed by name only `node.schema` (the resolved referent) is
3405
- * not traversed inline, which keeps the algorithm linear in the size of the
3406
- * schema graph.
3386
+ * Returns a Set of schema names with circular dependencies. Use this to wrap recursive schema positions
3387
+ * in deferred constructs (lazy getter, `z.lazy(() => …)`) to prevent infinite recursion when generated code runs.
3388
+ * Refs are followed by name only, keeping the algorithm linear in the schema graph size.
3407
3389
  *
3408
- * @example
3409
- * ```ts
3410
- * const circular = findCircularSchemas(inputNode.schemas)
3411
- * if (circular.has('Pet')) {
3412
- * // emit lazy wrapper for any property whose schema references Pet
3413
- * }
3414
- * ```
3390
+ * @note Call this once on the full schema graph, then use `containsCircularRef()` to check individual schemas.
3415
3391
  */
3416
3392
  declare function findCircularSchemas(schemas: ReadonlyArray<SchemaNode>): Set<string>;
3417
3393
  /**
3418
- * Returns true when `node` (or anything nested within it) carries a `ref`
3419
- * whose resolved name belongs to `circularSchemas`.
3394
+ * Type guard returning `true` when a schema or anything nested within it contains a ref to a circular schema.
3420
3395
  *
3421
- * When `excludeName` is provided, refs to that name are ignored — useful
3422
- * when self-references are already handled separately from cross-schema
3423
- * cycles (e.g. the faker plugin emits `undefined as any` for direct
3424
- * self-recursion but a lazy getter for indirect cycles).
3396
+ * Use `excludeName` to ignore refs to specific schemas (useful when self-references are handled separately).
3397
+ * Commonly used with `findCircularSchemas()` to detect where lazy wrappers are needed in code generation.
3425
3398
  *
3426
- * @example
3427
- * ```ts
3428
- * const circular = findCircularSchemas(schemas)
3429
- * if (containsCircularRef(property.schema, { circularSchemas: circular, excludeName: 'Pet' })) {
3430
- * // emit `get foo() { return fakeCat() }` instead of eager call
3431
- * }
3432
- * ```
3399
+ * @note Returns `true` for the first matching circular ref found; use for fast dependency checks.
3433
3400
  */
3434
3401
  declare function containsCircularRef(node: SchemaNode | undefined, {
3435
3402
  circularSchemas,
package/dist/index.js CHANGED
@@ -26,15 +26,11 @@ const nodeKinds = {
26
26
  break: "Break"
27
27
  };
28
28
  /**
29
- * Canonical schema type strings used by AST schema nodes.
29
+ * Schema type discriminators used by all AST schema nodes.
30
30
  *
31
- * These values are used across the AST as stable discriminators
32
- * (for example `schema.type === schemaTypes.object`).
33
- *
34
- * The map is grouped by intent:
35
- * - primitives (`string`, `number`, `boolean`, ...)
36
- * - structural/composite (`object`, `array`, `union`, ...)
37
- * - special OpenAPI-oriented types (`ref`, `datetime`, `uuid`, ...)
31
+ * These values serve as stable discriminators across the AST (e.g., `schema.type === schemaTypes.object`).
32
+ * Grouped by category: primitives (`string`, `number`, `boolean`), structural types (`object`, `array`, `union`),
33
+ * and format-specific types (`date`, `uuid`, `email`). Use `isScalarPrimitive()` to check for scalar types.
38
34
  */
39
35
  const schemaTypes = {
40
36
  /**
@@ -143,7 +139,9 @@ const schemaTypes = {
143
139
  never: "never"
144
140
  };
145
141
  /**
146
- * Primitive scalar schema types used when simplifying union members.
142
+ * Scalar primitive schema types used for union simplification and type narrowing.
143
+ *
144
+ * Use `isScalarPrimitive()` to safely check whether a type is a scalar primitive.
147
145
  */
148
146
  const SCALAR_PRIMITIVE_TYPES = new Set([
149
147
  "string",
@@ -153,11 +151,18 @@ const SCALAR_PRIMITIVE_TYPES = new Set([
153
151
  "boolean"
154
152
  ]);
155
153
  /**
156
- * Returns `true` when `type` is a scalar primitive schema type.
154
+ * Type guard that returns `true` when `type` is a scalar primitive schema type.
155
+ *
156
+ * Use this to check if a schema type can be directly assigned without wrapping (e.g., `string | number | boolean`).
157
157
  */
158
158
  function isScalarPrimitive(type) {
159
159
  return SCALAR_PRIMITIVE_TYPES.has(type);
160
160
  }
161
+ /**
162
+ * HTTP method identifiers used by operation nodes.
163
+ *
164
+ * Includes all standard HTTP methods (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, TRACE).
165
+ */
161
166
  const httpMethods = {
162
167
  get: "GET",
163
168
  post: "POST",
@@ -168,6 +173,12 @@ const httpMethods = {
168
173
  options: "OPTIONS",
169
174
  trace: "TRACE"
170
175
  };
176
+ /**
177
+ * Common MIME types used in request/response content negotiation.
178
+ *
179
+ * Covers JSON, XML, form data, PDFs, images, audio, and video formats.
180
+ * Use these as keys when serializing request/response bodies.
181
+ */
171
182
  const mediaTypes = {
172
183
  applicationJson: "application/json",
173
184
  applicationXml: "application/xml",
@@ -765,13 +776,17 @@ const plainStringTypes = new Set([
765
776
  "datetime"
766
777
  ]);
767
778
  /**
768
- * Returns a merged schema view for a ref node, combining the resolved `node.schema`
769
- * (base from the referenced definition) with any usage-site sibling fields set directly
770
- * on the ref node (description, readOnly, nullable, deprecated, etc.).
779
+ * Merges a ref node with its resolved schema, giving usage-site fields precedence.
771
780
  *
772
- * Usage-site fields take precedence over the resolved schema's own fields when both are defined.
781
+ * Usage-site fields (`description`, `readOnly`, `nullable`, `deprecated`) on the ref node
782
+ * override the same fields in the resolved `node.schema`. Non-ref nodes are returned unchanged.
773
783
  *
774
- * For non-ref nodes the node itself is returned unchanged.
784
+ * @example
785
+ * ```ts
786
+ * // Ref with description override
787
+ * const ref = createSchema({ type: 'ref', ref: '#/components/schemas/Pet', description: 'A cute pet' })
788
+ * const merged = syncSchemaRef(ref) // merges with resolved Pet schema
789
+ * ```
775
790
  */
776
791
  function syncSchemaRef(node) {
777
792
  const ref = narrowSchema(node, "ref");
@@ -785,16 +800,10 @@ function syncSchemaRef(node) {
785
800
  });
786
801
  }
787
802
  /**
788
- * Returns `true` when a schema is emitted as a plain `string` type.
789
- *
790
- * - `string`, `uuid`, `email`, `url`, `datetime` are always plain strings.
791
- * - `date` and `time` are plain strings when their `representation` is `'string'` rather than `'date'`.
803
+ * Type guard that returns `true` when a schema emits as a plain `string` type.
792
804
  *
793
- * @example
794
- * ```ts
795
- * isStringType(createSchema({ type: 'uuid' })) // true
796
- * isStringType(createSchema({ type: 'date', representation: 'date' })) // false
797
- * ```
805
+ * Covers `string`, `uuid`, `email`, `url`, and `datetime` types. For `date` and `time`
806
+ * types, returns `true` only when `representation` is `'string'` rather than `'date'`.
798
807
  */
799
808
  function isStringType(node) {
800
809
  if (plainStringTypes.has(node.type)) return true;
@@ -805,19 +814,9 @@ function isStringType(node) {
805
814
  /**
806
815
  * Applies casing rules to parameter names and returns a new parameter array.
807
816
  *
808
- * The input array is not mutated.
809
- * If `casing` is not set, the original array is returned unchanged.
810
- *
811
- * Use this before passing parameters to schema builders so that property keys
812
- * in generated output match the desired casing while preserving
813
- * `OperationNode.parameters` for other consumers.
814
- *
815
- * @example
816
- * ```ts
817
- * const params = [createParameter({ name: 'pet_id', in: 'query', schema: createSchema({ type: 'string' }) })]
818
- * const cased = caseParams(params, 'camelcase')
819
- * // cased[0].name === 'petId'
820
- * ```
817
+ * Use this before passing parameters to schema builders so output property keys match
818
+ * the desired casing while preserving `OperationNode.parameters` for other consumers.
819
+ * The input array is not mutated. When `casing` is not set, the original array is returned unchanged.
821
820
  */
822
821
  function caseParams(params, casing) {
823
822
  if (!casing) return params;
@@ -877,20 +876,12 @@ function resolveParamsType({ node, param, resolver }) {
877
876
  });
878
877
  }
879
878
  /**
880
- * Converts an {@link OperationNode} into a {@link FunctionParametersNode}.
881
- *
882
- * Centralizes the per-plugin `getParams()` pattern. Provide a `resolver` for
883
- * type resolution and `extraParams` for plugin-specific trailing parameters.
879
+ * Converts an `OperationNode` into function parameters for code generation.
884
880
  *
885
- * @example
886
- * ```ts
887
- * const params = createOperationParams(node, {
888
- * paramsType: 'inline',
889
- * pathParamsType: 'inline',
890
- * resolver: tsResolver,
891
- * extraParams: [createFunctionParameter({ name: 'options', type: createParamsType({ variant: 'reference', name: 'Partial<RequestOptions>' }), default: '{}' })],
892
- * })
893
- * ```
881
+ * Centralizes parameter grouping logic for all plugins. Provide a `resolver` for type name resolution
882
+ * and `extraParams` for plugin-specific trailing parameters (e.g., `options` objects).
883
+ * Supports three grouping modes: `object` (single destructured param), `inline` (separate params),
884
+ * and `inlineSpread` (rest parameter). Use `CreateOperationParamsOptions` to fine-tune output.
894
885
  */
895
886
  function createOperationParams(node, options) {
896
887
  const { paramsType, pathParamsType, paramsCasing, resolver, pathParamsDefault, extraParams = [], paramNames, typeWrapper } = options;
@@ -1100,9 +1091,9 @@ function sortKey(node) {
1100
1091
  return `${isArray}:${typeOnly}:${node.path}:${hasName}:${name}`;
1101
1092
  }
1102
1093
  /**
1103
- * Deduplicates an array of `SourceNode` objects.
1104
- * Named sources are deduplicated by `name + isExportable + isTypeOnly`.
1105
- * Unnamed sources are deduplicated by object reference.
1094
+ * Deduplicates and merges `SourceNode` objects by `name + isExportable + isTypeOnly`.
1095
+ *
1096
+ * Unnamed sources are deduplicated by object reference. Returns a deduplicated array in original order.
1106
1097
  */
1107
1098
  function combineSources(sources) {
1108
1099
  const seen = /* @__PURE__ */ new Map();
@@ -1113,8 +1104,10 @@ function combineSources(sources) {
1113
1104
  return [...seen.values()];
1114
1105
  }
1115
1106
  /**
1116
- * Deduplicates and merges an array of `ExportNode` objects.
1117
- * Exports with the same path and `isTypeOnly` flag have their names merged.
1107
+ * Deduplicates and merges `ExportNode` objects by path and type.
1108
+ *
1109
+ * Named exports with the same path and `isTypeOnly` flag have their names merged into a single export.
1110
+ * Non-array exports are deduplicated by exact identity. Returns a sorted, deduplicated array.
1118
1111
  */
1119
1112
  function combineExports(exports) {
1120
1113
  const result = [];
@@ -1154,9 +1147,12 @@ function combineExports(exports) {
1154
1147
  return result;
1155
1148
  }
1156
1149
  /**
1157
- * Deduplicates and merges an array of `ImportNode` objects.
1158
- * Filters out unused imports (names not referenced in `source` or re-exported).
1159
- * Imports with the same path and `isTypeOnly` flag have their names merged.
1150
+ * Deduplicates and merges `ImportNode` objects, filtering out unused imports.
1151
+ *
1152
+ * Retains imports that are referenced in `source` or re-exported. Imports with the same path and
1153
+ * `isTypeOnly` flag have their names merged. Returns a sorted, deduplicated, filtered array.
1154
+ *
1155
+ * @note Use this when combining imports from multiple files to avoid duplicate declarations.
1160
1156
  */
1161
1157
  function combineImports(imports, exports, source) {
1162
1158
  const exportedNames = new Set(exports.flatMap((e) => Array.isArray(e.name) ? e.name : e.name ? [e.name] : []));
@@ -1202,11 +1198,10 @@ function combineImports(imports, exports, source) {
1202
1198
  return result;
1203
1199
  }
1204
1200
  /**
1205
- * Recursively extracts all string content embedded in a {@link CodeNode} tree.
1201
+ * Extracts all string content from a `CodeNode` tree recursively.
1206
1202
  *
1207
- * Includes text node values, and string attribute fields (`params`, `generics`,
1208
- * `returnType`, `type`) that may reference identifiers needing imports.
1209
- * Used by `createFile` to build the full source string for import filtering.
1203
+ * Collects text node values, identifier references in string fields (`params`, `generics`, `returnType`, `type`),
1204
+ * and nested node content. Used internally to build the full source string for import filtering.
1210
1205
  */
1211
1206
  function extractStringsFromNodes(nodes) {
1212
1207
  if (!nodes?.length) return "";
@@ -1226,9 +1221,10 @@ function extractStringsFromNodes(nodes) {
1226
1221
  }).filter(Boolean).join("\n");
1227
1222
  }
1228
1223
  /**
1229
- * Resolves the referenced schema name of a `ref` node, falling back through
1230
- * `ref` → `name` → nested `schema.name`. Returns `undefined` for non-ref
1231
- * nodes or when no name can be resolved.
1224
+ * Resolves the schema name of a ref node, falling back through `ref` → `name` → nested `schema.name`.
1225
+ *
1226
+ * Returns `undefined` for non-ref nodes or when no name can be resolved. Use this to get a schema's
1227
+ * identifier for type definitions or error messages.
1232
1228
  *
1233
1229
  * @example
1234
1230
  * ```ts
@@ -1242,15 +1238,12 @@ function resolveRefName(node) {
1242
1238
  return node.name ?? node.schema?.name ?? void 0;
1243
1239
  }
1244
1240
  /**
1245
- * Recursively collects every named schema referenced (transitively) from
1246
- * `node` via `ref` edges. Refs are followed by name only — the resolved
1247
- * `node.schema` of a ref is not traversed inline.
1241
+ * Collects every named schema referenced (transitively) from a node via ref edges.
1248
1242
  *
1249
- * @example
1250
- * ```ts
1251
- * const refs = collectReferencedSchemaNames(petSchema)
1252
- * // => Set { 'Cat', 'Dog' }
1253
- * ```
1243
+ * Refs are followed by name only — the resolved `node.schema` is not traversed inline.
1244
+ * Use this to determine schema dependencies, build reference graphs, or detect what schemas need to be emitted.
1245
+ *
1246
+ * @note Returns a Set of schema names for efficient membership testing.
1254
1247
  */
1255
1248
  function collectReferencedSchemaNames(node, out = /* @__PURE__ */ new Set()) {
1256
1249
  if (!node) return out;
@@ -1263,26 +1256,13 @@ function collectReferencedSchemaNames(node, out = /* @__PURE__ */ new Set()) {
1263
1256
  return out;
1264
1257
  }
1265
1258
  /**
1266
- * Identifies every named schema that participates in a circular dependency
1267
- * chain — including direct self-loops (e.g. `TreeNode → TreeNode`) and indirect
1268
- * cycles spanning multiple schemas (e.g. `Pet → Cat → Pet`).
1269
- *
1270
- * The returned set contains schema names. Plugins that translate schemas into
1271
- * a host language can use this to wrap recursive positions in a deferred
1272
- * construct (lazy getter, `z.lazy(() => …)`, etc.) and avoid runtime stack
1273
- * overflows when the generated code is executed.
1259
+ * Identifies all schemas that participate in circular dependency chains, including direct self-loops.
1274
1260
  *
1275
- * Refs are followed by name only `node.schema` (the resolved referent) is
1276
- * not traversed inline, which keeps the algorithm linear in the size of the
1277
- * schema graph.
1261
+ * Returns a Set of schema names with circular dependencies. Use this to wrap recursive schema positions
1262
+ * in deferred constructs (lazy getter, `z.lazy(() => …)`) to prevent infinite recursion when generated code runs.
1263
+ * Refs are followed by name only, keeping the algorithm linear in the schema graph size.
1278
1264
  *
1279
- * @example
1280
- * ```ts
1281
- * const circular = findCircularSchemas(inputNode.schemas)
1282
- * if (circular.has('Pet')) {
1283
- * // emit lazy wrapper for any property whose schema references Pet
1284
- * }
1285
- * ```
1265
+ * @note Call this once on the full schema graph, then use `containsCircularRef()` to check individual schemas.
1286
1266
  */
1287
1267
  function findCircularSchemas(schemas) {
1288
1268
  const graph = /* @__PURE__ */ new Map();
@@ -1309,21 +1289,12 @@ function findCircularSchemas(schemas) {
1309
1289
  return circular;
1310
1290
  }
1311
1291
  /**
1312
- * Returns true when `node` (or anything nested within it) carries a `ref`
1313
- * whose resolved name belongs to `circularSchemas`.
1292
+ * Type guard returning `true` when a schema or anything nested within it contains a ref to a circular schema.
1314
1293
  *
1315
- * When `excludeName` is provided, refs to that name are ignored — useful
1316
- * when self-references are already handled separately from cross-schema
1317
- * cycles (e.g. the faker plugin emits `undefined as any` for direct
1318
- * self-recursion but a lazy getter for indirect cycles).
1294
+ * Use `excludeName` to ignore refs to specific schemas (useful when self-references are handled separately).
1295
+ * Commonly used with `findCircularSchemas()` to detect where lazy wrappers are needed in code generation.
1319
1296
  *
1320
- * @example
1321
- * ```ts
1322
- * const circular = findCircularSchemas(schemas)
1323
- * if (containsCircularRef(property.schema, { circularSchemas: circular, excludeName: 'Pet' })) {
1324
- * // emit `get foo() { return fakeCat() }` instead of eager call
1325
- * }
1326
- * ```
1297
+ * @note Returns `true` for the first matching circular ref found; use for fast dependency checks.
1327
1298
  */
1328
1299
  function containsCircularRef(node, { circularSchemas, excludeName }) {
1329
1300
  if (!node || circularSchemas.size === 0) return false;