@kubb/ast 5.0.0-alpha.73 → 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.cjs +75 -104
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +63 -96
- package/dist/index.js +75 -104
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +30 -15
- package/src/utils.ts +54 -94
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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* -
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
3181
|
-
*
|
|
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
|
-
*
|
|
3191
|
-
*
|
|
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
|
|
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
|
-
*
|
|
3352
|
-
*
|
|
3353
|
-
*
|
|
3354
|
-
*
|
|
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
|
-
*
|
|
3355
|
+
* Extracts all string content from a `CodeNode` tree recursively.
|
|
3364
3356
|
*
|
|
3365
|
-
*
|
|
3366
|
-
*
|
|
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
|
|
3372
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
3388
|
-
*
|
|
3389
|
-
*
|
|
3390
|
-
*
|
|
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
|
|
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
|
-
*
|
|
3405
|
-
*
|
|
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
|
-
* @
|
|
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
|
-
*
|
|
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
|
-
*
|
|
3422
|
-
*
|
|
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
|
-
* @
|
|
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
|
-
*
|
|
29
|
+
* Schema type discriminators used by all AST schema nodes.
|
|
30
30
|
*
|
|
31
|
-
* These values
|
|
32
|
-
* (
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
794
|
-
*
|
|
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
|
-
*
|
|
809
|
-
*
|
|
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
|
|
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
|
-
*
|
|
886
|
-
*
|
|
887
|
-
*
|
|
888
|
-
*
|
|
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
|
|
1104
|
-
*
|
|
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
|
|
1117
|
-
*
|
|
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
|
|
1158
|
-
*
|
|
1159
|
-
*
|
|
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
|
-
*
|
|
1201
|
+
* Extracts all string content from a `CodeNode` tree recursively.
|
|
1206
1202
|
*
|
|
1207
|
-
*
|
|
1208
|
-
*
|
|
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
|
|
1230
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
1250
|
-
*
|
|
1251
|
-
*
|
|
1252
|
-
*
|
|
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
|
|
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
|
-
*
|
|
1276
|
-
*
|
|
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
|
-
* @
|
|
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
|
-
*
|
|
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
|
-
*
|
|
1316
|
-
*
|
|
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
|
-
* @
|
|
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;
|