@kubb/adapter-oas 5.0.0-beta.17 → 5.0.0-beta.19
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 +85 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +85 -65
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/adapter.ts +24 -13
- package/src/discriminator.ts +4 -7
- package/src/parser.ts +26 -23
- package/src/refs.ts +2 -5
- package/src/resolvers.ts +7 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/adapter-oas",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.19",
|
|
4
4
|
"description": "OpenAPI and Swagger adapter for Kubb. Parses and validates OAS 2.0/3.x specifications into a @kubb/ast RootNode for downstream code generation plugins.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"adapter",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"oas": "^32.1.18",
|
|
48
48
|
"oas-normalize": "^16.0.4",
|
|
49
49
|
"swagger2openapi": "^7.0.8",
|
|
50
|
-
"@kubb/core": "5.0.0-beta.
|
|
50
|
+
"@kubb/core": "5.0.0-beta.19"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@types/swagger2openapi": "^7.0.4",
|
package/src/adapter.ts
CHANGED
|
@@ -58,6 +58,8 @@ export const adapterOas = createAdapter<AdapterOas>((options) => {
|
|
|
58
58
|
let nameMapping = new Map<string, string>()
|
|
59
59
|
let parsedDocument: Document | null = null
|
|
60
60
|
let schemaObjects: ReturnType<typeof getSchemas>['schemas'] | null = null
|
|
61
|
+
let baseOasInstance: BaseOas | null = null
|
|
62
|
+
let schemaParserInstance: ReturnType<typeof createSchemaParser> | null = null
|
|
61
63
|
|
|
62
64
|
function resolveBaseURL(document: Document): string | undefined {
|
|
63
65
|
const server = serverIndex !== undefined ? document.servers?.at(serverIndex) : undefined
|
|
@@ -81,6 +83,16 @@ export const adapterOas = createAdapter<AdapterOas>((options) => {
|
|
|
81
83
|
return schemaObjects
|
|
82
84
|
}
|
|
83
85
|
|
|
86
|
+
function ensureBaseOas(document: Document): BaseOas {
|
|
87
|
+
if (!baseOasInstance) baseOasInstance = new BaseOas(document)
|
|
88
|
+
return baseOasInstance
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function ensureSchemaParser(document: Document): ReturnType<typeof createSchemaParser> {
|
|
92
|
+
if (!schemaParserInstance) schemaParserInstance = createSchemaParser({ document, contentType })
|
|
93
|
+
return schemaParserInstance
|
|
94
|
+
}
|
|
95
|
+
|
|
84
96
|
return {
|
|
85
97
|
name: adapterOasName,
|
|
86
98
|
get options() {
|
|
@@ -148,7 +160,7 @@ export const adapterOas = createAdapter<AdapterOas>((options) => {
|
|
|
148
160
|
const document = await ensureDocument(source)
|
|
149
161
|
const schemas = await ensureSchemas(document)
|
|
150
162
|
|
|
151
|
-
const baseOas =
|
|
163
|
+
const baseOas = ensureBaseOas(document)
|
|
152
164
|
const operationCount = Object.values(baseOas.getPaths()).flatMap(Object.values).filter(Boolean).length
|
|
153
165
|
|
|
154
166
|
return { schemas: Object.keys(schemas).length, operations: operationCount }
|
|
@@ -157,30 +169,29 @@ export const adapterOas = createAdapter<AdapterOas>((options) => {
|
|
|
157
169
|
const document = await ensureDocument(source)
|
|
158
170
|
const schemas = await ensureSchemas(document)
|
|
159
171
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const { parseSchema: _preParser } =
|
|
172
|
+
const discriminatorChildMap: Awaited<ReturnType<typeof buildDiscriminatorChildMap>> | null = (() => {
|
|
173
|
+
if (discriminator !== 'inherit') return null
|
|
174
|
+
const { parseSchema: _preParser } = ensureSchemaParser(document)
|
|
163
175
|
const parentNodes: ast.SchemaNode[] = []
|
|
164
176
|
for (const [name, schema] of Object.entries(schemas)) {
|
|
165
177
|
if ((schema.oneOf ?? schema.anyOf) && schema.discriminator?.propertyName) {
|
|
166
178
|
parentNodes.push(_preParser({ schema, name }, parserOptions))
|
|
167
179
|
}
|
|
168
180
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
}
|
|
181
|
+
return parentNodes.length > 0 ? buildDiscriminatorChildMap(parentNodes) : null
|
|
182
|
+
})()
|
|
173
183
|
|
|
174
184
|
// Each [Symbol.asyncIterator]() call returns a fresh generator so multiple
|
|
175
185
|
// plugins can do independent `for await` passes without shared state.
|
|
186
|
+
// The underlying parser and BaseOas instance are cached at adapter scope.
|
|
176
187
|
const schemasIterable: AsyncIterable<ast.SchemaNode> = {
|
|
177
188
|
[Symbol.asyncIterator]() {
|
|
178
189
|
return (async function* () {
|
|
179
|
-
const { parseSchema: _parseSchema } =
|
|
190
|
+
const { parseSchema: _parseSchema } = ensureSchemaParser(document)
|
|
180
191
|
for (const [name, schema] of Object.entries(schemas)) {
|
|
181
|
-
|
|
192
|
+
const parsedNode = _parseSchema({ schema, name }, parserOptions)
|
|
182
193
|
const entry = discriminatorChildMap?.get(name)
|
|
183
|
-
|
|
194
|
+
const node = entry ? patchDiscriminatorNode(parsedNode, entry) : parsedNode
|
|
184
195
|
yield node
|
|
185
196
|
}
|
|
186
197
|
})()
|
|
@@ -190,8 +201,8 @@ export const adapterOas = createAdapter<AdapterOas>((options) => {
|
|
|
190
201
|
const operationsIterable: AsyncIterable<ast.OperationNode> = {
|
|
191
202
|
[Symbol.asyncIterator]() {
|
|
192
203
|
return (async function* () {
|
|
193
|
-
const { parseOperation: _parseOperation } =
|
|
194
|
-
const baseOas =
|
|
204
|
+
const { parseOperation: _parseOperation } = ensureSchemaParser(document)
|
|
205
|
+
const baseOas = ensureBaseOas(document)
|
|
195
206
|
const paths = baseOas.getPaths()
|
|
196
207
|
|
|
197
208
|
for (const methods of Object.values(paths)) {
|
package/src/discriminator.ts
CHANGED
|
@@ -61,14 +61,11 @@ export function buildDiscriminatorChildMap(schemas: ast.SchemaNode[]): Map<strin
|
|
|
61
61
|
if (!enumValues.length) continue
|
|
62
62
|
|
|
63
63
|
const existing = childMap.get(refNode.name)
|
|
64
|
-
if (existing) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
childMap.set(refNode.name, {
|
|
68
|
-
propertyName: discriminatorPropertyName,
|
|
69
|
-
enumValues: [...enumValues],
|
|
70
|
-
})
|
|
64
|
+
if (!existing) {
|
|
65
|
+
childMap.set(refNode.name, { propertyName: discriminatorPropertyName, enumValues: [...enumValues] })
|
|
66
|
+
continue
|
|
71
67
|
}
|
|
68
|
+
existing.enumValues.push(...enumValues)
|
|
72
69
|
}
|
|
73
70
|
}
|
|
74
71
|
|
package/src/parser.ts
CHANGED
|
@@ -115,9 +115,7 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
115
115
|
let resolvedSchema: ast.SchemaNode | undefined
|
|
116
116
|
const refPath = schema.$ref
|
|
117
117
|
if (refPath && !resolvingRefs.has(refPath)) {
|
|
118
|
-
if (resolvedRefCache.has(refPath)) {
|
|
119
|
-
resolvedSchema = resolvedRefCache.get(refPath)
|
|
120
|
-
} else {
|
|
118
|
+
if (!resolvedRefCache.has(refPath)) {
|
|
121
119
|
try {
|
|
122
120
|
const referenced = resolveRef<SchemaObject>(document, refPath)
|
|
123
121
|
if (referenced) {
|
|
@@ -130,6 +128,7 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
130
128
|
}
|
|
131
129
|
resolvedRefCache.set(refPath, resolvedSchema)
|
|
132
130
|
}
|
|
131
|
+
resolvedSchema = resolvedRefCache.get(refPath)
|
|
133
132
|
}
|
|
134
133
|
|
|
135
134
|
return ast.createSchema({
|
|
@@ -169,6 +168,7 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
169
168
|
default: mergedDefault,
|
|
170
169
|
example: schema.example ?? memberNode.example,
|
|
171
170
|
pattern: schema.pattern ?? ('pattern' in memberNode ? memberNode.pattern : undefined),
|
|
171
|
+
format: schema.format ?? memberNode.format,
|
|
172
172
|
} as ast.DistributiveOmit<ast.SchemaNode, 'kind'>)
|
|
173
173
|
}
|
|
174
174
|
|
|
@@ -359,6 +359,7 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
359
359
|
title: schema.title,
|
|
360
360
|
description: schema.description,
|
|
361
361
|
deprecated: schema.deprecated,
|
|
362
|
+
format: schema.format,
|
|
362
363
|
})
|
|
363
364
|
}
|
|
364
365
|
|
|
@@ -489,6 +490,7 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
489
490
|
writeOnly: schema.writeOnly,
|
|
490
491
|
default: enumDefault,
|
|
491
492
|
example: schema.example,
|
|
493
|
+
format: schema.format,
|
|
492
494
|
}
|
|
493
495
|
|
|
494
496
|
const extensionKey = enumExtensionKeys.find((key) => key in schema)
|
|
@@ -536,15 +538,17 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
536
538
|
|
|
537
539
|
const resolvedChildName = ast.childName(name, propName)
|
|
538
540
|
const propNode = parseSchema({ schema: resolvedPropSchema, name: resolvedChildName }, rawOptions)
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
541
|
+
const schemaNode = (() => {
|
|
542
|
+
const node = ast.setEnumName(propNode, name, propName, options.enumSuffix)
|
|
543
|
+
const tupleNode = ast.narrowSchema(node, 'tuple')
|
|
544
|
+
if (tupleNode?.items) {
|
|
545
|
+
const namedItems = tupleNode.items.map((item) => ast.setEnumName(item, name, propName, options.enumSuffix))
|
|
546
|
+
if (namedItems.some((item, i) => item !== tupleNode.items![i])) {
|
|
547
|
+
return { ...tupleNode, items: namedItems }
|
|
548
|
+
}
|
|
546
549
|
}
|
|
547
|
-
|
|
550
|
+
return node
|
|
551
|
+
})()
|
|
548
552
|
|
|
549
553
|
return ast.createProperty({
|
|
550
554
|
name: propName,
|
|
@@ -558,18 +562,15 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
558
562
|
: []
|
|
559
563
|
|
|
560
564
|
const additionalProperties = schema.additionalProperties
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
type: typeOptionMap.get(options.unknownType)!,
|
|
571
|
-
})
|
|
572
|
-
}
|
|
565
|
+
const additionalPropertiesNode: ast.SchemaNode | boolean | undefined = (() => {
|
|
566
|
+
if (additionalProperties === true) return true
|
|
567
|
+
if (additionalProperties === false) return false
|
|
568
|
+
if (additionalProperties && Object.keys(additionalProperties).length > 0) {
|
|
569
|
+
return parseSchema({ schema: additionalProperties as SchemaObject }, rawOptions)
|
|
570
|
+
}
|
|
571
|
+
if (additionalProperties) return ast.createSchema({ type: typeOptionMap.get(options.unknownType)! })
|
|
572
|
+
return undefined
|
|
573
|
+
})()
|
|
573
574
|
|
|
574
575
|
const rawPatternProperties = 'patternProperties' in schema ? schema.patternProperties : undefined
|
|
575
576
|
|
|
@@ -702,6 +703,7 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
702
703
|
description: schema.description,
|
|
703
704
|
deprecated: schema.deprecated,
|
|
704
705
|
nullable,
|
|
706
|
+
format: schema.format,
|
|
705
707
|
})
|
|
706
708
|
}
|
|
707
709
|
|
|
@@ -795,6 +797,7 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
795
797
|
name,
|
|
796
798
|
title: schema.title,
|
|
797
799
|
description: schema.description,
|
|
800
|
+
format: schema.format,
|
|
798
801
|
})
|
|
799
802
|
}
|
|
800
803
|
|
package/src/refs.ts
CHANGED
|
@@ -20,11 +20,8 @@ export function resolveRef<T = unknown>(document: Document, $ref: string): T | n
|
|
|
20
20
|
if ($ref === '') {
|
|
21
21
|
return null
|
|
22
22
|
}
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
} else {
|
|
26
|
-
return null
|
|
27
|
-
}
|
|
23
|
+
if (!$ref.startsWith('#')) return null
|
|
24
|
+
$ref = globalThis.decodeURIComponent($ref.substring(1))
|
|
28
25
|
|
|
29
26
|
let docCache = _refCache.get(document)
|
|
30
27
|
if (!docCache) {
|
package/src/resolvers.ts
CHANGED
|
@@ -314,13 +314,13 @@ function* collectRefs(schema: unknown): Generator<string, void, undefined> {
|
|
|
314
314
|
if (schema && typeof schema === 'object') {
|
|
315
315
|
for (const key in schema) {
|
|
316
316
|
const value = (schema as Record<string, unknown>)[key]
|
|
317
|
-
if (key === '$ref' && typeof value === 'string') {
|
|
318
|
-
if (value.startsWith(SCHEMA_REF_PREFIX)) {
|
|
319
|
-
const name = value.slice(SCHEMA_REF_PREFIX.length)
|
|
320
|
-
if (name) yield name
|
|
321
|
-
}
|
|
322
|
-
} else {
|
|
317
|
+
if (!(key === '$ref' && typeof value === 'string')) {
|
|
323
318
|
yield* collectRefs(value)
|
|
319
|
+
continue
|
|
320
|
+
}
|
|
321
|
+
if (value.startsWith(SCHEMA_REF_PREFIX)) {
|
|
322
|
+
const name = value.slice(SCHEMA_REF_PREFIX.length)
|
|
323
|
+
if (name) yield name
|
|
324
324
|
}
|
|
325
325
|
}
|
|
326
326
|
}
|
|
@@ -512,6 +512,7 @@ export function buildSchemaNode(schema: SchemaObject, name: string | null | unde
|
|
|
512
512
|
writeOnly: schema.writeOnly,
|
|
513
513
|
default: defaultValue,
|
|
514
514
|
example: schema.example,
|
|
515
|
+
format: schema.format,
|
|
515
516
|
} as const
|
|
516
517
|
}
|
|
517
518
|
|