@kubb/ast 5.0.0-beta.56 → 5.0.0-beta.57
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/README.md +2 -2
- package/dist/index.cjs +1710 -1745
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -46
- package/dist/index.js +1682 -1740
- package/dist/index.js.map +1 -1
- package/dist/{types-BL7RpQAE.d.ts → types-C5aVnRE1.d.ts} +1730 -1789
- package/dist/types.d.ts +2 -2
- package/package.json +1 -1
- package/src/dedupe.ts +1 -1
- package/src/factory.ts +3 -763
- package/src/guards.ts +1 -53
- package/src/index.ts +35 -20
- package/src/mocks.ts +6 -1
- package/src/node.ts +128 -0
- package/src/nodes/base.ts +3 -2
- package/src/nodes/code.ts +115 -0
- package/src/nodes/content.ts +19 -0
- package/src/nodes/file.ts +54 -0
- package/src/nodes/function.ts +221 -146
- package/src/nodes/index.ts +11 -3
- package/src/nodes/input.ts +36 -0
- package/src/nodes/operation.ts +59 -1
- package/src/nodes/output.ts +23 -0
- package/src/nodes/parameter.ts +33 -0
- package/src/nodes/property.ts +36 -0
- package/src/nodes/requestBody.ts +23 -1
- package/src/nodes/response.ts +39 -1
- package/src/nodes/schema.ts +72 -0
- package/src/registry.ts +70 -0
- package/src/transformers.ts +2 -2
- package/src/types.ts +5 -3
- package/src/utils/ast.ts +116 -193
- package/src/visitor.ts +3 -47
package/src/nodes/function.ts
CHANGED
|
@@ -1,84 +1,110 @@
|
|
|
1
|
+
import { defineNode } from '../node.ts'
|
|
1
2
|
import type { BaseNode } from './base.ts'
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
-
* type annotation. Each language printer renders the variant into its own syntax.
|
|
5
|
+
* A language-agnostic type expression used as a function parameter type annotation.
|
|
6
6
|
*
|
|
7
|
-
* - `
|
|
8
|
-
*
|
|
9
|
-
* -
|
|
10
|
-
|
|
7
|
+
* - a plain `string` is a type reference rendered as-is, e.g. `'string'`, `'QueryParams'`, `'Partial<Config>'`
|
|
8
|
+
* - a {@link TypeLiteralNode} is an inline anonymous type, e.g. `{ petId: string; name?: string }`
|
|
9
|
+
* - an {@link IndexedAccessTypeNode} is a single field accessed from a named type, e.g. `PathParams['petId']`
|
|
10
|
+
*/
|
|
11
|
+
export type TypeExpression = string | TypeLiteralNode | IndexedAccessTypeNode
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* AST node for an inline anonymous object type grouping named fields.
|
|
15
|
+
* TypeScript renders as `{ key: Type; other?: OtherType }`.
|
|
11
16
|
*
|
|
12
|
-
* @example
|
|
17
|
+
* @example
|
|
13
18
|
* ```ts
|
|
14
|
-
*
|
|
15
|
-
* //
|
|
19
|
+
* createTypeLiteral({ members: [{ name: 'petId', type: 'string', optional: false }] })
|
|
20
|
+
* // { petId: string }
|
|
16
21
|
* ```
|
|
22
|
+
*/
|
|
23
|
+
export type TypeLiteralNode = BaseNode & {
|
|
24
|
+
/**
|
|
25
|
+
* Node kind.
|
|
26
|
+
*/
|
|
27
|
+
kind: 'TypeLiteral'
|
|
28
|
+
/**
|
|
29
|
+
* Members of the object type, rendered in order.
|
|
30
|
+
*/
|
|
31
|
+
members: Array<{
|
|
32
|
+
/**
|
|
33
|
+
* Member key.
|
|
34
|
+
*/
|
|
35
|
+
name: string
|
|
36
|
+
/**
|
|
37
|
+
* Member type expression.
|
|
38
|
+
*/
|
|
39
|
+
type: TypeExpression
|
|
40
|
+
/**
|
|
41
|
+
* Whether the member is optional, rendered with `?`.
|
|
42
|
+
*/
|
|
43
|
+
optional?: boolean
|
|
44
|
+
}>
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* AST node for a single field accessed from a named group type.
|
|
49
|
+
* TypeScript renders as `objectType['indexType']`.
|
|
17
50
|
*
|
|
18
|
-
* @example
|
|
51
|
+
* @example
|
|
19
52
|
* ```ts
|
|
20
|
-
*
|
|
21
|
-
* //
|
|
53
|
+
* createIndexedAccessType({ objectType: 'GetPetPathParams', indexType: 'petId' })
|
|
54
|
+
* // GetPetPathParams['petId']
|
|
22
55
|
* ```
|
|
56
|
+
*/
|
|
57
|
+
export type IndexedAccessTypeNode = BaseNode & {
|
|
58
|
+
/**
|
|
59
|
+
* Node kind.
|
|
60
|
+
*/
|
|
61
|
+
kind: 'IndexedAccessType'
|
|
62
|
+
/**
|
|
63
|
+
* Name of the type being indexed, e.g. `'GetPetPathParams'`.
|
|
64
|
+
*/
|
|
65
|
+
objectType: string
|
|
66
|
+
/**
|
|
67
|
+
* Field key to access, e.g. `'petId'`.
|
|
68
|
+
*/
|
|
69
|
+
indexType: string
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* AST node for an object destructuring binding, used as the name of a grouped function parameter.
|
|
74
|
+
* TypeScript renders as `{ id, name }` or `{ id: renamed }` when `propertyName` differs.
|
|
23
75
|
*
|
|
24
|
-
* @example
|
|
76
|
+
* @example
|
|
25
77
|
* ```ts
|
|
26
|
-
*
|
|
27
|
-
* //
|
|
78
|
+
* createObjectBindingPattern({ elements: [{ name: 'id' }, { name: 'name' }] })
|
|
79
|
+
* // { id, name }
|
|
28
80
|
* ```
|
|
29
81
|
*/
|
|
30
|
-
export type
|
|
82
|
+
export type ObjectBindingPatternNode = BaseNode & {
|
|
31
83
|
/**
|
|
32
84
|
* Node kind.
|
|
33
85
|
*/
|
|
34
|
-
kind: '
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
* Struct variant, an inline anonymous type grouping named fields.
|
|
50
|
-
* TypeScript renders as `{ key: Type; other?: OtherType }`.
|
|
51
|
-
*/
|
|
52
|
-
variant: 'struct'
|
|
53
|
-
/**
|
|
54
|
-
* Properties of the struct type.
|
|
55
|
-
*/
|
|
56
|
-
properties: Array<{
|
|
57
|
-
name: string
|
|
58
|
-
optional: boolean
|
|
59
|
-
type: ParamsTypeNode
|
|
60
|
-
}>
|
|
61
|
-
}
|
|
62
|
-
| {
|
|
63
|
-
/**
|
|
64
|
-
* Member variant, a single named field accessed from a group type.
|
|
65
|
-
* TypeScript renders as `Base['key']`.
|
|
66
|
-
*/
|
|
67
|
-
variant: 'member'
|
|
68
|
-
/**
|
|
69
|
-
* Base type name, e.g. `'DeletePetPathParams'`.
|
|
70
|
-
*/
|
|
71
|
-
base: string
|
|
72
|
-
/**
|
|
73
|
-
* The field name to access, e.g. `'petId'`.
|
|
74
|
-
*/
|
|
75
|
-
key: string
|
|
76
|
-
}
|
|
77
|
-
)
|
|
86
|
+
kind: 'ObjectBindingPattern'
|
|
87
|
+
/**
|
|
88
|
+
* Bound elements, rendered in order.
|
|
89
|
+
*/
|
|
90
|
+
elements: Array<{
|
|
91
|
+
/**
|
|
92
|
+
* Local binding name.
|
|
93
|
+
*/
|
|
94
|
+
name: string
|
|
95
|
+
/**
|
|
96
|
+
* Source key when it differs from the binding name, rendered as `propertyName: name`.
|
|
97
|
+
*/
|
|
98
|
+
propertyName?: string
|
|
99
|
+
}>
|
|
100
|
+
}
|
|
78
101
|
|
|
79
102
|
/**
|
|
80
103
|
* AST node for one function parameter.
|
|
81
104
|
*
|
|
105
|
+
* A simple parameter has a `string` name. A destructured group has an
|
|
106
|
+
* {@link ObjectBindingPatternNode} name paired with a {@link TypeLiteralNode} type.
|
|
107
|
+
*
|
|
82
108
|
* @example Required parameter
|
|
83
109
|
* `name: Type`
|
|
84
110
|
*
|
|
@@ -90,6 +116,9 @@ export type ParamsTypeNode = BaseNode & {
|
|
|
90
116
|
*
|
|
91
117
|
* @example Rest parameter
|
|
92
118
|
* `...name: Type[]`
|
|
119
|
+
*
|
|
120
|
+
* @example Destructured group
|
|
121
|
+
* `{ id, name? }: { id: string; name?: string } = {}`
|
|
93
122
|
*/
|
|
94
123
|
export type FunctionParameterNode = BaseNode & {
|
|
95
124
|
/**
|
|
@@ -97,96 +126,25 @@ export type FunctionParameterNode = BaseNode & {
|
|
|
97
126
|
*/
|
|
98
127
|
kind: 'FunctionParameter'
|
|
99
128
|
/**
|
|
100
|
-
* Parameter name
|
|
101
|
-
*/
|
|
102
|
-
name: string
|
|
103
|
-
/**
|
|
104
|
-
* Type annotation as a structured {@link ParamsTypeNode}.
|
|
105
|
-
* Omit for untyped output.
|
|
106
|
-
*
|
|
107
|
-
* @example Reference type node
|
|
108
|
-
* `{ kind: 'ParamsType', variant: 'reference', name: 'string' }` → `petId: string`
|
|
109
|
-
*
|
|
110
|
-
* @example Struct type node
|
|
111
|
-
* `{ kind: 'ParamsType', variant: 'struct', properties: [...] }` → `{ key: Type; other?: OtherType }`
|
|
112
|
-
*
|
|
113
|
-
* @example Member type node
|
|
114
|
-
* `{ kind: 'ParamsType', variant: 'member', base: 'PathParams', key: 'petId' }` → `PathParams['petId']`
|
|
115
|
-
*/
|
|
116
|
-
type?: ParamsTypeNode
|
|
117
|
-
/**
|
|
118
|
-
* When `true` the parameter is emitted as a rest parameter.
|
|
119
|
-
*
|
|
120
|
-
* @example Rest parameter
|
|
121
|
-
* `...name: Type[]`
|
|
122
|
-
*/
|
|
123
|
-
rest?: boolean
|
|
124
|
-
} /**
|
|
125
|
-
* Optional parameter, rendered with `?` and may be omitted by the caller.
|
|
126
|
-
* Cannot be combined with `default` because a defaulted parameter is already optional.
|
|
127
|
-
*/ & (
|
|
128
|
-
| { optional: true; default?: never }
|
|
129
|
-
/**
|
|
130
|
-
* Required parameter, or a parameter with a default value.
|
|
131
|
-
*
|
|
132
|
-
* @example Required
|
|
133
|
-
* `name: Type`
|
|
134
|
-
*
|
|
135
|
-
* @example With default
|
|
136
|
-
* `name: Type = default`
|
|
137
|
-
*/
|
|
138
|
-
| { optional?: false; default?: string }
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* AST node for a group of related function parameters treated as a single unit.
|
|
143
|
-
*
|
|
144
|
-
* Each language printer decides how to render this group:
|
|
145
|
-
* - TypeScript/JS: destructured object `{ key1, key2 }: { key1: Type1; key2: Type2 } = {}`
|
|
146
|
-
* - Python: keyword-only args or a typed dict parameter
|
|
147
|
-
* - C# / Kotlin: named record / data-class parameter
|
|
148
|
-
*
|
|
149
|
-
* When `inline` is `true`, the group is spread as individual top-level parameters
|
|
150
|
-
* rather than wrapped in a single grouped construct.
|
|
151
|
-
*
|
|
152
|
-
* @example Grouped destructuring
|
|
153
|
-
* `{ id, name }: { id: string; name: string } = {}`
|
|
154
|
-
*
|
|
155
|
-
* @example Inline (spread as individual parameters)
|
|
156
|
-
* `id: string, name: string`
|
|
157
|
-
*/
|
|
158
|
-
export type ParameterGroupNode = BaseNode & {
|
|
159
|
-
/**
|
|
160
|
-
* Node kind.
|
|
161
|
-
*/
|
|
162
|
-
kind: 'ParameterGroup'
|
|
163
|
-
/**
|
|
164
|
-
* The individual parameters that form the group.
|
|
165
|
-
* Rendered as a destructured object or spread inline when `inline` is `true`.
|
|
129
|
+
* Parameter name, or an {@link ObjectBindingPatternNode} for a destructured group.
|
|
166
130
|
*/
|
|
167
|
-
|
|
131
|
+
name: string | ObjectBindingPatternNode
|
|
168
132
|
/**
|
|
169
|
-
*
|
|
170
|
-
* When absent, printers auto-compute it from `properties`.
|
|
133
|
+
* Type annotation as a {@link TypeExpression}. Omit for untyped output.
|
|
171
134
|
*/
|
|
172
|
-
type?:
|
|
135
|
+
type?: TypeExpression
|
|
173
136
|
/**
|
|
174
|
-
*
|
|
175
|
-
* being wrapped in a single grouped construct.
|
|
176
|
-
*
|
|
177
|
-
* @default false
|
|
178
|
-
*/
|
|
179
|
-
inline?: boolean
|
|
180
|
-
/**
|
|
181
|
-
* Whether the group as a whole is optional.
|
|
182
|
-
* If omitted, printers infer this from child properties.
|
|
137
|
+
* Whether the parameter is optional, rendered with `?`.
|
|
183
138
|
*/
|
|
184
139
|
optional?: boolean
|
|
185
140
|
/**
|
|
186
|
-
* Default value
|
|
187
|
-
* Commonly `'{}'` to allow omitting the argument entirely.
|
|
141
|
+
* Default value, written verbatim after `=`. Commonly `'{}'` for a destructured group.
|
|
188
142
|
*/
|
|
189
143
|
default?: string
|
|
144
|
+
/**
|
|
145
|
+
* When `true` the parameter is emitted as a rest parameter, e.g. `...name: Type[]`.
|
|
146
|
+
*/
|
|
147
|
+
rest?: boolean
|
|
190
148
|
}
|
|
191
149
|
|
|
192
150
|
/**
|
|
@@ -198,8 +156,6 @@ export type ParameterGroupNode = BaseNode & {
|
|
|
198
156
|
* Renders differently depending on the output mode:
|
|
199
157
|
* - `declaration` → `(id: string, config: Config = {})` function declaration parameters
|
|
200
158
|
* - `call` → `(id, { method, url })` function call arguments
|
|
201
|
-
* - `keys` → `{ id, config }` key names only (for destructuring)
|
|
202
|
-
* - `values` → `{ id: id, config: config }` key → value pairs
|
|
203
159
|
*/
|
|
204
160
|
export type FunctionParametersNode = BaseNode & {
|
|
205
161
|
/**
|
|
@@ -209,15 +165,134 @@ export type FunctionParametersNode = BaseNode & {
|
|
|
209
165
|
/**
|
|
210
166
|
* Ordered parameter nodes.
|
|
211
167
|
*/
|
|
212
|
-
params: ReadonlyArray<FunctionParameterNode
|
|
168
|
+
params: ReadonlyArray<FunctionParameterNode>
|
|
213
169
|
}
|
|
214
170
|
|
|
215
171
|
/**
|
|
216
172
|
* Union of all function-parameter AST node variants used by the function-parameter printer.
|
|
217
173
|
*/
|
|
218
|
-
export type FunctionParamNode = FunctionParameterNode |
|
|
174
|
+
export type FunctionParamNode = FunctionParameterNode | FunctionParametersNode | TypeLiteralNode | IndexedAccessTypeNode | ObjectBindingPatternNode
|
|
219
175
|
|
|
220
176
|
/**
|
|
221
177
|
* Handler map keys, one per `FunctionParamNode` kind.
|
|
222
178
|
*/
|
|
223
|
-
export type FunctionNodeType = 'functionParameter' | '
|
|
179
|
+
export type FunctionNodeType = 'functionParameter' | 'functionParameters' | 'typeLiteral' | 'indexedAccessType' | 'objectBindingPattern'
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Definition for the {@link TypeLiteralNode}.
|
|
183
|
+
*/
|
|
184
|
+
export const typeLiteralDef = defineNode<TypeLiteralNode, Pick<TypeLiteralNode, 'members'>>({ kind: 'TypeLiteral' })
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Creates a {@link TypeLiteralNode} representing an inline anonymous object type.
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```ts
|
|
191
|
+
* createTypeLiteral({ members: [{ name: 'petId', type: 'string', optional: false }] })
|
|
192
|
+
* // { petId: string }
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
export const createTypeLiteral = typeLiteralDef.create
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Definition for the {@link IndexedAccessTypeNode}.
|
|
199
|
+
*/
|
|
200
|
+
export const indexedAccessTypeDef = defineNode<IndexedAccessTypeNode, Omit<IndexedAccessTypeNode, 'kind'>>({ kind: 'IndexedAccessType' })
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Creates an {@link IndexedAccessTypeNode} representing a single field accessed from a named type.
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* ```ts
|
|
207
|
+
* createIndexedAccessType({ objectType: 'DeletePetPathParams', indexType: 'petId' })
|
|
208
|
+
* // DeletePetPathParams['petId']
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
export const createIndexedAccessType = indexedAccessTypeDef.create
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Definition for the {@link ObjectBindingPatternNode}.
|
|
215
|
+
*/
|
|
216
|
+
export const objectBindingPatternDef = defineNode<ObjectBindingPatternNode, Pick<ObjectBindingPatternNode, 'elements'>>({ kind: 'ObjectBindingPattern' })
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Creates an {@link ObjectBindingPatternNode} for a destructured parameter binding.
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```ts
|
|
223
|
+
* createObjectBindingPattern({ elements: [{ name: 'id' }, { name: 'name' }] })
|
|
224
|
+
* // { id, name }
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
export const createObjectBindingPattern = objectBindingPatternDef.create
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Plain property descriptor for a destructured group built by {@link createFunctionParameter}.
|
|
231
|
+
*/
|
|
232
|
+
type FunctionParameterProperty = {
|
|
233
|
+
name: string
|
|
234
|
+
type: TypeExpression
|
|
235
|
+
optional?: boolean
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
type FunctionParameterInput =
|
|
239
|
+
| { name: string; type?: TypeExpression; optional?: boolean; default?: string; rest?: boolean }
|
|
240
|
+
| { properties: Array<FunctionParameterProperty>; optional?: boolean; default?: string }
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Definition for the {@link FunctionParameterNode}. `optional` defaults to `false`.
|
|
244
|
+
* Passing `properties` builds a destructured group: an {@link ObjectBindingPatternNode} name
|
|
245
|
+
* paired with a {@link TypeLiteralNode} type.
|
|
246
|
+
*/
|
|
247
|
+
export const functionParameterDef = defineNode<FunctionParameterNode, FunctionParameterInput>({
|
|
248
|
+
kind: 'FunctionParameter',
|
|
249
|
+
build: (input) => {
|
|
250
|
+
if ('properties' in input) {
|
|
251
|
+
return {
|
|
252
|
+
name: createObjectBindingPattern({ elements: input.properties.map((p) => ({ name: p.name })) }),
|
|
253
|
+
type: createTypeLiteral({ members: input.properties.map((p) => ({ name: p.name, type: p.type, optional: p.optional ?? false })) }),
|
|
254
|
+
optional: input.optional ?? false,
|
|
255
|
+
...(input.default !== undefined ? { default: input.default } : {}),
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return { optional: false, ...input }
|
|
259
|
+
},
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Creates a `FunctionParameterNode`. `optional` defaults to `false`.
|
|
264
|
+
*
|
|
265
|
+
* @example Optional param
|
|
266
|
+
* ```ts
|
|
267
|
+
* createFunctionParameter({ name: 'params', type: 'QueryParams', optional: true })
|
|
268
|
+
* // → params?: QueryParams
|
|
269
|
+
* ```
|
|
270
|
+
*
|
|
271
|
+
* @example Destructured group
|
|
272
|
+
* ```ts
|
|
273
|
+
* createFunctionParameter({ properties: [{ name: 'id', type: 'string' }, { name: 'name', type: 'string', optional: true }], default: '{}' })
|
|
274
|
+
* // → { id, name }: { id: string; name?: string } = {}
|
|
275
|
+
* ```
|
|
276
|
+
*/
|
|
277
|
+
export const createFunctionParameter = functionParameterDef.create
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Definition for the {@link FunctionParametersNode}.
|
|
281
|
+
*/
|
|
282
|
+
export const functionParametersDef = defineNode<FunctionParametersNode, Partial<Omit<FunctionParametersNode, 'kind'>>>({
|
|
283
|
+
kind: 'FunctionParameters',
|
|
284
|
+
defaults: { params: [] },
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Creates a `FunctionParametersNode` from an ordered list of parameters.
|
|
289
|
+
*
|
|
290
|
+
* @example
|
|
291
|
+
* ```ts
|
|
292
|
+
* const empty = createFunctionParameters()
|
|
293
|
+
* // { kind: 'FunctionParameters', params: [] }
|
|
294
|
+
* ```
|
|
295
|
+
*/
|
|
296
|
+
export function createFunctionParameters(props: Partial<Omit<FunctionParametersNode, 'kind'>> = {}): FunctionParametersNode {
|
|
297
|
+
return functionParametersDef.create(props)
|
|
298
|
+
}
|
package/src/nodes/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ArrowFunctionNode, ConstNode, FunctionNode, TypeNode } from './code.ts'
|
|
2
2
|
import type { ContentNode } from './content.ts'
|
|
3
3
|
import type { ExportNode, FileNode, ImportNode, SourceNode } from './file.ts'
|
|
4
|
-
import type { FunctionParamNode
|
|
4
|
+
import type { FunctionParamNode } from './function.ts'
|
|
5
5
|
import type { InputNode } from './input.ts'
|
|
6
6
|
import type { OperationNode } from './operation.ts'
|
|
7
7
|
import type { OutputNode } from './output.ts'
|
|
@@ -15,7 +15,16 @@ export type { NodeKind } from './base.ts'
|
|
|
15
15
|
export type { ArrowFunctionNode, BreakNode, CodeNode, ConstNode, FunctionNode, JSDocNode, JsxNode, TextNode, TypeNode } from './code.ts'
|
|
16
16
|
export type { ContentNode } from './content.ts'
|
|
17
17
|
export type { ExportNode, FileNode, ImportNode, SourceNode } from './file.ts'
|
|
18
|
-
export type {
|
|
18
|
+
export type {
|
|
19
|
+
FunctionNodeType,
|
|
20
|
+
FunctionParameterNode,
|
|
21
|
+
FunctionParametersNode,
|
|
22
|
+
FunctionParamNode,
|
|
23
|
+
IndexedAccessTypeNode,
|
|
24
|
+
ObjectBindingPatternNode,
|
|
25
|
+
TypeExpression,
|
|
26
|
+
TypeLiteralNode,
|
|
27
|
+
} from './function.ts'
|
|
19
28
|
export type { StatusCode } from './http.ts'
|
|
20
29
|
export type { InputMeta, InputNode } from './input.ts'
|
|
21
30
|
export type { GenericOperationNode, HttpMethod, HttpOperationNode, OperationNode } from './operation.ts'
|
|
@@ -81,6 +90,5 @@ export type Node =
|
|
|
81
90
|
| SourceNode
|
|
82
91
|
| ConstNode
|
|
83
92
|
| TypeNode
|
|
84
|
-
| ParamsTypeNode
|
|
85
93
|
| FunctionNode
|
|
86
94
|
| ArrowFunctionNode
|
package/src/nodes/input.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Streamable } from '@internals/utils'
|
|
2
|
+
import { defineNode } from '../node.ts'
|
|
2
3
|
import type { BaseNode } from './base.ts'
|
|
3
4
|
import type { OperationNode } from './operation.ts'
|
|
4
5
|
import type { SchemaNode } from './schema.ts'
|
|
@@ -101,3 +102,38 @@ export type InputNode<Stream extends boolean = false> = BaseNode & {
|
|
|
101
102
|
*/
|
|
102
103
|
operations: Streamable<OperationNode, Stream>
|
|
103
104
|
} & (Stream extends true ? { meta?: InputMeta } : { meta: InputMeta })
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Definition for the {@link InputNode}.
|
|
108
|
+
*/
|
|
109
|
+
export const inputDef = defineNode<InputNode, Partial<Omit<InputNode, 'kind'>>>({
|
|
110
|
+
kind: 'Input',
|
|
111
|
+
defaults: { schemas: [], operations: [], meta: { circularNames: [], enumNames: [] } },
|
|
112
|
+
children: ['schemas', 'operations'],
|
|
113
|
+
visitorKey: 'input',
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Creates an `InputNode` with stable defaults for `schemas` and `operations`.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* const input = createInput()
|
|
122
|
+
* // { kind: 'Input', schemas: [], operations: [] }
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
export function createInput(overrides: Partial<Omit<InputNode, 'kind'>> = {}): InputNode {
|
|
126
|
+
return inputDef.create(overrides)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Creates a streaming `InputNode<true>` from pre-built `AsyncIterable` sources.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* const node = createStreamInput(schemasIterable, operationsIterable, { title: 'My API' })
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
export function createStreamInput(schemas: AsyncIterable<SchemaNode>, operations: AsyncIterable<OperationNode>, meta?: InputMeta): InputNode<true> {
|
|
138
|
+
return { kind: 'Input', schemas, operations, meta }
|
|
139
|
+
}
|
package/src/nodes/operation.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { defineNode } from '../node.ts'
|
|
1
2
|
import type { BaseNode } from './base.ts'
|
|
2
3
|
import type { ParameterNode } from './parameter.ts'
|
|
3
|
-
import type
|
|
4
|
+
import { createRequestBody, type RequestBodyNode, type UserRequestBody } from './requestBody.ts'
|
|
4
5
|
import type { ResponseNode } from './response.ts'
|
|
5
6
|
|
|
6
7
|
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'TRACE'
|
|
@@ -105,3 +106,60 @@ export type GenericOperationNode = OperationNodeBase & {
|
|
|
105
106
|
* `isHttpOperationNode(node)` or `node.protocol === 'http'` before reading `method`/`path`.
|
|
106
107
|
*/
|
|
107
108
|
export type OperationNode = HttpOperationNode | GenericOperationNode
|
|
109
|
+
|
|
110
|
+
type OperationInput = {
|
|
111
|
+
operationId: string
|
|
112
|
+
method?: HttpOperationNode['method']
|
|
113
|
+
path?: HttpOperationNode['path']
|
|
114
|
+
requestBody?: UserRequestBody
|
|
115
|
+
[key: string]: unknown
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Definition for the {@link OperationNode}. HTTP operations (those carrying both
|
|
120
|
+
* `method` and `path`) are tagged with `protocol: 'http'`, and the request body is
|
|
121
|
+
* normalized into a `RequestBodyNode`.
|
|
122
|
+
*/
|
|
123
|
+
export const operationDef = defineNode<OperationNode, OperationInput>({
|
|
124
|
+
kind: 'Operation',
|
|
125
|
+
build: (props) => {
|
|
126
|
+
const { requestBody, ...rest } = props
|
|
127
|
+
const isHttp = rest.method !== undefined && rest.path !== undefined
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
tags: [],
|
|
131
|
+
parameters: [],
|
|
132
|
+
responses: [],
|
|
133
|
+
...rest,
|
|
134
|
+
...(isHttp ? { protocol: 'http' as const } : {}),
|
|
135
|
+
requestBody: requestBody ? createRequestBody(requestBody) : undefined,
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
children: ['parameters', 'requestBody', 'responses'],
|
|
139
|
+
visitorKey: 'operation',
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Creates an `OperationNode` with default empty arrays for `tags`, `parameters`, and `responses`.
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```ts
|
|
147
|
+
* const operation = createOperation({ operationId: 'getPetById', method: 'GET', path: '/pet/{petId}' })
|
|
148
|
+
* // tags, parameters, and responses are []
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
export function createOperation(
|
|
152
|
+
props: Pick<HttpOperationNode, 'operationId' | 'method' | 'path'> &
|
|
153
|
+
Partial<Omit<HttpOperationNode, 'kind' | 'operationId' | 'method' | 'path' | 'requestBody'>> & {
|
|
154
|
+
requestBody?: UserRequestBody
|
|
155
|
+
},
|
|
156
|
+
): HttpOperationNode
|
|
157
|
+
export function createOperation(
|
|
158
|
+
props: Pick<GenericOperationNode, 'operationId'> &
|
|
159
|
+
Partial<Omit<GenericOperationNode, 'kind' | 'operationId' | 'requestBody'>> & {
|
|
160
|
+
requestBody?: UserRequestBody
|
|
161
|
+
},
|
|
162
|
+
): GenericOperationNode
|
|
163
|
+
export function createOperation(props: OperationInput): OperationNode {
|
|
164
|
+
return operationDef.create(props)
|
|
165
|
+
}
|
package/src/nodes/output.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { defineNode } from '../node.ts'
|
|
1
2
|
import type { BaseNode } from './base.ts'
|
|
2
3
|
import type { FileNode } from './file.ts'
|
|
3
4
|
|
|
@@ -24,3 +25,25 @@ export type OutputNode = BaseNode & {
|
|
|
24
25
|
*/
|
|
25
26
|
files: Array<FileNode>
|
|
26
27
|
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Definition for the {@link OutputNode}.
|
|
31
|
+
*/
|
|
32
|
+
export const outputDef = defineNode<OutputNode, Partial<Omit<OutputNode, 'kind'>>>({
|
|
33
|
+
kind: 'Output',
|
|
34
|
+
defaults: { files: [] },
|
|
35
|
+
visitorKey: 'output',
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Creates an `OutputNode` with a stable default for `files`.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* const output = createOutput()
|
|
44
|
+
* // { kind: 'Output', files: [] }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export function createOutput(overrides: Partial<Omit<OutputNode, 'kind'>> = {}): OutputNode {
|
|
48
|
+
return outputDef.create(overrides)
|
|
49
|
+
}
|
package/src/nodes/parameter.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { defineNode, syncOptionality } from '../node.ts'
|
|
1
2
|
import type { BaseNode } from './base.ts'
|
|
2
3
|
import type { SchemaNode } from './schema.ts'
|
|
3
4
|
|
|
@@ -39,3 +40,35 @@ export type ParameterNode = BaseNode & {
|
|
|
39
40
|
*/
|
|
40
41
|
required: boolean
|
|
41
42
|
}
|
|
43
|
+
|
|
44
|
+
type UserParameterNode = Pick<ParameterNode, 'name' | 'in' | 'schema'> & Partial<Omit<ParameterNode, 'kind' | 'name' | 'in' | 'schema'>>
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Definition for the {@link ParameterNode}. `required` defaults to `false` and the
|
|
48
|
+
* schema's `optional`/`nullish` flags are kept in sync with it.
|
|
49
|
+
*/
|
|
50
|
+
export const parameterDef = defineNode<ParameterNode, UserParameterNode>({
|
|
51
|
+
kind: 'Parameter',
|
|
52
|
+
build: (props) => {
|
|
53
|
+
const required = props.required ?? false
|
|
54
|
+
return { ...props, required, schema: syncOptionality(props.schema, required) }
|
|
55
|
+
},
|
|
56
|
+
children: ['schema'],
|
|
57
|
+
visitorKey: 'parameter',
|
|
58
|
+
rebuild: true,
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Creates a `ParameterNode`.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* const param = createParameter({
|
|
67
|
+
* name: 'petId',
|
|
68
|
+
* in: 'path',
|
|
69
|
+
* required: true,
|
|
70
|
+
* schema: createSchema({ type: 'string' }),
|
|
71
|
+
* })
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export const createParameter = parameterDef.create
|