@kubb/ast 5.0.0-beta.55 → 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/utils/ast.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { camelCase, isValidVarName, memoize } from '@internals/utils'
|
|
2
2
|
|
|
3
|
-
import { createFunctionParameter, createFunctionParameters, createParameterGroup, createParamsType, createProperty, createSchema } from '../factory.ts'
|
|
4
3
|
import { narrowSchema } from '../guards.ts'
|
|
4
|
+
import { createFunctionParameter, createFunctionParameters, createIndexedAccessType, createTypeLiteral } from '../nodes/function.ts'
|
|
5
|
+
import { createProperty } from '../nodes/property.ts'
|
|
6
|
+
import { createSchema } from '../nodes/schema.ts'
|
|
5
7
|
import type {
|
|
6
8
|
CodeNode,
|
|
7
9
|
ExportNode,
|
|
@@ -9,11 +11,11 @@ import type {
|
|
|
9
11
|
FunctionParametersNode,
|
|
10
12
|
ImportNode,
|
|
11
13
|
OperationNode,
|
|
12
|
-
ParameterGroupNode,
|
|
13
14
|
ParameterNode,
|
|
14
|
-
ParamsTypeNode,
|
|
15
15
|
SchemaNode,
|
|
16
16
|
SourceNode,
|
|
17
|
+
TypeExpression,
|
|
18
|
+
TypeLiteralNode,
|
|
17
19
|
} from '../nodes/index.ts'
|
|
18
20
|
import type { SchemaType } from '../nodes/schema.ts'
|
|
19
21
|
import { extractRefName } from './index.ts'
|
|
@@ -120,15 +122,24 @@ export function createDiscriminantNode({ propertyName, value }: { propertyName:
|
|
|
120
122
|
*/
|
|
121
123
|
type ParamGroupType = {
|
|
122
124
|
/**
|
|
123
|
-
*
|
|
125
|
+
* Type expression for the group, a plain group-name reference.
|
|
124
126
|
*/
|
|
125
|
-
type:
|
|
127
|
+
type: TypeExpression
|
|
126
128
|
/**
|
|
127
129
|
* Whether the parameter group is optional.
|
|
128
130
|
*/
|
|
129
131
|
optional: boolean
|
|
130
132
|
}
|
|
131
133
|
|
|
134
|
+
/**
|
|
135
|
+
* A single member of a destructured parameter group, fed to `createFunctionParameter({ properties })`.
|
|
136
|
+
*/
|
|
137
|
+
type GroupProperty = {
|
|
138
|
+
name: string
|
|
139
|
+
type: TypeExpression
|
|
140
|
+
optional?: boolean
|
|
141
|
+
}
|
|
142
|
+
|
|
132
143
|
/**
|
|
133
144
|
* Resolver interface for {@link createOperationParams}.
|
|
134
145
|
*
|
|
@@ -215,7 +226,7 @@ export type CreateOperationParamsOptions = {
|
|
|
215
226
|
* extraParams: [createFunctionParameter({ name: 'options', type: 'Partial<RequestOptions>', default: '{}' })]
|
|
216
227
|
* ```
|
|
217
228
|
*/
|
|
218
|
-
extraParams?: Array<FunctionParameterNode
|
|
229
|
+
extraParams?: Array<FunctionParameterNode>
|
|
219
230
|
/**
|
|
220
231
|
* Override the default parameter names used for body, query, header, and rest-path groups.
|
|
221
232
|
*
|
|
@@ -255,7 +266,14 @@ export type CreateOperationParamsOptions = {
|
|
|
255
266
|
typeWrapper?: (type: string) => string
|
|
256
267
|
}
|
|
257
268
|
|
|
258
|
-
|
|
269
|
+
/**
|
|
270
|
+
* Resolves the {@link TypeExpression} for an individual parameter.
|
|
271
|
+
*
|
|
272
|
+
* Without a resolver, falls back to the schema primitive (a plain type-name string).
|
|
273
|
+
* When the parameter belongs to a named group, emits an {@link IndexedAccessTypeNode}
|
|
274
|
+
* (`GroupParams['petId']`); otherwise the resolved individual name as a plain string.
|
|
275
|
+
*/
|
|
276
|
+
export function resolveParamType({
|
|
259
277
|
node,
|
|
260
278
|
param,
|
|
261
279
|
resolver,
|
|
@@ -263,12 +281,9 @@ function resolveParamsType({
|
|
|
263
281
|
node: OperationNode
|
|
264
282
|
param: ParameterNode
|
|
265
283
|
resolver: OperationParamsResolver | undefined
|
|
266
|
-
}):
|
|
284
|
+
}): TypeExpression {
|
|
267
285
|
if (!resolver) {
|
|
268
|
-
return
|
|
269
|
-
variant: 'reference',
|
|
270
|
-
name: param.schema.primitive ?? 'unknown',
|
|
271
|
-
})
|
|
286
|
+
return param.schema.primitive ?? 'unknown'
|
|
272
287
|
}
|
|
273
288
|
|
|
274
289
|
const individualName = resolver.resolveParamName(node, param)
|
|
@@ -284,23 +299,19 @@ function resolveParamsType({
|
|
|
284
299
|
const groupName = groupLocation ? groupResolvers[groupLocation].call(resolver, node, param) : undefined
|
|
285
300
|
|
|
286
301
|
if (groupName && groupName !== individualName) {
|
|
287
|
-
return
|
|
288
|
-
variant: 'member',
|
|
289
|
-
base: groupName,
|
|
290
|
-
key: param.name,
|
|
291
|
-
})
|
|
302
|
+
return createIndexedAccessType({ objectType: groupName, indexType: param.name })
|
|
292
303
|
}
|
|
293
304
|
|
|
294
|
-
return
|
|
305
|
+
return individualName
|
|
295
306
|
}
|
|
296
307
|
|
|
297
308
|
/**
|
|
298
309
|
* Converts an `OperationNode` into function parameters for code generation.
|
|
299
310
|
*
|
|
300
|
-
* Centralizes parameter grouping logic for all plugins.
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
* and `
|
|
311
|
+
* Centralizes parameter grouping logic for all plugins. `paramsType` chooses between one
|
|
312
|
+
* destructured object parameter (`object`) and separate top-level parameters (`inline`), while
|
|
313
|
+
* `pathParamsType` controls how path params render in inline mode. Provide a `resolver` for type
|
|
314
|
+
* name resolution and `extraParams` for plugin-specific trailing parameters such as an `options` object.
|
|
304
315
|
*/
|
|
305
316
|
export function createOperationParams(node: OperationNode, options: CreateOperationParamsOptions): FunctionParametersNode {
|
|
306
317
|
const { paramsType, pathParamsType, paramsCasing, resolver, pathParamsDefault, extraParams = [], paramNames, typeWrapper } = options
|
|
@@ -310,147 +321,58 @@ export function createOperationParams(node: OperationNode, options: CreateOperat
|
|
|
310
321
|
const headersName = paramNames?.headers ?? 'headers'
|
|
311
322
|
const pathName = paramNames?.path ?? 'pathParams'
|
|
312
323
|
|
|
313
|
-
const wrapType = (type: string):
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
})
|
|
318
|
-
// Only reference-variant TypeNodes are wrapped, they hold a plain type name string that needs casing applied.
|
|
319
|
-
// Member and struct TypeNodes are pre-resolved structured expressions and are passed through unchanged.
|
|
320
|
-
const wrapTypeNode = (type: ParamsTypeNode): ParamsTypeNode => (type.kind === 'ParamsType' && type.variant === 'reference' ? wrapType(type.name) : type)
|
|
324
|
+
const wrapType = (type: string): string => (typeWrapper ? typeWrapper(type) : type)
|
|
325
|
+
// Only plain type-name references are wrapped, they need casing applied.
|
|
326
|
+
// TypeLiteral and IndexedAccessType expressions are pre-resolved and pass through unchanged.
|
|
327
|
+
const wrapTypeExpression = (type: TypeExpression): TypeExpression => (typeof type === 'string' ? wrapType(type) : type)
|
|
321
328
|
|
|
322
329
|
const casedParams = caseParams(node.parameters, paramsCasing)
|
|
323
330
|
const pathParams = casedParams.filter((p) => p.in === 'path')
|
|
324
331
|
const queryParams = casedParams.filter((p) => p.in === 'query')
|
|
325
332
|
const headerParams = casedParams.filter((p) => p.in === 'header')
|
|
326
333
|
|
|
334
|
+
const toProperty = (param: ParameterNode): GroupProperty => ({
|
|
335
|
+
name: param.name,
|
|
336
|
+
type: wrapTypeExpression(resolveParamType({ node, param, resolver })),
|
|
337
|
+
optional: !param.required,
|
|
338
|
+
})
|
|
339
|
+
const emptyObjectDefault = (props: Array<GroupProperty>): string | undefined => (props.every((p) => p.optional) ? '{}' : undefined)
|
|
340
|
+
|
|
327
341
|
const bodyType = node.requestBody?.content?.[0]?.schema ? wrapType(resolver?.resolveDataName(node) ?? 'unknown') : undefined
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
const
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
})
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
params: headerParams,
|
|
342
|
-
groupMethod: resolver.resolveHeaderParamsName,
|
|
343
|
-
resolver,
|
|
344
|
-
})
|
|
345
|
-
: undefined
|
|
346
|
-
|
|
347
|
-
const params: Array<FunctionParameterNode | ParameterGroupNode> = []
|
|
342
|
+
const bodyProperty: Array<GroupProperty> = bodyType ? [{ name: dataName, type: bodyType, optional: !(node.requestBody?.required ?? false) }] : []
|
|
343
|
+
|
|
344
|
+
const trailingGroups: Array<BuildGroupArgs> = [
|
|
345
|
+
{ name: paramsName, node, params: queryParams, groupType: resolveGroupType({ node, params: queryParams, group: 'query', resolver }), resolver, wrapType },
|
|
346
|
+
{
|
|
347
|
+
name: headersName,
|
|
348
|
+
node,
|
|
349
|
+
params: headerParams,
|
|
350
|
+
groupType: resolveGroupType({ node, params: headerParams, group: 'header', resolver }),
|
|
351
|
+
resolver,
|
|
352
|
+
wrapType,
|
|
353
|
+
},
|
|
354
|
+
]
|
|
348
355
|
|
|
349
|
-
|
|
350
|
-
const children: Array<FunctionParameterNode> = [
|
|
351
|
-
...pathParams.map((p) => {
|
|
352
|
-
const type = resolveParamsType({ node, param: p, resolver })
|
|
353
|
-
return createFunctionParameter({
|
|
354
|
-
name: p.name,
|
|
355
|
-
type: wrapTypeNode(type),
|
|
356
|
-
optional: !p.required,
|
|
357
|
-
})
|
|
358
|
-
}),
|
|
359
|
-
...(bodyType
|
|
360
|
-
? [
|
|
361
|
-
createFunctionParameter({
|
|
362
|
-
name: dataName,
|
|
363
|
-
type: bodyType,
|
|
364
|
-
optional: !bodyRequired,
|
|
365
|
-
}),
|
|
366
|
-
]
|
|
367
|
-
: []),
|
|
368
|
-
...buildGroupParam({
|
|
369
|
-
name: paramsName,
|
|
370
|
-
node,
|
|
371
|
-
params: queryParams,
|
|
372
|
-
groupType: queryGroupType,
|
|
373
|
-
resolver,
|
|
374
|
-
wrapType,
|
|
375
|
-
}),
|
|
376
|
-
...buildGroupParam({
|
|
377
|
-
name: headersName,
|
|
378
|
-
node,
|
|
379
|
-
params: headerParams,
|
|
380
|
-
groupType: headerGroupType,
|
|
381
|
-
resolver,
|
|
382
|
-
wrapType,
|
|
383
|
-
}),
|
|
384
|
-
]
|
|
356
|
+
const params: Array<FunctionParameterNode> = []
|
|
385
357
|
|
|
358
|
+
if (paramsType === 'object') {
|
|
359
|
+
const children = [...pathParams.map(toProperty), ...bodyProperty, ...trailingGroups.flatMap(buildGroupProperty)]
|
|
386
360
|
if (children.length) {
|
|
387
|
-
params.push(
|
|
388
|
-
createParameterGroup({
|
|
389
|
-
properties: children,
|
|
390
|
-
default: children.every((c) => c.optional) ? '{}' : undefined,
|
|
391
|
-
}),
|
|
392
|
-
)
|
|
361
|
+
params.push(createFunctionParameter({ properties: children, default: emptyObjectDefault(children) }))
|
|
393
362
|
}
|
|
394
363
|
} else {
|
|
395
|
-
if (pathParams.length) {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
}),
|
|
404
|
-
)
|
|
405
|
-
} else {
|
|
406
|
-
const pathChildren = pathParams.map((p) => {
|
|
407
|
-
const type = resolveParamsType({ node, param: p, resolver })
|
|
408
|
-
return createFunctionParameter({
|
|
409
|
-
name: p.name,
|
|
410
|
-
type: wrapTypeNode(type),
|
|
411
|
-
optional: !p.required,
|
|
412
|
-
})
|
|
413
|
-
})
|
|
414
|
-
params.push(
|
|
415
|
-
createParameterGroup({
|
|
416
|
-
properties: pathChildren,
|
|
417
|
-
inline: pathParamsType === 'inline',
|
|
418
|
-
default: pathParamsDefault ?? (pathChildren.every((c) => c.optional) ? '{}' : undefined),
|
|
419
|
-
}),
|
|
420
|
-
)
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
if (bodyType) {
|
|
425
|
-
params.push(
|
|
426
|
-
createFunctionParameter({
|
|
427
|
-
name: dataName,
|
|
428
|
-
type: bodyType,
|
|
429
|
-
optional: !bodyRequired,
|
|
430
|
-
}),
|
|
431
|
-
)
|
|
364
|
+
if (pathParamsType === 'inlineSpread' && pathParams.length) {
|
|
365
|
+
const spreadType = resolver?.resolvePathParamsName(node, pathParams[0]!)
|
|
366
|
+
params.push(createFunctionParameter({ name: pathName, type: spreadType ? wrapType(spreadType) : undefined, rest: true }))
|
|
367
|
+
} else if (pathParamsType === 'inline') {
|
|
368
|
+
params.push(...pathParams.map((p) => createFunctionParameter(toProperty(p))))
|
|
369
|
+
} else if (pathParams.length) {
|
|
370
|
+
const pathChildren = pathParams.map(toProperty)
|
|
371
|
+
params.push(createFunctionParameter({ properties: pathChildren, default: pathParamsDefault ?? emptyObjectDefault(pathChildren) }))
|
|
432
372
|
}
|
|
433
373
|
|
|
434
|
-
params.push(
|
|
435
|
-
|
|
436
|
-
name: paramsName,
|
|
437
|
-
node,
|
|
438
|
-
params: queryParams,
|
|
439
|
-
groupType: queryGroupType,
|
|
440
|
-
resolver,
|
|
441
|
-
wrapType,
|
|
442
|
-
}),
|
|
443
|
-
)
|
|
444
|
-
params.push(
|
|
445
|
-
...buildGroupParam({
|
|
446
|
-
name: headersName,
|
|
447
|
-
node,
|
|
448
|
-
params: headerParams,
|
|
449
|
-
groupType: headerGroupType,
|
|
450
|
-
resolver,
|
|
451
|
-
wrapType,
|
|
452
|
-
}),
|
|
453
|
-
)
|
|
374
|
+
params.push(...bodyProperty.map((p) => createFunctionParameter(p)))
|
|
375
|
+
params.push(...trailingGroups.flatMap(buildGroupParam))
|
|
454
376
|
}
|
|
455
377
|
|
|
456
378
|
params.push(...extraParams)
|
|
@@ -459,80 +381,82 @@ export function createOperationParams(node: OperationNode, options: CreateOperat
|
|
|
459
381
|
}
|
|
460
382
|
|
|
461
383
|
/**
|
|
462
|
-
*
|
|
463
|
-
* Returns an empty array when there are no params to emit.
|
|
464
|
-
*
|
|
465
|
-
* If a pre-resolved `groupType` is provided it emits `name: GroupType`.
|
|
466
|
-
* Otherwise, it builds an inline struct from the individual params.
|
|
384
|
+
* Shared arguments for building a query or header parameter group.
|
|
467
385
|
*/
|
|
468
|
-
|
|
469
|
-
name,
|
|
470
|
-
node,
|
|
471
|
-
params,
|
|
472
|
-
groupType,
|
|
473
|
-
resolver,
|
|
474
|
-
wrapType,
|
|
475
|
-
}: {
|
|
386
|
+
type BuildGroupArgs = {
|
|
476
387
|
name: string
|
|
477
388
|
node: OperationNode
|
|
478
389
|
params: Array<ParameterNode>
|
|
479
|
-
groupType: ParamGroupType | null
|
|
390
|
+
groupType: ParamGroupType | null
|
|
480
391
|
resolver: OperationParamsResolver | undefined
|
|
481
|
-
wrapType: (type: string) =>
|
|
482
|
-
}
|
|
392
|
+
wrapType: (type: string) => string
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Builds the property descriptor for a query or header group.
|
|
397
|
+
* Returns an empty array when there are no params to emit.
|
|
398
|
+
*
|
|
399
|
+
* A pre-resolved `groupType` emits `name: GroupType`. Otherwise it builds an inline
|
|
400
|
+
* {@link TypeLiteralNode} from the individual params.
|
|
401
|
+
*/
|
|
402
|
+
function buildGroupProperty({ name, node, params, groupType, resolver, wrapType }: BuildGroupArgs): Array<GroupProperty> {
|
|
483
403
|
if (groupType) {
|
|
484
|
-
const type =
|
|
485
|
-
return [
|
|
404
|
+
const type = typeof groupType.type === 'string' ? wrapType(groupType.type) : groupType.type
|
|
405
|
+
return [{ name, type, optional: groupType.optional }]
|
|
486
406
|
}
|
|
487
407
|
if (params.length) {
|
|
488
|
-
return [
|
|
489
|
-
createFunctionParameter({
|
|
490
|
-
name,
|
|
491
|
-
type: toStructType({ node, params, resolver }),
|
|
492
|
-
optional: params.every((p) => !p.required),
|
|
493
|
-
}),
|
|
494
|
-
]
|
|
408
|
+
return [{ name, type: buildTypeLiteral({ node, params, resolver }), optional: params.every((p) => !p.required) }]
|
|
495
409
|
}
|
|
496
410
|
return []
|
|
497
411
|
}
|
|
498
412
|
|
|
499
413
|
/**
|
|
500
|
-
*
|
|
501
|
-
* Returns
|
|
414
|
+
* Builds a single {@link FunctionParameterNode} for a query or header group.
|
|
415
|
+
* Returns an empty array when there are no params to emit.
|
|
416
|
+
*
|
|
417
|
+
* A pre-resolved `groupType` emits `name: GroupType`. Otherwise it builds an inline
|
|
418
|
+
* {@link TypeLiteralNode} from the individual params.
|
|
419
|
+
*/
|
|
420
|
+
export function buildGroupParam(args: BuildGroupArgs): Array<FunctionParameterNode> {
|
|
421
|
+
return buildGroupProperty(args).map((p) => createFunctionParameter(p))
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Derives a {@link ParamGroupType} for a query or header group from the resolver.
|
|
426
|
+
*
|
|
427
|
+
* Returns `null` when there is no resolver, no params, or the group name equals the
|
|
428
|
+
* individual param name (so there is no real group to emit).
|
|
502
429
|
*/
|
|
503
|
-
function resolveGroupType({
|
|
430
|
+
export function resolveGroupType({
|
|
504
431
|
node,
|
|
505
432
|
params,
|
|
506
|
-
|
|
433
|
+
group,
|
|
507
434
|
resolver,
|
|
508
435
|
}: {
|
|
509
436
|
node: OperationNode
|
|
510
437
|
params: Array<ParameterNode>
|
|
511
|
-
|
|
512
|
-
resolver: OperationParamsResolver
|
|
438
|
+
group: 'query' | 'header'
|
|
439
|
+
resolver: OperationParamsResolver | undefined
|
|
513
440
|
}): ParamGroupType | null {
|
|
514
|
-
if (!params.length) {
|
|
441
|
+
if (!resolver || !params.length) {
|
|
515
442
|
return null
|
|
516
443
|
}
|
|
517
444
|
const firstParam = params[0]!
|
|
445
|
+
const groupMethod = group === 'query' ? resolver.resolveQueryParamsName : resolver.resolveHeaderParamsName
|
|
518
446
|
const groupName = groupMethod.call(resolver, node, firstParam)
|
|
519
447
|
if (groupName === resolver.resolveParamName(node, firstParam)) {
|
|
520
448
|
return null
|
|
521
449
|
}
|
|
522
|
-
|
|
523
|
-
return {
|
|
524
|
-
type: createParamsType({ variant: 'reference', name: groupName }),
|
|
525
|
-
optional: allOptional,
|
|
526
|
-
}
|
|
450
|
+
return { type: groupName, optional: params.every((p) => !p.required) }
|
|
527
451
|
}
|
|
528
452
|
|
|
529
453
|
/**
|
|
530
|
-
* Builds a {@link
|
|
454
|
+
* Builds a {@link TypeLiteralNode} for an inline anonymous type grouping named fields.
|
|
531
455
|
*
|
|
532
456
|
* Used when query or header parameters have no dedicated group type name.
|
|
533
457
|
* Each language printer renders this appropriately (TypeScript: `{ petId: string; name?: string }`).
|
|
534
458
|
*/
|
|
535
|
-
function
|
|
459
|
+
export function buildTypeLiteral({
|
|
536
460
|
node,
|
|
537
461
|
params,
|
|
538
462
|
resolver,
|
|
@@ -540,13 +464,12 @@ function toStructType({
|
|
|
540
464
|
node: OperationNode
|
|
541
465
|
params: Array<ParameterNode>
|
|
542
466
|
resolver: OperationParamsResolver | undefined
|
|
543
|
-
}):
|
|
544
|
-
return
|
|
545
|
-
|
|
546
|
-
properties: params.map((p) => ({
|
|
467
|
+
}): TypeLiteralNode {
|
|
468
|
+
return createTypeLiteral({
|
|
469
|
+
members: params.map((p) => ({
|
|
547
470
|
name: p.name,
|
|
471
|
+
type: resolveParamType({ node, param: p, resolver }),
|
|
548
472
|
optional: !p.required,
|
|
549
|
-
type: resolveParamsType({ node, param: p, resolver }),
|
|
550
473
|
})),
|
|
551
474
|
})
|
|
552
475
|
}
|
package/src/visitor.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import type { VisitorDepth } from './constants.ts'
|
|
2
2
|
import { visitorDepths, WALK_CONCURRENCY } from './constants.ts'
|
|
3
|
-
import {
|
|
3
|
+
import { nodeRebuilders, VISITOR_KEY_BY_KIND, VISITOR_KEYS } from './registry.ts'
|
|
4
4
|
import type {
|
|
5
5
|
ContentNode,
|
|
6
6
|
InputNode,
|
|
7
7
|
Node,
|
|
8
|
-
NodeKind,
|
|
9
8
|
OperationNode,
|
|
10
9
|
OutputNode,
|
|
11
10
|
ParameterNode,
|
|
@@ -281,24 +280,6 @@ export type CollectOptions<T> = CollectVisitor<T> & {
|
|
|
281
280
|
parent?: Node
|
|
282
281
|
}
|
|
283
282
|
|
|
284
|
-
/**
|
|
285
|
-
* Child node fields per node kind, in traversal order (Babel's `VISITOR_KEYS`).
|
|
286
|
-
*
|
|
287
|
-
* Each listed property holds a child node, an array of child nodes, or, for
|
|
288
|
-
* `additionalProperties` a node or the literal `true` (skipped). Every value
|
|
289
|
-
* in a child slot is a node, so one table drives both `getChildren` and `transform`.
|
|
290
|
-
*/
|
|
291
|
-
const VISITOR_KEYS = {
|
|
292
|
-
Input: ['schemas', 'operations'],
|
|
293
|
-
Operation: ['parameters', 'requestBody', 'responses'],
|
|
294
|
-
RequestBody: ['content'],
|
|
295
|
-
Content: ['schema'],
|
|
296
|
-
Response: ['content'],
|
|
297
|
-
Schema: ['properties', 'items', 'members', 'additionalProperties'],
|
|
298
|
-
Property: ['schema'],
|
|
299
|
-
Parameter: ['schema'],
|
|
300
|
-
} as const satisfies Partial<Record<NodeKind, ReadonlyArray<string>>>
|
|
301
|
-
|
|
302
283
|
const visitorKeysByKind = VISITOR_KEYS as Record<string, ReadonlyArray<string> | undefined>
|
|
303
284
|
|
|
304
285
|
/**
|
|
@@ -336,21 +317,6 @@ function* getChildren(node: Node, recurse: boolean): Generator<Node, void, undef
|
|
|
336
317
|
}
|
|
337
318
|
}
|
|
338
319
|
|
|
339
|
-
/**
|
|
340
|
-
* Maps a node `kind` to the matching visitor callback name. Only the seven
|
|
341
|
-
* traversable node kinds have an entry. Every other kind resolves to
|
|
342
|
-
* `undefined` and is skipped.
|
|
343
|
-
*/
|
|
344
|
-
const VISITOR_KEY_BY_KIND: Partial<Record<NodeKind, keyof Visitor>> = {
|
|
345
|
-
Input: 'input',
|
|
346
|
-
Output: 'output',
|
|
347
|
-
Operation: 'operation',
|
|
348
|
-
Schema: 'schema',
|
|
349
|
-
Property: 'property',
|
|
350
|
-
Parameter: 'parameter',
|
|
351
|
-
Response: 'response',
|
|
352
|
-
}
|
|
353
|
-
|
|
354
320
|
/**
|
|
355
321
|
* Invokes the visitor callback that matches `node.kind`, passing the traversal
|
|
356
322
|
* context. Returns the callback's result (a replacement node, a collected
|
|
@@ -455,18 +421,8 @@ export function transform(node: Node, options: TransformOptions): Node {
|
|
|
455
421
|
// changed" by identity and ancestors can avoid reallocating.
|
|
456
422
|
if (rebuilt === node) return node
|
|
457
423
|
|
|
458
|
-
const
|
|
459
|
-
return
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
/**
|
|
463
|
-
* Per-kind builders rerun after children are rebuilt. `Property`/`Parameter`
|
|
464
|
-
* resync schema optionality against their `required` flag once the schema may
|
|
465
|
-
* have changed.
|
|
466
|
-
*/
|
|
467
|
-
const nodeFinalizers: Partial<Record<NodeKind, (node: Node) => Node>> = {
|
|
468
|
-
Property: (node) => createProperty(node as PropertyNode),
|
|
469
|
-
Parameter: (node) => createParameter(node as ParameterNode),
|
|
424
|
+
const rebuild = nodeRebuilders[rebuilt.kind]
|
|
425
|
+
return rebuild ? rebuild(rebuilt) : rebuilt
|
|
470
426
|
}
|
|
471
427
|
|
|
472
428
|
/**
|