@kubb/adapter-oas 5.0.0-alpha.23 → 5.0.0-alpha.25

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/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`, `ipv6`, and `hostname` map to `'url'` as the closest supported scalar.
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: 'url',
78
- ipv6: 'url',
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 = await Promise.all(pathOrApi.map((p) => parseDocument(p, { enablePaths: false, canBundle: false })))
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
- nullable,
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 | true | undefined
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 = undefined
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
  }