@kubb/ast 5.0.0-alpha.2 → 5.0.0-alpha.20
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 +1031 -128
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +273 -9
- package/dist/index.js +1008 -129
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/visitor-DCQyoFvH.d.ts +1976 -0
- package/package.json +3 -2
- package/src/constants.ts +97 -4
- package/src/factory.ts +276 -18
- package/src/guards.ts +63 -8
- package/src/index.ts +32 -6
- package/src/infer.ts +130 -0
- package/src/mocks.ts +12 -5
- package/src/nodes/base.ts +31 -4
- package/src/nodes/function.ts +131 -0
- package/src/nodes/http.ts +17 -5
- package/src/nodes/index.ts +18 -5
- package/src/nodes/operation.ts +61 -4
- package/src/nodes/parameter.ts +27 -1
- package/src/nodes/property.ts +23 -1
- package/src/nodes/response.ts +29 -3
- package/src/nodes/root.ts +41 -10
- package/src/nodes/schema.ts +328 -38
- package/src/printers/functionPrinter.ts +196 -0
- package/src/printers/index.ts +3 -0
- package/src/printers/printer.ts +204 -0
- package/src/refs.ts +36 -4
- package/src/resolvers.ts +45 -0
- package/src/transformers.ts +196 -0
- package/src/types.ts +9 -2
- package/src/utils.ts +77 -0
- package/src/visitor.ts +376 -81
- package/dist/visitor-CmsfJzro.d.ts +0 -649
- package/src/printer.ts +0 -129
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/ast",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.20",
|
|
4
4
|
"description": "Spec-agnostic AST layer for Kubb. Defines nodes, visitor pattern, and factory functions used across codegen plugins.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"kubb",
|
|
@@ -45,7 +45,8 @@
|
|
|
45
45
|
"!/**/__snapshots__/**"
|
|
46
46
|
],
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@types/node": "^22.19.15"
|
|
48
|
+
"@types/node": "^22.19.15",
|
|
49
|
+
"@internals/utils": "0.0.0"
|
|
49
50
|
},
|
|
50
51
|
"main": "./dist/index.cjs",
|
|
51
52
|
"module": "./dist/index.js",
|
package/src/constants.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { ParameterLocation } from './nodes/parameter.ts'
|
|
|
5
5
|
import type { SchemaType } from './nodes/schema.ts'
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Traversal depth used by AST visitor utilities.
|
|
9
9
|
*/
|
|
10
10
|
export type VisitorDepth = 'shallow' | 'deep'
|
|
11
11
|
|
|
@@ -21,9 +21,26 @@ export const nodeKinds = {
|
|
|
21
21
|
property: 'Property',
|
|
22
22
|
parameter: 'Parameter',
|
|
23
23
|
response: 'Response',
|
|
24
|
-
|
|
24
|
+
functionParameter: 'FunctionParameter',
|
|
25
|
+
objectBindingParameter: 'ObjectBindingParameter',
|
|
26
|
+
functionParameters: 'FunctionParameters',
|
|
27
|
+
} as const satisfies Record<string, NodeKind>
|
|
25
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Canonical schema type strings used by AST schema nodes.
|
|
31
|
+
*
|
|
32
|
+
* These values are used across the AST as stable discriminators
|
|
33
|
+
* (for example `schema.type === schemaTypes.object`).
|
|
34
|
+
*
|
|
35
|
+
* The map is grouped by intent:
|
|
36
|
+
* - primitives (`string`, `number`, `boolean`, ...)
|
|
37
|
+
* - structural/composite (`object`, `array`, `union`, ...)
|
|
38
|
+
* - special OpenAPI-oriented types (`ref`, `datetime`, `uuid`, ...)
|
|
39
|
+
*/
|
|
26
40
|
export const schemaTypes = {
|
|
41
|
+
/**
|
|
42
|
+
* Text value.
|
|
43
|
+
*/
|
|
27
44
|
string: 'string',
|
|
28
45
|
/**
|
|
29
46
|
* Floating-point number (`float`, `double`).
|
|
@@ -37,27 +54,93 @@ export const schemaTypes = {
|
|
|
37
54
|
* 64-bit integer (`int64`). Only used when `integerType` is set to `'bigint'`.
|
|
38
55
|
*/
|
|
39
56
|
bigint: 'bigint',
|
|
57
|
+
/**
|
|
58
|
+
* Boolean value
|
|
59
|
+
*/
|
|
40
60
|
boolean: 'boolean',
|
|
61
|
+
/**
|
|
62
|
+
* Explicit null value.
|
|
63
|
+
*/
|
|
41
64
|
null: 'null',
|
|
65
|
+
/**
|
|
66
|
+
* Any value (no type restriction).
|
|
67
|
+
*/
|
|
42
68
|
any: 'any',
|
|
69
|
+
/**
|
|
70
|
+
* Unknown value (must be narrowed before usage).
|
|
71
|
+
*/
|
|
43
72
|
unknown: 'unknown',
|
|
73
|
+
/**
|
|
74
|
+
* No return value (`void`).
|
|
75
|
+
*/
|
|
44
76
|
void: 'void',
|
|
77
|
+
/**
|
|
78
|
+
* Object with named properties.
|
|
79
|
+
*/
|
|
45
80
|
object: 'object',
|
|
81
|
+
/**
|
|
82
|
+
* Sequential list of items.
|
|
83
|
+
*/
|
|
46
84
|
array: 'array',
|
|
85
|
+
/**
|
|
86
|
+
* Fixed-length list with position-specific items.
|
|
87
|
+
*/
|
|
47
88
|
tuple: 'tuple',
|
|
89
|
+
/**
|
|
90
|
+
* "One of" multiple schema members.
|
|
91
|
+
*/
|
|
48
92
|
union: 'union',
|
|
93
|
+
/**
|
|
94
|
+
* "All of" multiple schema members.
|
|
95
|
+
*/
|
|
49
96
|
intersection: 'intersection',
|
|
97
|
+
/**
|
|
98
|
+
* Enum schema.
|
|
99
|
+
*/
|
|
50
100
|
enum: 'enum',
|
|
101
|
+
/**
|
|
102
|
+
* Reference to another schema.
|
|
103
|
+
*/
|
|
51
104
|
ref: 'ref',
|
|
105
|
+
/**
|
|
106
|
+
* Calendar date (for example `2026-03-24`).
|
|
107
|
+
*/
|
|
52
108
|
date: 'date',
|
|
109
|
+
/**
|
|
110
|
+
* Date-time value (for example `2026-03-24T09:00:00Z`).
|
|
111
|
+
*/
|
|
53
112
|
datetime: 'datetime',
|
|
113
|
+
/**
|
|
114
|
+
* Time-only value (for example `09:00:00`).
|
|
115
|
+
*/
|
|
54
116
|
time: 'time',
|
|
117
|
+
/**
|
|
118
|
+
* UUID value.
|
|
119
|
+
*/
|
|
55
120
|
uuid: 'uuid',
|
|
121
|
+
/**
|
|
122
|
+
* Email address value.
|
|
123
|
+
*/
|
|
56
124
|
email: 'email',
|
|
125
|
+
/**
|
|
126
|
+
* URL value.
|
|
127
|
+
*/
|
|
57
128
|
url: 'url',
|
|
129
|
+
/**
|
|
130
|
+
* Binary/blob value.
|
|
131
|
+
*/
|
|
58
132
|
blob: 'blob',
|
|
133
|
+
/**
|
|
134
|
+
* Impossible value (`never`).
|
|
135
|
+
*/
|
|
136
|
+
never: 'never',
|
|
59
137
|
} as const satisfies Record<SchemaType, SchemaType>
|
|
60
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Primitive scalar schema types used when simplifying union members.
|
|
141
|
+
*/
|
|
142
|
+
export const SCALAR_PRIMITIVE_TYPES = new Set(['string', 'number', 'integer', 'bigint', 'boolean'] as const)
|
|
143
|
+
|
|
61
144
|
export const httpMethods = {
|
|
62
145
|
get: 'GET',
|
|
63
146
|
post: 'POST',
|
|
@@ -77,12 +160,22 @@ export const parameterLocations = {
|
|
|
77
160
|
} as const satisfies Record<ParameterLocation, ParameterLocation>
|
|
78
161
|
|
|
79
162
|
/**
|
|
80
|
-
* Default
|
|
163
|
+
* Default maximum number of concurrent callbacks used by `walk`.
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```ts
|
|
167
|
+
* walk(root, { concurrency: WALK_CONCURRENCY, root: () => {} })
|
|
168
|
+
* ```
|
|
81
169
|
*/
|
|
82
170
|
export const WALK_CONCURRENCY = 30
|
|
83
171
|
|
|
84
172
|
/**
|
|
85
|
-
* Fallback status code
|
|
173
|
+
* Fallback response status code used for catch-all responses.
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```ts
|
|
177
|
+
* const status = DEFAULT_STATUS_CODE // 'default'
|
|
178
|
+
* ```
|
|
86
179
|
*/
|
|
87
180
|
export const DEFAULT_STATUS_CODE = 'default' as const
|
|
88
181
|
|
package/src/factory.ts
CHANGED
|
@@ -1,12 +1,49 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { InferSchemaNode } from './infer.ts'
|
|
2
|
+
import type {
|
|
3
|
+
FunctionParameterNode,
|
|
4
|
+
FunctionParametersNode,
|
|
5
|
+
ObjectBindingParameterNode,
|
|
6
|
+
ObjectSchemaNode,
|
|
7
|
+
OperationNode,
|
|
8
|
+
ParameterNode,
|
|
9
|
+
PropertyNode,
|
|
10
|
+
ResponseNode,
|
|
11
|
+
RootNode,
|
|
12
|
+
SchemaNode,
|
|
13
|
+
} from './nodes/index.ts'
|
|
14
|
+
import { syncOptionality } from './utils.ts'
|
|
2
15
|
|
|
3
16
|
/**
|
|
4
|
-
* Distributive
|
|
17
|
+
* Distributive `Omit` that preserves each member of a union.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* type A = { kind: 'a'; keep: string; drop: number }
|
|
22
|
+
* type B = { kind: 'b'; keep: boolean; drop: number }
|
|
23
|
+
* type Result = DistributiveOmit<A | B, 'drop'>
|
|
24
|
+
* // -> { kind: 'a'; keep: string } | { kind: 'b'; keep: boolean }
|
|
25
|
+
* ```
|
|
5
26
|
*/
|
|
6
27
|
export type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never
|
|
7
28
|
|
|
29
|
+
type CreateSchemaObjectInput = Omit<ObjectSchemaNode, 'kind' | 'properties'> & { properties?: Array<PropertyNode> }
|
|
30
|
+
type CreateSchemaInput = CreateSchemaObjectInput | DistributiveOmit<Exclude<SchemaNode, ObjectSchemaNode>, 'kind'>
|
|
31
|
+
type CreateSchemaOutput<T extends CreateSchemaInput> = InferSchemaNode<T> & { kind: 'Schema' }
|
|
32
|
+
|
|
8
33
|
/**
|
|
9
|
-
* Creates a `RootNode`.
|
|
34
|
+
* Creates a `RootNode` with stable defaults for `schemas` and `operations`.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* const root = createRoot()
|
|
39
|
+
* // { kind: 'Root', schemas: [], operations: [] }
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* const root = createRoot({ schemas: [petSchema] })
|
|
45
|
+
* // keeps default operations: []
|
|
46
|
+
* ```
|
|
10
47
|
*/
|
|
11
48
|
export function createRoot(overrides: Partial<Omit<RootNode, 'kind'>> = {}): RootNode {
|
|
12
49
|
return {
|
|
@@ -18,7 +55,27 @@ export function createRoot(overrides: Partial<Omit<RootNode, 'kind'>> = {}): Roo
|
|
|
18
55
|
}
|
|
19
56
|
|
|
20
57
|
/**
|
|
21
|
-
* Creates an `OperationNode`.
|
|
58
|
+
* Creates an `OperationNode` with default empty arrays for `tags`, `parameters`, and `responses`.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* const operation = createOperation({
|
|
63
|
+
* operationId: 'getPetById',
|
|
64
|
+
* method: 'GET',
|
|
65
|
+
* path: '/pet/{petId}',
|
|
66
|
+
* })
|
|
67
|
+
* // tags, parameters, and responses are []
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* const operation = createOperation({
|
|
73
|
+
* operationId: 'findPets',
|
|
74
|
+
* method: 'GET',
|
|
75
|
+
* path: '/pet/findByStatus',
|
|
76
|
+
* tags: ['pet'],
|
|
77
|
+
* })
|
|
78
|
+
* ```
|
|
22
79
|
*/
|
|
23
80
|
export function createOperation(
|
|
24
81
|
props: Pick<OperationNode, 'operationId' | 'method' | 'path'> & Partial<Omit<OperationNode, 'kind' | 'operationId' | 'method' | 'path'>>,
|
|
@@ -34,51 +91,252 @@ export function createOperation(
|
|
|
34
91
|
|
|
35
92
|
/**
|
|
36
93
|
* Creates a `SchemaNode`, narrowed to the variant of `props.type`.
|
|
37
|
-
* For object schemas, `properties` defaults to
|
|
94
|
+
* For object schemas, `properties` defaults to an empty array.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* const scalar = createSchema({ type: 'string' })
|
|
99
|
+
* // { kind: 'Schema', type: 'string' }
|
|
100
|
+
* ```
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* const object = createSchema({ type: 'object' })
|
|
105
|
+
* // { kind: 'Schema', type: 'object', properties: [] }
|
|
106
|
+
* ```
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* const enumSchema = createSchema({
|
|
111
|
+
* type: 'enum',
|
|
112
|
+
* primitive: 'string',
|
|
113
|
+
* enumValues: ['available', 'pending'],
|
|
114
|
+
* })
|
|
115
|
+
* ```
|
|
38
116
|
*/
|
|
39
|
-
export function createSchema<T extends
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export function createSchema<T extends DistributiveOmit<Exclude<SchemaNode, ObjectSchemaNode>, 'kind'>>(props: T): T & { kind: 'Schema' }
|
|
43
|
-
export function createSchema(props: DistributiveOmit<SchemaNode, 'kind'>): SchemaNode
|
|
44
|
-
export function createSchema(props: Record<string, unknown>): Record<string, unknown> {
|
|
117
|
+
export function createSchema<T extends CreateSchemaInput>(props: T): CreateSchemaOutput<T>
|
|
118
|
+
export function createSchema(props: CreateSchemaInput): SchemaNode
|
|
119
|
+
export function createSchema(props: CreateSchemaInput): SchemaNode {
|
|
45
120
|
if (props['type'] === 'object') {
|
|
46
|
-
return { properties: [], ...props, kind: 'Schema' }
|
|
121
|
+
return { properties: [], ...props, kind: 'Schema' } as CreateSchemaOutput<typeof props>
|
|
47
122
|
}
|
|
48
123
|
|
|
49
|
-
return { ...props, kind: 'Schema' }
|
|
124
|
+
return { ...props, kind: 'Schema' } as CreateSchemaOutput<typeof props>
|
|
50
125
|
}
|
|
51
126
|
|
|
52
127
|
/**
|
|
53
|
-
* Creates a `PropertyNode`.
|
|
128
|
+
* Creates a `PropertyNode`.
|
|
129
|
+
*
|
|
130
|
+
* `required` defaults to `false`.
|
|
131
|
+
* `schema.optional` and `schema.nullish` are derived from `required` and `schema.nullable`.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* const property = createProperty({
|
|
136
|
+
* name: 'status',
|
|
137
|
+
* schema: createSchema({ type: 'string' }),
|
|
138
|
+
* })
|
|
139
|
+
* // required=false, schema.optional=true
|
|
140
|
+
* ```
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```ts
|
|
144
|
+
* const property = createProperty({
|
|
145
|
+
* name: 'status',
|
|
146
|
+
* required: true,
|
|
147
|
+
* schema: createSchema({ type: 'string', nullable: true }),
|
|
148
|
+
* })
|
|
149
|
+
* // required=true, no optional/nullish
|
|
150
|
+
* ```
|
|
54
151
|
*/
|
|
55
152
|
export function createProperty(props: Pick<PropertyNode, 'name' | 'schema'> & Partial<Omit<PropertyNode, 'kind' | 'name' | 'schema'>>): PropertyNode {
|
|
153
|
+
const required = props.required ?? false
|
|
154
|
+
|
|
56
155
|
return {
|
|
57
|
-
required: false,
|
|
58
156
|
...props,
|
|
59
157
|
kind: 'Property',
|
|
158
|
+
required,
|
|
159
|
+
schema: syncOptionality(required, props.schema),
|
|
60
160
|
}
|
|
61
161
|
}
|
|
62
162
|
|
|
63
163
|
/**
|
|
64
|
-
* Creates a `ParameterNode`.
|
|
164
|
+
* Creates a `ParameterNode`.
|
|
165
|
+
*
|
|
166
|
+
* `required` defaults to `false`.
|
|
167
|
+
* Nested schema flags are set from `required` and `schema.nullable`.
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```ts
|
|
171
|
+
* const param = createParameter({
|
|
172
|
+
* name: 'petId',
|
|
173
|
+
* in: 'path',
|
|
174
|
+
* required: true,
|
|
175
|
+
* schema: createSchema({ type: 'string' }),
|
|
176
|
+
* })
|
|
177
|
+
* ```
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```ts
|
|
181
|
+
* const param = createParameter({
|
|
182
|
+
* name: 'status',
|
|
183
|
+
* in: 'query',
|
|
184
|
+
* schema: createSchema({ type: 'string', nullable: true }),
|
|
185
|
+
* })
|
|
186
|
+
* // required=false, schema.nullish=true
|
|
187
|
+
* ```
|
|
65
188
|
*/
|
|
66
189
|
export function createParameter(
|
|
67
190
|
props: Pick<ParameterNode, 'name' | 'in' | 'schema'> & Partial<Omit<ParameterNode, 'kind' | 'name' | 'in' | 'schema'>>,
|
|
68
191
|
): ParameterNode {
|
|
192
|
+
const required = props.required ?? false
|
|
69
193
|
return {
|
|
70
|
-
required: false,
|
|
71
194
|
...props,
|
|
72
195
|
kind: 'Parameter',
|
|
196
|
+
required,
|
|
197
|
+
schema: syncOptionality(required, props.schema),
|
|
73
198
|
}
|
|
74
199
|
}
|
|
75
200
|
|
|
76
201
|
/**
|
|
77
202
|
* Creates a `ResponseNode`.
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```ts
|
|
206
|
+
* const response = createResponse({
|
|
207
|
+
* statusCode: '200',
|
|
208
|
+
* description: 'Success',
|
|
209
|
+
* schema: createSchema({ type: 'object', properties: [] }),
|
|
210
|
+
* })
|
|
211
|
+
* ```
|
|
78
212
|
*/
|
|
79
|
-
export function createResponse(
|
|
213
|
+
export function createResponse(
|
|
214
|
+
props: Pick<ResponseNode, 'statusCode' | 'schema'> & Partial<Omit<ResponseNode, 'kind' | 'statusCode' | 'schema'>>,
|
|
215
|
+
): ResponseNode {
|
|
80
216
|
return {
|
|
81
217
|
...props,
|
|
82
218
|
kind: 'Response',
|
|
83
219
|
}
|
|
84
220
|
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Creates a single-property object schema used as a discriminator literal.
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```ts
|
|
227
|
+
* createDiscriminantNode({ propertyName: 'type', value: 'dog' })
|
|
228
|
+
* // -> { type: 'object', properties: [{ name: 'type', required: true, schema: enum('dog') }] }
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
231
|
+
export function createDiscriminantNode({ propertyName, value }: { propertyName: string; value: string }): SchemaNode {
|
|
232
|
+
return createSchema({
|
|
233
|
+
type: 'object',
|
|
234
|
+
primitive: 'object',
|
|
235
|
+
properties: [
|
|
236
|
+
createProperty({
|
|
237
|
+
name: propertyName,
|
|
238
|
+
schema: createSchema({
|
|
239
|
+
type: 'enum',
|
|
240
|
+
primitive: 'string',
|
|
241
|
+
enumValues: [value],
|
|
242
|
+
}),
|
|
243
|
+
required: true,
|
|
244
|
+
}),
|
|
245
|
+
],
|
|
246
|
+
})
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Creates a `FunctionParameterNode`.
|
|
251
|
+
*
|
|
252
|
+
* `optional` defaults to `false`.
|
|
253
|
+
*
|
|
254
|
+
* @example Required typed param
|
|
255
|
+
* ```ts
|
|
256
|
+
* createFunctionParameter({ name: 'petId', type: 'string' })
|
|
257
|
+
* // → petId: string
|
|
258
|
+
* ```
|
|
259
|
+
*
|
|
260
|
+
* @example Optional param
|
|
261
|
+
* ```ts
|
|
262
|
+
* createFunctionParameter({ name: 'params', type: 'QueryParams', optional: true })
|
|
263
|
+
* // → params?: QueryParams
|
|
264
|
+
* ```
|
|
265
|
+
*
|
|
266
|
+
* @example Param with default (implicitly optional; cannot combine with `optional: true`)
|
|
267
|
+
* ```ts
|
|
268
|
+
* createFunctionParameter({ name: 'config', type: 'RequestConfig', default: '{}' })
|
|
269
|
+
* // → config: RequestConfig = {}
|
|
270
|
+
* ```
|
|
271
|
+
*/
|
|
272
|
+
export function createFunctionParameter(
|
|
273
|
+
props: { name: string; type?: string; rest?: boolean } & ({ optional: true; default?: never } | { optional?: false; default?: string }),
|
|
274
|
+
): FunctionParameterNode {
|
|
275
|
+
return {
|
|
276
|
+
optional: false,
|
|
277
|
+
...props,
|
|
278
|
+
kind: 'FunctionParameter',
|
|
279
|
+
} as FunctionParameterNode
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Creates an `ObjectBindingParameterNode` for object-destructured parameter groups.
|
|
284
|
+
*
|
|
285
|
+
* @example Destructured object param
|
|
286
|
+
* ```ts
|
|
287
|
+
* createObjectBindingParameter({
|
|
288
|
+
* properties: [
|
|
289
|
+
* createFunctionParameter({ name: 'id', type: 'string', optional: false }),
|
|
290
|
+
* createFunctionParameter({ name: 'name', type: 'string', optional: true }),
|
|
291
|
+
* ],
|
|
292
|
+
* default: '{}',
|
|
293
|
+
* })
|
|
294
|
+
* // declaration → { id, name? }: { id: string; name?: string } = {}
|
|
295
|
+
* // call → { id, name }
|
|
296
|
+
* ```
|
|
297
|
+
*
|
|
298
|
+
* @example Inline mode — children emitted as individual top-level parameters
|
|
299
|
+
* ```ts
|
|
300
|
+
* createObjectBindingParameter({
|
|
301
|
+
* properties: [createFunctionParameter({ name: 'petId', type: 'string', optional: false })],
|
|
302
|
+
* inline: true,
|
|
303
|
+
* })
|
|
304
|
+
* // declaration → petId: string
|
|
305
|
+
* // call → petId
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
export function createObjectBindingParameter(
|
|
309
|
+
props: Pick<ObjectBindingParameterNode, 'properties'> & Partial<Omit<ObjectBindingParameterNode, 'kind' | 'properties'>>,
|
|
310
|
+
): ObjectBindingParameterNode {
|
|
311
|
+
return {
|
|
312
|
+
...props,
|
|
313
|
+
kind: 'ObjectBindingParameter',
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Creates a `FunctionParametersNode` from an ordered list of parameters.
|
|
319
|
+
*
|
|
320
|
+
* @example
|
|
321
|
+
* ```ts
|
|
322
|
+
* createFunctionParameters({
|
|
323
|
+
* params: [
|
|
324
|
+
* createFunctionParameter({ name: 'petId', type: 'string', optional: false }),
|
|
325
|
+
* createFunctionParameter({ name: 'config', type: 'RequestConfig', optional: false, default: '{}' }),
|
|
326
|
+
* ],
|
|
327
|
+
* })
|
|
328
|
+
* ```
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
* ```ts
|
|
332
|
+
* const empty = createFunctionParameters()
|
|
333
|
+
* // { kind: 'FunctionParameters', params: [] }
|
|
334
|
+
* ```
|
|
335
|
+
*/
|
|
336
|
+
export function createFunctionParameters(props: Partial<Omit<FunctionParametersNode, 'kind'>> = {}): FunctionParametersNode {
|
|
337
|
+
return {
|
|
338
|
+
params: [],
|
|
339
|
+
...props,
|
|
340
|
+
kind: 'FunctionParameters',
|
|
341
|
+
}
|
|
342
|
+
}
|
package/src/guards.ts
CHANGED
|
@@ -1,7 +1,26 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
FunctionParameterNode,
|
|
3
|
+
FunctionParametersNode,
|
|
4
|
+
Node,
|
|
5
|
+
NodeKind,
|
|
6
|
+
ObjectBindingParameterNode,
|
|
7
|
+
OperationNode,
|
|
8
|
+
ParameterNode,
|
|
9
|
+
PropertyNode,
|
|
10
|
+
ResponseNode,
|
|
11
|
+
RootNode,
|
|
12
|
+
SchemaNode,
|
|
13
|
+
SchemaNodeByType,
|
|
14
|
+
} from './nodes/index.ts'
|
|
2
15
|
|
|
3
16
|
/**
|
|
4
|
-
* Narrows a `SchemaNode` to the
|
|
17
|
+
* Narrows a `SchemaNode` to the variant that matches `type`.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const schema = createSchema({ type: 'string' })
|
|
22
|
+
* const stringNode = narrowSchema(schema, 'string') // StringSchemaNode | undefined
|
|
23
|
+
* ```
|
|
5
24
|
*/
|
|
6
25
|
export function narrowSchema<T extends SchemaNode['type']>(node: SchemaNode | undefined, type: T): SchemaNodeByType[T] | undefined {
|
|
7
26
|
return node?.type === type ? (node as SchemaNodeByType[T]) : undefined
|
|
@@ -12,31 +31,67 @@ function isKind<T extends Node>(kind: NodeKind) {
|
|
|
12
31
|
}
|
|
13
32
|
|
|
14
33
|
/**
|
|
15
|
-
*
|
|
34
|
+
* Returns `true` when the input is a `RootNode`.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* if (isRootNode(node)) {
|
|
39
|
+
* console.log(node.schemas.length)
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
16
42
|
*/
|
|
17
43
|
export const isRootNode = isKind<RootNode>('Root')
|
|
18
44
|
|
|
19
45
|
/**
|
|
20
|
-
*
|
|
46
|
+
* Returns `true` when the input is an `OperationNode`.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* if (isOperationNode(node)) {
|
|
51
|
+
* console.log(node.operationId)
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
21
54
|
*/
|
|
22
55
|
export const isOperationNode = isKind<OperationNode>('Operation')
|
|
23
56
|
|
|
24
57
|
/**
|
|
25
|
-
*
|
|
58
|
+
* Returns `true` when the input is a `SchemaNode`.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* if (isSchemaNode(node)) {
|
|
63
|
+
* console.log(node.type)
|
|
64
|
+
* }
|
|
65
|
+
* ```
|
|
26
66
|
*/
|
|
27
67
|
export const isSchemaNode = isKind<SchemaNode>('Schema')
|
|
28
68
|
|
|
29
69
|
/**
|
|
30
|
-
*
|
|
70
|
+
* Returns `true` when the input is a `PropertyNode`.
|
|
31
71
|
*/
|
|
32
72
|
export const isPropertyNode = isKind<PropertyNode>('Property')
|
|
33
73
|
|
|
34
74
|
/**
|
|
35
|
-
*
|
|
75
|
+
* Returns `true` when the input is a `ParameterNode`.
|
|
36
76
|
*/
|
|
37
77
|
export const isParameterNode = isKind<ParameterNode>('Parameter')
|
|
38
78
|
|
|
39
79
|
/**
|
|
40
|
-
*
|
|
80
|
+
* Returns `true` when the input is a `ResponseNode`.
|
|
41
81
|
*/
|
|
42
82
|
export const isResponseNode = isKind<ResponseNode>('Response')
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Returns `true` when the input is a `FunctionParameterNode`.
|
|
86
|
+
*/
|
|
87
|
+
export const isFunctionParameterNode = isKind<FunctionParameterNode>('FunctionParameter')
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Returns `true` when the input is an `ObjectBindingParameterNode`.
|
|
91
|
+
*/
|
|
92
|
+
export const isObjectBindingParameterNode = isKind<ObjectBindingParameterNode>('ObjectBindingParameter')
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Returns `true` when the input is a `FunctionParametersNode`.
|
|
96
|
+
*/
|
|
97
|
+
export const isFunctionParametersNode = isKind<FunctionParametersNode>('FunctionParameters')
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,32 @@
|
|
|
1
|
-
export { httpMethods, mediaTypes, nodeKinds, schemaTypes } from './constants.ts'
|
|
2
|
-
export {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
export { httpMethods, mediaTypes, nodeKinds, SCALAR_PRIMITIVE_TYPES, schemaTypes } from './constants.ts'
|
|
2
|
+
export {
|
|
3
|
+
createDiscriminantNode,
|
|
4
|
+
createFunctionParameter,
|
|
5
|
+
createFunctionParameters,
|
|
6
|
+
createObjectBindingParameter,
|
|
7
|
+
createOperation,
|
|
8
|
+
createParameter,
|
|
9
|
+
createProperty,
|
|
10
|
+
createResponse,
|
|
11
|
+
createRoot,
|
|
12
|
+
createSchema,
|
|
13
|
+
} from './factory.ts'
|
|
14
|
+
export {
|
|
15
|
+
isFunctionParameterNode,
|
|
16
|
+
isFunctionParametersNode,
|
|
17
|
+
isObjectBindingParameterNode,
|
|
18
|
+
isOperationNode,
|
|
19
|
+
isParameterNode,
|
|
20
|
+
isPropertyNode,
|
|
21
|
+
isResponseNode,
|
|
22
|
+
isRootNode,
|
|
23
|
+
isSchemaNode,
|
|
24
|
+
narrowSchema,
|
|
25
|
+
} from './guards.ts'
|
|
26
|
+
export type { InferSchema, InferSchemaNode, ParserOptions } from './infer.ts'
|
|
27
|
+
export { defineFunctionPrinter, definePrinter, functionPrinter } from './printers/index.ts'
|
|
28
|
+
export { buildRefMap, extractRefName, refMapToObject, resolveRef } from './refs.ts'
|
|
29
|
+
export { childName, collectImports, enumPropName, findDiscriminator } from './resolvers.ts'
|
|
30
|
+
export { mergeAdjacentObjects, resolveNames, setDiscriminatorEnum, setEnumName, simplifyUnion } from './transformers.ts'
|
|
31
|
+
export { caseParams, isStringType, syncOptionality } from './utils.ts'
|
|
32
|
+
export { collect, composeTransformers, transform, walk } from './visitor.ts'
|