@kubb/adapter-oas 5.0.0-alpha.14 → 5.0.0-alpha.16
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 +164 -404
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +0 -17
- package/dist/index.js +158 -402
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/adapter.ts +3 -5
- package/src/constants.ts +0 -49
- package/src/discriminator.ts +25 -0
- package/src/infer.ts +85 -0
- package/src/naming.ts +25 -0
- package/src/oas/Oas.ts +2 -10
- package/src/oas/types.ts +10 -4
- package/src/parser.ts +123 -340
- package/src/refResolver.ts +65 -0
- package/src/types.ts +0 -11
- package/src/utils.ts +0 -168
package/src/parser.ts
CHANGED
|
@@ -1,127 +1,50 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { URLPath } from '@internals/utils'
|
|
2
|
+
import {
|
|
3
|
+
applyDiscriminatorEnum,
|
|
4
|
+
createOperation,
|
|
5
|
+
createParameter,
|
|
6
|
+
createProperty,
|
|
7
|
+
createResponse,
|
|
8
|
+
createRoot,
|
|
9
|
+
createSchema,
|
|
10
|
+
extractRefName,
|
|
11
|
+
mediaTypes,
|
|
12
|
+
mergeAdjacentAnonymousObjects,
|
|
13
|
+
narrowSchema,
|
|
14
|
+
schemaTypes,
|
|
15
|
+
simplifyUnionMembers,
|
|
16
|
+
} from '@kubb/ast'
|
|
3
17
|
import type {
|
|
4
|
-
|
|
5
|
-
DateSchemaNode,
|
|
6
|
-
DatetimeSchemaNode,
|
|
7
|
-
EnumSchemaNode,
|
|
18
|
+
DistributiveOmit,
|
|
8
19
|
HttpMethod,
|
|
9
|
-
IntersectionSchemaNode,
|
|
10
20
|
MediaType,
|
|
11
|
-
NumberSchemaNode,
|
|
12
|
-
ObjectSchemaNode,
|
|
13
21
|
OperationNode,
|
|
14
22
|
ParameterLocation,
|
|
15
23
|
ParameterNode,
|
|
16
24
|
PrimitiveSchemaType,
|
|
17
25
|
PropertyNode,
|
|
18
|
-
RefSchemaNode,
|
|
19
26
|
ResponseNode,
|
|
20
27
|
RootNode,
|
|
21
|
-
ScalarSchemaNode,
|
|
22
28
|
ScalarSchemaType,
|
|
23
29
|
SchemaNode,
|
|
24
30
|
SchemaType,
|
|
25
31
|
StatusCode,
|
|
26
|
-
StringSchemaNode,
|
|
27
|
-
TimeSchemaNode,
|
|
28
|
-
UnionSchemaNode,
|
|
29
32
|
} from '@kubb/ast/types'
|
|
30
|
-
import { DEFAULT_PARSER_OPTIONS, enumExtensionKeys, formatMap
|
|
33
|
+
import { DEFAULT_PARSER_OPTIONS, enumExtensionKeys, formatMap } from './constants.ts'
|
|
34
|
+
import { createDiscriminantNode, resolveDiscriminatorValue } from './discriminator.ts'
|
|
35
|
+
import type { InferSchemaNode } from './infer.ts'
|
|
36
|
+
import { applyEnumName, resolveChildName, resolveEnumPropName } from './naming.ts'
|
|
31
37
|
import type { Oas } from './oas/Oas.ts'
|
|
32
38
|
import type { contentType, Operation, ReferenceObject, SchemaObject } from './oas/types.ts'
|
|
33
39
|
import { flattenSchema, isDiscriminator, isNullable, isReference } from './oas/utils.ts'
|
|
40
|
+
import { resolveRefs as resolveRefsNode } from './refResolver.ts'
|
|
34
41
|
import type { ParserOptions } from './types.ts'
|
|
35
|
-
import { applyDiscriminatorEnum, extractRefName, mergeAdjacentAnonymousObjects, simplifyUnionMembers } from './utils.ts'
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Distributive `Omit` — correctly distributes over union types so that
|
|
39
|
-
* `Omit<A | B, 'kind'>` produces `Omit<A, 'kind'> | Omit<B, 'kind'>`
|
|
40
|
-
* rather than `Omit<A | B, 'kind'>`.
|
|
41
|
-
*/
|
|
42
|
-
type DistributiveOmit<TValue, TKey extends PropertyKey> = TValue extends unknown ? Omit<TValue, TKey> : never
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Maps each `dateType` option value to the AST node produced by `format: 'date-time'`.
|
|
46
|
-
*/
|
|
47
|
-
type DateTimeNodeByDateType = {
|
|
48
|
-
date: DateSchemaNode
|
|
49
|
-
string: DatetimeSchemaNode
|
|
50
|
-
stringOffset: DatetimeSchemaNode
|
|
51
|
-
stringLocal: DatetimeSchemaNode
|
|
52
|
-
false: StringSchemaNode
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Resolves the AST node produced by `format: 'date-time'` based on the `dateType` option.
|
|
57
|
-
*/
|
|
58
|
-
type ResolveDateTimeNode<TDateType extends ParserOptions['dateType']> = DateTimeNodeByDateType[TDateType extends keyof DateTimeNodeByDateType
|
|
59
|
-
? TDateType
|
|
60
|
-
: 'string']
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Single source of truth: ordered list of `[shape, SchemaNode]` pairs.
|
|
64
|
-
* `InferSchemaNode` walks this tuple in order and returns the node type of the first matching entry.
|
|
65
|
-
* Parameterized over `TDateType` so `format: 'date-time'` resolves to the correct node based on the option.
|
|
66
|
-
*/
|
|
67
|
-
type SchemaNodeMap<TDateType extends ParserOptions['dateType'] = 'string'> = [
|
|
68
|
-
[{ $ref: string }, RefSchemaNode],
|
|
69
|
-
// allOf with sibling `properties` always produces an intersection (shared props are appended as a member).
|
|
70
|
-
[{ allOf: ReadonlyArray<unknown>; properties: object }, IntersectionSchemaNode],
|
|
71
|
-
// allOf with 2+ members always produces an intersection.
|
|
72
|
-
[{ allOf: readonly [unknown, unknown, ...unknown[]] }, IntersectionSchemaNode],
|
|
73
|
-
// Single-member allOf without sibling `properties` flattens to the member type.
|
|
74
|
-
[{ allOf: ReadonlyArray<unknown> }, SchemaNode],
|
|
75
|
-
[{ oneOf: ReadonlyArray<unknown> }, UnionSchemaNode],
|
|
76
|
-
[{ anyOf: ReadonlyArray<unknown> }, UnionSchemaNode],
|
|
77
|
-
[{ const: null }, ScalarSchemaNode],
|
|
78
|
-
[{ const: string | number | boolean }, EnumSchemaNode],
|
|
79
|
-
// OAS 3.1 multi-type array: `{ type: ['string', 'integer'] }` → union node.
|
|
80
|
-
[{ type: ReadonlyArray<string> }, UnionSchemaNode],
|
|
81
|
-
// `{ type: 'array', enum }` is normalized at runtime: enum moves into items → array node.
|
|
82
|
-
[{ type: 'array'; enum: ReadonlyArray<unknown> }, ArraySchemaNode],
|
|
83
|
-
[{ enum: ReadonlyArray<unknown> }, EnumSchemaNode],
|
|
84
|
-
[{ type: 'object' }, ObjectSchemaNode],
|
|
85
|
-
[{ additionalProperties: boolean | {} }, ObjectSchemaNode],
|
|
86
|
-
[{ type: 'array' }, ArraySchemaNode],
|
|
87
|
-
[{ items: object }, ArraySchemaNode],
|
|
88
|
-
[{ prefixItems: ReadonlyArray<unknown> }, ArraySchemaNode],
|
|
89
|
-
// Format entries with explicit type — placed before generic type entries so format wins.
|
|
90
|
-
[{ type: string; format: 'date-time' }, ResolveDateTimeNode<TDateType>],
|
|
91
|
-
[{ type: string; format: 'date' }, DateSchemaNode],
|
|
92
|
-
[{ type: string; format: 'time' }, TimeSchemaNode],
|
|
93
|
-
[{ format: 'date-time' }, ResolveDateTimeNode<TDateType>],
|
|
94
|
-
[{ format: 'date' }, DateSchemaNode],
|
|
95
|
-
[{ format: 'time' }, TimeSchemaNode],
|
|
96
|
-
[{ type: 'string' }, StringSchemaNode],
|
|
97
|
-
[{ type: 'number' }, NumberSchemaNode],
|
|
98
|
-
[{ type: 'integer' }, NumberSchemaNode],
|
|
99
|
-
[{ type: 'bigint' }, NumberSchemaNode],
|
|
100
|
-
[{ type: string }, ScalarSchemaNode],
|
|
101
|
-
// Inferred scalar types from constraints when no explicit type is present.
|
|
102
|
-
[{ minLength: number }, StringSchemaNode],
|
|
103
|
-
[{ maxLength: number }, StringSchemaNode],
|
|
104
|
-
[{ pattern: string }, StringSchemaNode],
|
|
105
|
-
[{ minimum: number }, NumberSchemaNode],
|
|
106
|
-
[{ maximum: number }, NumberSchemaNode],
|
|
107
|
-
]
|
|
108
|
-
|
|
109
|
-
export type InferSchemaNode<
|
|
110
|
-
TSchema extends SchemaObject,
|
|
111
|
-
TDateType extends ParserOptions['dateType'] = 'string',
|
|
112
|
-
TEntries extends ReadonlyArray<[object, SchemaNode]> = SchemaNodeMap<TDateType>,
|
|
113
|
-
> = TEntries extends [infer TEntry extends [object, SchemaNode], ...infer TRest extends ReadonlyArray<[object, SchemaNode]>]
|
|
114
|
-
? TSchema extends TEntry[0]
|
|
115
|
-
? TEntry[1]
|
|
116
|
-
: InferSchemaNode<TSchema, TDateType, TRest>
|
|
117
|
-
: SchemaNode
|
|
118
42
|
|
|
119
43
|
/**
|
|
120
44
|
* Construction-time options for `createOasParser`.
|
|
121
45
|
*/
|
|
122
46
|
export type OasParserOptions = {
|
|
123
47
|
contentType?: contentType
|
|
124
|
-
collisionDetection?: boolean
|
|
125
48
|
}
|
|
126
49
|
|
|
127
50
|
/**
|
|
@@ -149,7 +72,7 @@ function getPrimitiveType(type: string | undefined): PrimitiveSchemaType {
|
|
|
149
72
|
* Returns `undefined` for content types not present in `KNOWN_MEDIA_TYPES`.
|
|
150
73
|
*/
|
|
151
74
|
function toMediaType(contentType: string): MediaType | undefined {
|
|
152
|
-
return
|
|
75
|
+
return Object.values(mediaTypes).includes(contentType as MediaType) ? (contentType as MediaType) : undefined
|
|
153
76
|
}
|
|
154
77
|
|
|
155
78
|
/**
|
|
@@ -165,8 +88,8 @@ type SchemaContext = {
|
|
|
165
88
|
* Normalized single type string (first element when OAS 3.1 multi-type array).
|
|
166
89
|
*/
|
|
167
90
|
type: string | undefined
|
|
168
|
-
|
|
169
|
-
|
|
91
|
+
rawOptions: Partial<ParserOptions> | undefined
|
|
92
|
+
options: ParserOptions
|
|
170
93
|
}
|
|
171
94
|
|
|
172
95
|
/**
|
|
@@ -221,27 +144,30 @@ export type OasParser = {
|
|
|
221
144
|
* const root = parser.parse({ emptySchemaType: 'unknown' })
|
|
222
145
|
* ```
|
|
223
146
|
*/
|
|
224
|
-
export function createOasParser(oas: Oas, { contentType
|
|
147
|
+
export function createOasParser(oas: Oas, { contentType }: OasParserOptions = {}): OasParser {
|
|
225
148
|
// Map from original component paths to resolved schema names (after collision resolution)
|
|
226
149
|
// e.g., { '#/components/schemas/Order': 'OrderSchema', '#/components/responses/Product': 'ProductResponse' }
|
|
227
|
-
const { schemas: schemaObjects, nameMapping } = oas.getSchemas({ contentType
|
|
228
|
-
|
|
229
|
-
// Legacy enum name deduplication: tracks used enum names and appends numeric suffixes
|
|
230
|
-
// (e.g. ParamsStatusEnum, ParamsStatusEnum2) when collisionDetection is disabled.
|
|
231
|
-
const usedEnumNames: Record<string, number> = {}
|
|
150
|
+
const { schemas: schemaObjects, nameMapping } = oas.getSchemas({ contentType })
|
|
232
151
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
152
|
+
const TYPE_OPTION_MAP: Record<'any' | 'unknown' | 'void', ScalarSchemaType> = {
|
|
153
|
+
any: schemaTypes.any,
|
|
154
|
+
unknown: schemaTypes.unknown,
|
|
155
|
+
void: schemaTypes.void,
|
|
156
|
+
}
|
|
236
157
|
|
|
237
158
|
/**
|
|
238
159
|
* Maps an `'any' | 'unknown' | 'void'` option string to the corresponding `SchemaType` constant.
|
|
239
160
|
* Used for both `unknownType` (unannotated schemas) and `emptySchemaType` (empty `{}` schemas).
|
|
240
161
|
*/
|
|
241
162
|
function resolveTypeOption(value: 'any' | 'unknown' | 'void'): ScalarSchemaType {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
163
|
+
return TYPE_OPTION_MAP[value]
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function normalizeArrayEnum(schema: SchemaObject): SchemaObject {
|
|
167
|
+
const isItemsObject = typeof schema.items === 'object' && !Array.isArray(schema.items)
|
|
168
|
+
const normalizedItems: SchemaObject = { ...(isItemsObject ? (schema.items as SchemaObject) : {}), enum: schema.enum }
|
|
169
|
+
const { enum: _enum, ...schemaWithoutEnum } = schema
|
|
170
|
+
return { ...schemaWithoutEnum, items: normalizedItems } as SchemaObject
|
|
245
171
|
}
|
|
246
172
|
|
|
247
173
|
/**
|
|
@@ -337,7 +263,7 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
337
263
|
* Circular references through discriminator parents are detected and skipped to prevent
|
|
338
264
|
* infinite recursion during code generation.
|
|
339
265
|
*/
|
|
340
|
-
function convertAllOf({ schema, name, nullable, defaultValue,
|
|
266
|
+
function convertAllOf({ schema, name, nullable, defaultValue, rawOptions }: SchemaContext): SchemaNode {
|
|
341
267
|
if (
|
|
342
268
|
schema.allOf!.length === 1 &&
|
|
343
269
|
!schema.properties &&
|
|
@@ -345,7 +271,7 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
345
271
|
schema.additionalProperties === undefined
|
|
346
272
|
) {
|
|
347
273
|
const [memberSchema] = schema.allOf as Array<SchemaObject | ReferenceObject>
|
|
348
|
-
const memberNode = convertSchema({ schema: memberSchema! as SchemaObject },
|
|
274
|
+
const memberNode = convertSchema({ schema: memberSchema! as SchemaObject }, rawOptions)
|
|
349
275
|
const { kind: _kind, ...memberNodeProps } = memberNode
|
|
350
276
|
const mergedNullable = nullable || memberNode.nullable || undefined
|
|
351
277
|
const mergedDefault = schema.default === null && mergedNullable ? undefined : (schema.default ?? memberNode.default)
|
|
@@ -380,7 +306,7 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
380
306
|
const inOneOf = parentUnion.some((oneOfItem) => isReference(oneOfItem) && oneOfItem.$ref === childRef)
|
|
381
307
|
const inMapping = Object.values(deref.discriminator.mapping ?? {}).some((v) => v === childRef)
|
|
382
308
|
if (inOneOf || inMapping) {
|
|
383
|
-
const discriminatorValue =
|
|
309
|
+
const discriminatorValue = resolveDiscriminatorValue(deref.discriminator.mapping, childRef)
|
|
384
310
|
if (discriminatorValue) {
|
|
385
311
|
filteredDiscriminantValues.push({ propertyName: deref.discriminator.propertyName, value: discriminatorValue })
|
|
386
312
|
}
|
|
@@ -388,7 +314,7 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
388
314
|
}
|
|
389
315
|
return true
|
|
390
316
|
})
|
|
391
|
-
.map((s) => convertSchema({ schema: s as SchemaObject },
|
|
317
|
+
.map((s) => convertSchema({ schema: s as SchemaObject }, rawOptions))
|
|
392
318
|
|
|
393
319
|
// Track where allOf-derived members end so each portion can be merged independently.
|
|
394
320
|
const syntheticStart = allOfMembers.length
|
|
@@ -409,7 +335,7 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
409
335
|
for (const key of missingRequired) {
|
|
410
336
|
for (const resolved of resolvedMembers) {
|
|
411
337
|
if (resolved.properties?.[key]) {
|
|
412
|
-
allOfMembers.push(convertSchema({ schema: { properties: { [key]: resolved.properties[key] }, required: [key] } as SchemaObject },
|
|
338
|
+
allOfMembers.push(convertSchema({ schema: { properties: { [key]: resolved.properties[key] }, required: [key] } as SchemaObject }, rawOptions))
|
|
413
339
|
break
|
|
414
340
|
}
|
|
415
341
|
}
|
|
@@ -419,29 +345,13 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
419
345
|
|
|
420
346
|
if (schema.properties) {
|
|
421
347
|
const { allOf: _allOf, ...schemaWithoutAllOf } = schema
|
|
422
|
-
allOfMembers.push(convertSchema({ schema: schemaWithoutAllOf },
|
|
348
|
+
allOfMembers.push(convertSchema({ schema: schemaWithoutAllOf }, rawOptions))
|
|
423
349
|
}
|
|
424
350
|
|
|
425
351
|
// Inject a synthetic single-property object for each discriminant value collected from
|
|
426
352
|
// filtered discriminator parents so that child schemas carry the narrowed literal type.
|
|
427
353
|
for (const { propertyName, value } of filteredDiscriminantValues) {
|
|
428
|
-
allOfMembers.push(
|
|
429
|
-
createSchema({
|
|
430
|
-
type: 'object',
|
|
431
|
-
primitive: 'object',
|
|
432
|
-
properties: [
|
|
433
|
-
createProperty({
|
|
434
|
-
name: propertyName,
|
|
435
|
-
schema: createSchema({
|
|
436
|
-
type: 'enum',
|
|
437
|
-
primitive: 'string',
|
|
438
|
-
enumValues: [value],
|
|
439
|
-
}),
|
|
440
|
-
required: true,
|
|
441
|
-
}),
|
|
442
|
-
],
|
|
443
|
-
}),
|
|
444
|
-
)
|
|
354
|
+
allOfMembers.push(createDiscriminantNode(propertyName, value))
|
|
445
355
|
}
|
|
446
356
|
|
|
447
357
|
// Merge consecutive anonymous object members within the synthetic portion — see `mergeAdjacentAnonymousObjects`.
|
|
@@ -460,81 +370,56 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
460
370
|
* individually intersected with the shared properties node to match the OAS pattern of
|
|
461
371
|
* adding common fields next to a discriminated union.
|
|
462
372
|
*/
|
|
463
|
-
function convertUnion({ schema, name, nullable, defaultValue,
|
|
373
|
+
function convertUnion({ schema, name, nullable, defaultValue, rawOptions }: SchemaContext): SchemaNode {
|
|
464
374
|
const unionMembers = [...(schema.oneOf ?? []), ...(schema.anyOf ?? [])]
|
|
465
375
|
const unionBase = {
|
|
466
376
|
...renderSchemaBase(schema, name, nullable, defaultValue),
|
|
467
377
|
discriminatorPropertyName: isDiscriminator(schema) ? schema.discriminator.propertyName : undefined,
|
|
468
378
|
}
|
|
379
|
+
const discriminator = isDiscriminator(schema) ? schema.discriminator : undefined
|
|
380
|
+
const sharedPropertiesNode = schema.properties
|
|
381
|
+
? (() => {
|
|
382
|
+
const { oneOf: _oneOf, anyOf: _anyOf, ...schemaWithoutUnion } = schema
|
|
383
|
+
// Strip discriminator so convertObject won't re-apply the full mapping enum.
|
|
384
|
+
const memberBaseSchema: SchemaObject = discriminator
|
|
385
|
+
? (Object.fromEntries(Object.entries(schemaWithoutUnion).filter(([key]) => key !== 'discriminator')) as SchemaObject)
|
|
386
|
+
: schemaWithoutUnion
|
|
387
|
+
// Convert shared properties once to avoid duplicate enum naming
|
|
388
|
+
// (e.g. StatusEnum appearing twice and getting a numeric suffix).
|
|
389
|
+
return convertSchema({ schema: memberBaseSchema, name }, rawOptions)
|
|
390
|
+
})()
|
|
391
|
+
: undefined
|
|
469
392
|
|
|
470
|
-
if (
|
|
471
|
-
const { oneOf: _oneOf, anyOf: _anyOf, ...schemaWithoutUnion } = schema
|
|
472
|
-
const discriminator = isDiscriminator(schema) ? schema.discriminator : undefined
|
|
473
|
-
|
|
474
|
-
// Strip discriminator so convertObject won't re-apply the full mapping enum.
|
|
475
|
-
const memberBaseSchema: SchemaObject = discriminator
|
|
476
|
-
? (Object.fromEntries(Object.entries(schemaWithoutUnion).filter(([key]) => key !== 'discriminator')) as SchemaObject)
|
|
477
|
-
: schemaWithoutUnion
|
|
478
|
-
|
|
479
|
-
// Convert shared properties once to avoid duplicate enum naming
|
|
480
|
-
// (e.g. StatusEnum appearing twice and getting a numeric suffix).
|
|
481
|
-
const sharedPropertiesNode = convertSchema({ schema: memberBaseSchema, name: isLegacyNaming ? undefined : name }, options)
|
|
482
|
-
|
|
393
|
+
if (sharedPropertiesNode || discriminator?.mapping) {
|
|
483
394
|
return createSchema({
|
|
484
395
|
type: 'union',
|
|
485
396
|
...unionBase,
|
|
486
397
|
members: unionMembers.map((s) => {
|
|
487
398
|
const ref = isReference(s) ? s.$ref : undefined
|
|
488
|
-
const discriminatorValue = discriminator?.mapping
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
399
|
+
const discriminatorValue = resolveDiscriminatorValue(discriminator?.mapping, ref)
|
|
400
|
+
const memberNode = convertSchema({ schema: s as SchemaObject }, rawOptions)
|
|
401
|
+
|
|
402
|
+
if (sharedPropertiesNode) {
|
|
403
|
+
const narrowedProperties =
|
|
404
|
+
discriminatorValue && discriminator
|
|
405
|
+
? applyDiscriminatorEnum({
|
|
406
|
+
node: sharedPropertiesNode,
|
|
407
|
+
propertyName: discriminator.propertyName,
|
|
408
|
+
values: [discriminatorValue],
|
|
409
|
+
})
|
|
410
|
+
: sharedPropertiesNode
|
|
411
|
+
|
|
412
|
+
return createSchema({
|
|
413
|
+
type: 'intersection',
|
|
414
|
+
members: [memberNode, narrowedProperties],
|
|
415
|
+
})
|
|
494
416
|
}
|
|
495
417
|
|
|
496
|
-
return
|
|
497
|
-
type: 'intersection',
|
|
498
|
-
members: [convertSchema({ schema: s as SchemaObject }, options), propertiesNode],
|
|
499
|
-
})
|
|
500
|
-
}),
|
|
501
|
-
})
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
// When a discriminator with mapping is present but there are no sibling properties,
|
|
505
|
-
// embed the narrowed discriminant value into each member to produce precise literal
|
|
506
|
-
// intersection types (e.g. `Cat & { type: 'cat' }`) instead of plain `Cat | Dog`.
|
|
507
|
-
const discriminator = isDiscriminator(schema) ? schema.discriminator : undefined
|
|
508
|
-
if (discriminator?.mapping) {
|
|
509
|
-
return createSchema({
|
|
510
|
-
type: 'union',
|
|
511
|
-
...unionBase,
|
|
512
|
-
members: unionMembers.map((s) => {
|
|
513
|
-
const ref = isReference(s) ? s.$ref : undefined
|
|
514
|
-
const discriminatorValue = ref ? Object.entries(discriminator.mapping!).find(([, v]) => v === ref)?.[0] : undefined
|
|
515
|
-
const memberNode = convertSchema({ schema: s as SchemaObject }, options)
|
|
516
|
-
|
|
517
|
-
if (!discriminatorValue) return memberNode
|
|
518
|
-
|
|
519
|
-
const discriminantNode = createSchema({
|
|
520
|
-
type: 'object',
|
|
521
|
-
primitive: 'object',
|
|
522
|
-
properties: [
|
|
523
|
-
createProperty({
|
|
524
|
-
name: discriminator.propertyName,
|
|
525
|
-
schema: createSchema({
|
|
526
|
-
type: 'enum',
|
|
527
|
-
primitive: 'string',
|
|
528
|
-
enumValues: [discriminatorValue],
|
|
529
|
-
}),
|
|
530
|
-
required: true,
|
|
531
|
-
}),
|
|
532
|
-
],
|
|
533
|
-
})
|
|
418
|
+
if (!discriminatorValue || !discriminator) return memberNode
|
|
534
419
|
|
|
535
420
|
return createSchema({
|
|
536
421
|
type: 'intersection',
|
|
537
|
-
members: [memberNode,
|
|
422
|
+
members: [memberNode, createDiscriminantNode(discriminator.propertyName, discriminatorValue)],
|
|
538
423
|
})
|
|
539
424
|
}),
|
|
540
425
|
})
|
|
@@ -543,7 +428,7 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
543
428
|
return createSchema({
|
|
544
429
|
type: 'union',
|
|
545
430
|
...unionBase,
|
|
546
|
-
members: simplifyUnionMembers(unionMembers.map((s) => convertSchema({ schema: s as SchemaObject },
|
|
431
|
+
members: simplifyUnionMembers(unionMembers.map((s) => convertSchema({ schema: s as SchemaObject }, rawOptions))),
|
|
547
432
|
})
|
|
548
433
|
}
|
|
549
434
|
|
|
@@ -582,13 +467,13 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
582
467
|
* Returns `undefined` when the format should fall through to string handling
|
|
583
468
|
* (i.e. `format: 'date-time'` with `dateType: false`).
|
|
584
469
|
*/
|
|
585
|
-
function convertFormat({ schema, name, nullable, defaultValue,
|
|
470
|
+
function convertFormat({ schema, name, nullable, defaultValue, options }: SchemaContext): SchemaNode | undefined {
|
|
586
471
|
const base = renderSchemaBase(schema, name, nullable, defaultValue)
|
|
587
472
|
|
|
588
473
|
// int64 is option-dependent so it can't live in the static formatMap.
|
|
589
474
|
if (schema.format === 'int64') {
|
|
590
475
|
return createSchema({
|
|
591
|
-
type:
|
|
476
|
+
type: options.integerType === 'bigint' ? 'bigint' : 'integer',
|
|
592
477
|
primitive: 'integer',
|
|
593
478
|
...base,
|
|
594
479
|
min: schema.minimum,
|
|
@@ -600,7 +485,7 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
600
485
|
|
|
601
486
|
// date-time / date / time are option-dependent and can't live in the static formatMap.
|
|
602
487
|
if (schema.format === 'date-time' || schema.format === 'date' || schema.format === 'time') {
|
|
603
|
-
const dateType = getDateType(
|
|
488
|
+
const dateType = getDateType(options, schema.format)
|
|
604
489
|
if (!dateType) return undefined // dateType: false → fall through to string
|
|
605
490
|
|
|
606
491
|
if (dateType.type === 'datetime') {
|
|
@@ -634,13 +519,10 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
634
519
|
* - Numeric and boolean enums require a const-map representation because most generators cannot
|
|
635
520
|
* use string-enum syntax for non-string values.
|
|
636
521
|
*/
|
|
637
|
-
function convertEnum({ schema, name, nullable, type,
|
|
522
|
+
function convertEnum({ schema, name, nullable, type, rawOptions }: SchemaContext): SchemaNode {
|
|
638
523
|
// Malformed schema: `{ type: 'array', enum: [...] }` — normalize by moving the enum into items.
|
|
639
524
|
if (type === 'array') {
|
|
640
|
-
|
|
641
|
-
const normalizedItems: SchemaObject = { ...(isItemsObject ? (schema.items as SchemaObject) : {}), enum: schema.enum }
|
|
642
|
-
const { enum: _enum, ...schemaWithoutEnum } = schema
|
|
643
|
-
return convertSchema({ schema: { ...schemaWithoutEnum, items: normalizedItems } as SchemaObject, name }, options)
|
|
525
|
+
return convertSchema({ schema: normalizeArrayEnum(schema), name }, rawOptions)
|
|
644
526
|
}
|
|
645
527
|
|
|
646
528
|
// `null` in enum values is the OAS 3.0 convention for a nullable enum.
|
|
@@ -666,53 +548,26 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
666
548
|
|
|
667
549
|
// x-enumNames / x-enum-varnames: named variants with explicit labels take priority.
|
|
668
550
|
const extensionKey = enumExtensionKeys.find((key) => key in schema)
|
|
669
|
-
if (extensionKey) {
|
|
670
|
-
const
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
: ('string' as const)
|
|
551
|
+
if (extensionKey || enumPrimitive === 'number' || enumPrimitive === 'integer' || enumPrimitive === 'boolean') {
|
|
552
|
+
const enumType = (enumPrimitive === 'number' || enumPrimitive === 'integer' ? 'number' : enumPrimitive === 'boolean' ? 'boolean' : 'string') as
|
|
553
|
+
| 'number'
|
|
554
|
+
| 'boolean'
|
|
555
|
+
| 'string'
|
|
556
|
+
const sourceValues = extensionKey
|
|
557
|
+
? [...new Set((schema as Record<string, unknown>)[extensionKey] as Array<string | number>)]
|
|
558
|
+
: [...new Set(filteredValues)]
|
|
678
559
|
|
|
679
560
|
return createSchema({
|
|
680
561
|
...enumBase,
|
|
681
562
|
enumType,
|
|
682
|
-
namedEnumValues:
|
|
563
|
+
namedEnumValues: sourceValues.map((label, index) => ({
|
|
683
564
|
name: String(label),
|
|
684
|
-
value: filteredValues[index] ?? label,
|
|
565
|
+
value: extensionKey ? (filteredValues[index] ?? label) : label,
|
|
685
566
|
format: enumType,
|
|
686
567
|
})),
|
|
687
568
|
})
|
|
688
569
|
}
|
|
689
570
|
|
|
690
|
-
// Number / integer enum — must use a const map since most generators can't use string-enum for numbers.
|
|
691
|
-
if (type === 'number' || type === 'integer') {
|
|
692
|
-
return createSchema({
|
|
693
|
-
...enumBase,
|
|
694
|
-
enumType: 'number' as const,
|
|
695
|
-
namedEnumValues: [...new Set(filteredValues)].map((value) => ({
|
|
696
|
-
name: String(value),
|
|
697
|
-
value: value as number,
|
|
698
|
-
format: 'number' as const,
|
|
699
|
-
})),
|
|
700
|
-
})
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
// Boolean enum — same const-map approach as numeric.
|
|
704
|
-
if (type === 'boolean') {
|
|
705
|
-
return createSchema({
|
|
706
|
-
...enumBase,
|
|
707
|
-
enumType: 'boolean' as const,
|
|
708
|
-
namedEnumValues: [...new Set(filteredValues)].map((value) => ({
|
|
709
|
-
name: String(value),
|
|
710
|
-
value: value as boolean,
|
|
711
|
-
format: 'boolean' as const,
|
|
712
|
-
})),
|
|
713
|
-
})
|
|
714
|
-
}
|
|
715
|
-
|
|
716
571
|
// Plain string enum (default path).
|
|
717
572
|
return createSchema({
|
|
718
573
|
...enumBase,
|
|
@@ -732,55 +587,8 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
732
587
|
* - not required + not nullable → `optional: true`
|
|
733
588
|
* - not required + nullable → `nullish: true`
|
|
734
589
|
*/
|
|
735
|
-
/**
|
|
736
|
-
* Builds the propagation name for a child property during recursive schema conversion.
|
|
737
|
-
*
|
|
738
|
-
* - **Legacy naming** (`isLegacyNaming`): only the immediate property key is used
|
|
739
|
-
* (e.g. `Params` for property `params`), keeping nested names short.
|
|
740
|
-
* - **Default naming**: the parent name is prepended so the full path is encoded
|
|
741
|
-
* (e.g. `OrderParams` when parent is `Order`).
|
|
742
|
-
*/
|
|
743
|
-
function resolveChildName(parentName: string | undefined, propName: string): string | undefined {
|
|
744
|
-
if (isLegacyNaming) {
|
|
745
|
-
return pascalCase(propName)
|
|
746
|
-
}
|
|
747
|
-
return parentName ? pascalCase([parentName, propName].join(' ')) : undefined
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
/**
|
|
751
|
-
* Derives the final name for an enum property schema node.
|
|
752
|
-
*
|
|
753
|
-
* The raw name always includes the enum suffix (e.g. `StatusEnum`).
|
|
754
|
-
* In legacy mode an additional deduplication step appends a numeric suffix
|
|
755
|
-
* when the same name has already been used (e.g. `ParamsStatusEnum2`).
|
|
756
|
-
*/
|
|
757
|
-
function resolveEnumPropName(parentName: string | undefined, propName: string, enumSuffix: string): string {
|
|
758
|
-
const raw = pascalCase([parentName, propName, enumSuffix].filter(Boolean).join(' '))
|
|
759
|
-
return isLegacyNaming ? getUniqueName(raw, usedEnumNames) : raw
|
|
760
|
-
}
|
|
761
590
|
|
|
762
|
-
|
|
763
|
-
* Given a freshly-converted property schema, returns the node with a correct
|
|
764
|
-
* `name` attached — or stripped — depending on whether the node is a named
|
|
765
|
-
* enum, a boolean const-enum (always inlined), or a regular schema.
|
|
766
|
-
*/
|
|
767
|
-
function applyEnumName(propNode: SchemaNode, parentName: string | undefined, propName: string, enumSuffix: string): SchemaNode {
|
|
768
|
-
const enumNode = narrowSchema(propNode, 'enum')
|
|
769
|
-
|
|
770
|
-
// Boolean-primitive enum nodes (e.g. `const: false`) are always inlined as
|
|
771
|
-
// literal types and must not receive a named identifier.
|
|
772
|
-
if (enumNode?.primitive === 'boolean') {
|
|
773
|
-
return { ...propNode, name: undefined }
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
if (enumNode) {
|
|
777
|
-
return { ...propNode, name: resolveEnumPropName(parentName, propName, enumSuffix) }
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
return propNode
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
function convertObject({ schema, name, nullable, defaultValue, options, mergedOptions }: SchemaContext): SchemaNode {
|
|
591
|
+
function convertObject({ schema, name, nullable, defaultValue, rawOptions, options }: SchemaContext): SchemaNode {
|
|
784
592
|
const properties: Array<PropertyNode> = schema.properties
|
|
785
593
|
? Object.entries(schema.properties).map(([propName, propSchema]) => {
|
|
786
594
|
const required = Array.isArray(schema.required) ? schema.required.includes(propName) : !!schema.required
|
|
@@ -788,12 +596,12 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
788
596
|
const propNullable = isNullable(resolvedPropSchema)
|
|
789
597
|
|
|
790
598
|
const childName = resolveChildName(name, propName)
|
|
791
|
-
const propNode = convertSchema({ schema: resolvedPropSchema, name: childName },
|
|
792
|
-
let schemaNode = applyEnumName(propNode, name, propName,
|
|
599
|
+
const propNode = convertSchema({ schema: resolvedPropSchema, name: childName }, rawOptions)
|
|
600
|
+
let schemaNode = applyEnumName(propNode, name, propName, options.enumSuffix)
|
|
793
601
|
|
|
794
602
|
const tupleNode = narrowSchema(schemaNode, 'tuple')
|
|
795
603
|
if (tupleNode?.items) {
|
|
796
|
-
const namedItems = tupleNode.items.map((item) => applyEnumName(item, name, propName,
|
|
604
|
+
const namedItems = tupleNode.items.map((item) => applyEnumName(item, name, propName, options.enumSuffix))
|
|
797
605
|
if (namedItems.some((item, i) => item !== tupleNode.items![i])) {
|
|
798
606
|
schemaNode = { ...tupleNode, items: namedItems }
|
|
799
607
|
}
|
|
@@ -815,11 +623,11 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
815
623
|
if (additionalProperties === true) {
|
|
816
624
|
additionalPropertiesNode = true
|
|
817
625
|
} else if (additionalProperties && Object.keys(additionalProperties).length > 0) {
|
|
818
|
-
additionalPropertiesNode = convertSchema({ schema: additionalProperties as SchemaObject },
|
|
626
|
+
additionalPropertiesNode = convertSchema({ schema: additionalProperties as SchemaObject }, rawOptions)
|
|
819
627
|
} else if (additionalProperties === false) {
|
|
820
628
|
additionalPropertiesNode = undefined
|
|
821
629
|
} else if (additionalProperties) {
|
|
822
|
-
additionalPropertiesNode = createSchema({ type: resolveTypeOption(
|
|
630
|
+
additionalPropertiesNode = createSchema({ type: resolveTypeOption(options.unknownType) })
|
|
823
631
|
}
|
|
824
632
|
|
|
825
633
|
const rawPatternProperties = 'patternProperties' in schema ? schema.patternProperties : undefined
|
|
@@ -829,8 +637,8 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
829
637
|
Object.entries(rawPatternProperties).map(([pattern, patternSchema]) => [
|
|
830
638
|
pattern,
|
|
831
639
|
patternSchema === true || (typeof patternSchema === 'object' && Object.keys(patternSchema).length === 0)
|
|
832
|
-
? createSchema({ type: resolveTypeOption(
|
|
833
|
-
: convertSchema({ schema: patternSchema as SchemaObject },
|
|
640
|
+
? createSchema({ type: resolveTypeOption(options.unknownType) })
|
|
641
|
+
: convertSchema({ schema: patternSchema as SchemaObject }, rawOptions),
|
|
834
642
|
]),
|
|
835
643
|
)
|
|
836
644
|
: undefined
|
|
@@ -849,7 +657,7 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
849
657
|
if (isDiscriminator(schema) && schema.discriminator.mapping) {
|
|
850
658
|
const discPropName = schema.discriminator.propertyName
|
|
851
659
|
const values = Object.keys(schema.discriminator.mapping)
|
|
852
|
-
const enumName = name ? resolveEnumPropName(name, discPropName,
|
|
660
|
+
const enumName = name ? resolveEnumPropName(name, discPropName, options.enumSuffix) : undefined
|
|
853
661
|
return applyDiscriminatorEnum({ node: objectNode, propertyName: discPropName, values, enumName })
|
|
854
662
|
}
|
|
855
663
|
|
|
@@ -864,9 +672,9 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
864
672
|
* a rest element of type `any` is emitted to match JSON Schema semantics (absent `items`
|
|
865
673
|
* means additional items are allowed).
|
|
866
674
|
*/
|
|
867
|
-
function convertTuple({ schema, name, nullable, defaultValue,
|
|
868
|
-
const tupleItems = (schema.prefixItems ?? []).map((item) => convertSchema({ schema: item as SchemaObject },
|
|
869
|
-
const rest = schema.items ? convertSchema({ schema: schema.items as SchemaObject },
|
|
675
|
+
function convertTuple({ schema, name, nullable, defaultValue, rawOptions }: SchemaContext): SchemaNode {
|
|
676
|
+
const tupleItems = (schema.prefixItems ?? []).map((item) => convertSchema({ schema: item as SchemaObject }, rawOptions))
|
|
677
|
+
const rest = schema.items ? convertSchema({ schema: schema.items as SchemaObject }, rawOptions) : createSchema({ type: 'any' })
|
|
870
678
|
|
|
871
679
|
return createSchema({
|
|
872
680
|
type: 'tuple',
|
|
@@ -885,12 +693,12 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
885
693
|
* When the items schema is an inline enum, a name derived from the parent array's name and
|
|
886
694
|
* `enumSuffix` is forwarded so generators can emit a named enum declaration.
|
|
887
695
|
*/
|
|
888
|
-
function convertArray({ schema, name, nullable, defaultValue,
|
|
696
|
+
function convertArray({ schema, name, nullable, defaultValue, rawOptions, options }: SchemaContext): SchemaNode {
|
|
889
697
|
const rawItems = schema.items as SchemaObject | undefined
|
|
890
698
|
// When the items schema contains an inline enum, derive a named identifier
|
|
891
699
|
// so generators can emit a standalone enum declaration.
|
|
892
|
-
const itemName = rawItems?.enum?.length && name ? resolveEnumPropName(undefined, name,
|
|
893
|
-
const items = rawItems ? [convertSchema({ schema: rawItems, name: itemName },
|
|
700
|
+
const itemName = rawItems?.enum?.length && name ? resolveEnumPropName(undefined, name, options.enumSuffix) : undefined
|
|
701
|
+
const items = rawItems ? [convertSchema({ schema: rawItems, name: itemName }, rawOptions)] : []
|
|
894
702
|
|
|
895
703
|
return createSchema({
|
|
896
704
|
type: 'array',
|
|
@@ -974,13 +782,13 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
974
782
|
* 10. Object / array / tuple / scalar by `type`
|
|
975
783
|
* 11. Empty schema fallback (`emptySchemaType` option)
|
|
976
784
|
*/
|
|
977
|
-
function convertSchema({ schema, name }: { schema: SchemaObject; name?: string },
|
|
978
|
-
const
|
|
785
|
+
function convertSchema({ schema, name }: { schema: SchemaObject; name?: string }, rawOptions?: Partial<ParserOptions>): SchemaNode {
|
|
786
|
+
const options: ParserOptions = { ...DEFAULT_PARSER_OPTIONS, ...rawOptions }
|
|
979
787
|
// Flatten keyword-only allOf fragments (no $ref, no structural keys) into the parent
|
|
980
788
|
// schema before parsing, so simple annotation patterns don't produce needless intersections.
|
|
981
789
|
const flattenedSchema = flattenSchema(schema)
|
|
982
790
|
if (flattenedSchema && flattenedSchema !== schema) {
|
|
983
|
-
return convertSchema({ schema: flattenedSchema, name },
|
|
791
|
+
return convertSchema({ schema: flattenedSchema, name }, rawOptions)
|
|
984
792
|
}
|
|
985
793
|
|
|
986
794
|
const nullable = isNullable(schema) || undefined
|
|
@@ -988,7 +796,7 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
988
796
|
// Normalize OAS 3.1 multi-type array to a single type string for the dispatch below.
|
|
989
797
|
const type = Array.isArray(schema.type) ? schema.type[0] : schema.type
|
|
990
798
|
|
|
991
|
-
const ctx: SchemaContext = { schema, name, nullable, defaultValue, type,
|
|
799
|
+
const ctx: SchemaContext = { schema, name, nullable, defaultValue, type, rawOptions, options }
|
|
992
800
|
|
|
993
801
|
// $ref — pointer to another definition.
|
|
994
802
|
// In OAS 3.0 siblings of $ref are technically ignored, but Kubb intentionally preserves them
|
|
@@ -1027,7 +835,7 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
1027
835
|
if (nonNullTypes.length > 1) {
|
|
1028
836
|
return createSchema({
|
|
1029
837
|
type: 'union',
|
|
1030
|
-
members: nonNullTypes.map((t) => convertSchema({ schema: { ...schema, type: t } as SchemaObject, name },
|
|
838
|
+
members: nonNullTypes.map((t) => convertSchema({ schema: { ...schema, type: t } as SchemaObject, name }, rawOptions)),
|
|
1031
839
|
...renderSchemaBase(schema, name, arrayNullable, defaultValue),
|
|
1032
840
|
})
|
|
1033
841
|
}
|
|
@@ -1055,7 +863,7 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
1055
863
|
if (type === 'boolean') return convertBoolean(ctx)
|
|
1056
864
|
if (type === 'null') return convertNull(ctx)
|
|
1057
865
|
|
|
1058
|
-
const emptyType = resolveTypeOption(
|
|
866
|
+
const emptyType = resolveTypeOption(options.emptySchemaType)
|
|
1059
867
|
return createSchema({ type: emptyType as ScalarSchemaType, name, title: schema.title, description: schema.description })
|
|
1060
868
|
}
|
|
1061
869
|
|
|
@@ -1179,36 +987,11 @@ export function createOasParser(oas: Oas, { contentType, collisionDetection }: O
|
|
|
1179
987
|
return createRoot({ schemas, operations })
|
|
1180
988
|
}
|
|
1181
989
|
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
*
|
|
1188
|
-
* Collision-resolved names (from `nameMapping`) are applied before user-supplied resolvers.
|
|
1189
|
-
*/
|
|
1190
|
-
function resolveRefs(node: SchemaNode, resolveName: (ref: string) => string | undefined, resolveEnumName?: (name: string) => string | undefined): SchemaNode {
|
|
1191
|
-
return transform(node, {
|
|
1192
|
-
schema(schemaNode) {
|
|
1193
|
-
const schemaRef = narrowSchema(schemaNode, schemaTypes.ref)
|
|
1194
|
-
|
|
1195
|
-
if (schemaRef && (schemaRef.ref || schemaRef.name)) {
|
|
1196
|
-
const rawRef = schemaRef.ref ?? schemaRef.name!
|
|
1197
|
-
const resolved = resolveName(nameMapping.get(rawRef) ?? rawRef)
|
|
1198
|
-
if (resolved) {
|
|
1199
|
-
return { ...schemaNode, name: resolved }
|
|
1200
|
-
}
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
if (schemaNode.type === 'enum' && schemaNode.name) {
|
|
1204
|
-
const resolved = (resolveEnumName ?? resolveName)(schemaNode.name)
|
|
1205
|
-
if (resolved) {
|
|
1206
|
-
return { ...schemaNode, name: resolved }
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
},
|
|
1210
|
-
}) as SchemaNode
|
|
1211
|
-
}
|
|
990
|
+
const resolveRefs = (
|
|
991
|
+
node: SchemaNode,
|
|
992
|
+
resolveName: (ref: string) => string | undefined,
|
|
993
|
+
resolveEnumName?: (name: string) => string | undefined,
|
|
994
|
+
): SchemaNode => resolveRefsNode({ node, nameMapping, resolveName, resolveEnumName })
|
|
1212
995
|
|
|
1213
996
|
return {
|
|
1214
997
|
parse,
|