@kubb/adapter-oas 5.0.0-alpha.24 → 5.0.0-alpha.26
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 +54 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +54 -16
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/src/constants.ts +4 -3
- package/src/factory.ts +4 -1
- package/src/parser.ts +44 -12
package/src/constants.ts
CHANGED
|
@@ -56,7 +56,8 @@ export const structuralKeys = new Set(['properties', 'items', 'additionalPropert
|
|
|
56
56
|
*
|
|
57
57
|
* Only formats whose AST type differs from the OAS `type` field appear here.
|
|
58
58
|
* Formats that depend on runtime options (`int64`, `date-time`, `date`, `time`) are handled separately
|
|
59
|
-
* in the parser. `ipv4
|
|
59
|
+
* in the parser. `ipv4` and `ipv6` map to their own dedicated schema types; `hostname` and
|
|
60
|
+
* `idn-hostname` map to `'url'` as the closest generic string-format type.
|
|
60
61
|
*
|
|
61
62
|
* @example
|
|
62
63
|
* ```ts
|
|
@@ -74,8 +75,8 @@ export const formatMap = {
|
|
|
74
75
|
uri: 'url',
|
|
75
76
|
'uri-reference': 'url',
|
|
76
77
|
url: 'url',
|
|
77
|
-
ipv4: '
|
|
78
|
-
ipv6: '
|
|
78
|
+
ipv4: 'ipv4',
|
|
79
|
+
ipv6: 'ipv6',
|
|
79
80
|
hostname: 'url',
|
|
80
81
|
'idn-hostname': 'url',
|
|
81
82
|
binary: 'blob',
|
package/src/factory.ts
CHANGED
|
@@ -65,7 +65,10 @@ export async function parseDocument(pathOrApi: string | Document, { canBundle =
|
|
|
65
65
|
* ```
|
|
66
66
|
*/
|
|
67
67
|
export async function mergeDocuments(pathOrApi: Array<string | Document>): Promise<Document> {
|
|
68
|
-
const documents
|
|
68
|
+
const documents: Document[] = []
|
|
69
|
+
for (const p of pathOrApi) {
|
|
70
|
+
documents.push(await parseDocument(p, { enablePaths: false, canBundle: false }))
|
|
71
|
+
}
|
|
69
72
|
|
|
70
73
|
if (documents.length === 0) {
|
|
71
74
|
throw new Error('No OAS documents provided for merging.')
|
package/src/parser.ts
CHANGED
|
@@ -103,22 +103,42 @@ function createSchemaParser(ctx: OasParserContext) {
|
|
|
103
103
|
|
|
104
104
|
// Branch handlers — each converts one OAS schema pattern to a SchemaNode.
|
|
105
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Tracks `$ref` paths that are currently being resolved to prevent infinite
|
|
108
|
+
* recursion when schemas contain circular references (e.g. `Pet → parent → Pet`).
|
|
109
|
+
*/
|
|
110
|
+
const resolvingRefs = new Set<string>()
|
|
111
|
+
|
|
106
112
|
/**
|
|
107
113
|
* Converts a `$ref` schema into a `RefSchemaNode`.
|
|
114
|
+
*
|
|
115
|
+
* The resolved schema is stored in `node.schema`. Usage-site sibling fields
|
|
116
|
+
* (description, readOnly, nullable, etc.) are stored directly on the ref node.
|
|
117
|
+
* Use `syncSchemaRef(node)` in printers to get a merged view of both.
|
|
118
|
+
* Circular refs are detected via `resolvingRefs` and leave `schema` as `undefined`.
|
|
108
119
|
*/
|
|
109
|
-
function convertRef({ schema, nullable, defaultValue }: SchemaContext): SchemaNode {
|
|
120
|
+
function convertRef({ schema, name, nullable, defaultValue, rawOptions }: SchemaContext): SchemaNode {
|
|
121
|
+
let resolvedSchema: SchemaNode | undefined
|
|
122
|
+
const refPath = schema.$ref
|
|
123
|
+
if (refPath && !resolvingRefs.has(refPath)) {
|
|
124
|
+
try {
|
|
125
|
+
const referenced = resolveRef<SchemaObject>(document, refPath)
|
|
126
|
+
if (referenced) {
|
|
127
|
+
resolvingRefs.add(refPath)
|
|
128
|
+
resolvedSchema = parseSchema({ schema: referenced }, rawOptions)
|
|
129
|
+
resolvingRefs.delete(refPath)
|
|
130
|
+
}
|
|
131
|
+
} catch {
|
|
132
|
+
// Ref cannot be resolved in this document (e.g. unit tests with minimal documents).
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
110
136
|
return createSchema({
|
|
137
|
+
...buildSchemaNode(schema, name, nullable, defaultValue),
|
|
111
138
|
type: 'ref',
|
|
112
139
|
name: extractRefName(schema.$ref!),
|
|
113
140
|
ref: schema.$ref,
|
|
114
|
-
|
|
115
|
-
description: schema.description,
|
|
116
|
-
deprecated: schema.deprecated,
|
|
117
|
-
readOnly: schema.readOnly,
|
|
118
|
-
writeOnly: schema.writeOnly,
|
|
119
|
-
pattern: schema.type === 'string' ? schema.pattern : undefined,
|
|
120
|
-
example: schema.example,
|
|
121
|
-
default: defaultValue,
|
|
141
|
+
schema: resolvedSchema,
|
|
122
142
|
})
|
|
123
143
|
}
|
|
124
144
|
|
|
@@ -365,7 +385,16 @@ function createSchemaParser(ctx: OasParserContext) {
|
|
|
365
385
|
return createSchema({ ...base, primitive: specialPrimitive, type: specialType })
|
|
366
386
|
}
|
|
367
387
|
if (specialType === 'url') {
|
|
368
|
-
return createSchema({ ...base, primitive: 'string' as const, type: 'url' })
|
|
388
|
+
return createSchema({ ...base, primitive: 'string' as const, type: 'url', min: schema.minLength, max: schema.maxLength })
|
|
389
|
+
}
|
|
390
|
+
if (specialType === 'ipv4') {
|
|
391
|
+
return createSchema({ ...base, primitive: 'string' as const, type: 'ipv4' })
|
|
392
|
+
}
|
|
393
|
+
if (specialType === 'ipv6') {
|
|
394
|
+
return createSchema({ ...base, primitive: 'string' as const, type: 'ipv6' })
|
|
395
|
+
}
|
|
396
|
+
if (specialType === 'uuid' || specialType === 'email') {
|
|
397
|
+
return createSchema({ ...base, primitive: 'string' as const, type: specialType, min: schema.minLength, max: schema.maxLength })
|
|
369
398
|
}
|
|
370
399
|
|
|
371
400
|
return createSchema({ ...base, primitive: specialPrimitive, type: specialType as ScalarSchemaType })
|
|
@@ -460,13 +489,13 @@ function createSchemaParser(ctx: OasParserContext) {
|
|
|
460
489
|
: []
|
|
461
490
|
|
|
462
491
|
const additionalProperties = schema.additionalProperties
|
|
463
|
-
let additionalPropertiesNode: SchemaNode |
|
|
492
|
+
let additionalPropertiesNode: SchemaNode | boolean | undefined
|
|
464
493
|
if (additionalProperties === true) {
|
|
465
494
|
additionalPropertiesNode = true
|
|
466
495
|
} else if (additionalProperties && Object.keys(additionalProperties).length > 0) {
|
|
467
496
|
additionalPropertiesNode = parseSchema({ schema: additionalProperties as SchemaObject }, rawOptions)
|
|
468
497
|
} else if (additionalProperties === false) {
|
|
469
|
-
additionalPropertiesNode =
|
|
498
|
+
additionalPropertiesNode = false
|
|
470
499
|
} else if (additionalProperties) {
|
|
471
500
|
additionalPropertiesNode = createSchema({ type: typeOptionMap.get(options.unknownType)! })
|
|
472
501
|
}
|
|
@@ -490,6 +519,8 @@ function createSchemaParser(ctx: OasParserContext) {
|
|
|
490
519
|
properties,
|
|
491
520
|
additionalProperties: additionalPropertiesNode,
|
|
492
521
|
patternProperties,
|
|
522
|
+
minProperties: schema.minProperties,
|
|
523
|
+
maxProperties: schema.maxProperties,
|
|
493
524
|
...buildSchemaNode(schema, name, nullable, defaultValue),
|
|
494
525
|
})
|
|
495
526
|
|
|
@@ -565,6 +596,7 @@ function createSchemaParser(ctx: OasParserContext) {
|
|
|
565
596
|
max: schema.maximum,
|
|
566
597
|
exclusiveMinimum: typeof schema.exclusiveMinimum === 'number' ? schema.exclusiveMinimum : undefined,
|
|
567
598
|
exclusiveMaximum: typeof schema.exclusiveMaximum === 'number' ? schema.exclusiveMaximum : undefined,
|
|
599
|
+
multipleOf: schema.multipleOf,
|
|
568
600
|
...buildSchemaNode(schema, name, nullable, defaultValue),
|
|
569
601
|
})
|
|
570
602
|
}
|