@kubb/adapter-oas 5.0.0-alpha.53 → 5.0.0-alpha.55

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/adapter-oas",
3
- "version": "5.0.0-alpha.53",
3
+ "version": "5.0.0-alpha.55",
4
4
  "description": "OpenAPI / Swagger adapter for Kubb converts OAS input into a @kubb/ast RootNode.",
5
5
  "keywords": [
6
6
  "adapter",
@@ -46,7 +46,7 @@
46
46
  "oas": "^32.1.15",
47
47
  "oas-normalize": "^16.0.4",
48
48
  "swagger2openapi": "^7.0.8",
49
- "@kubb/core": "5.0.0-alpha.53"
49
+ "@kubb/core": "5.0.0-alpha.55"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/swagger2openapi": "^7.0.4",
package/src/parser.ts CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  getMediaType,
12
12
  getParameters,
13
13
  getPrimitiveType,
14
+ getRequestBodyContentTypes,
14
15
  getRequestSchema,
15
16
  getResponseSchema,
16
17
  getSchemas,
@@ -789,13 +790,12 @@ function createSchemaParser(ctx: OasParserContext) {
789
790
  }
790
791
 
791
792
  /**
792
- * Reads the inline `requestBody` metadata (description / required / contentType) that OAS exposes
793
+ * Reads the inline `requestBody` metadata (description / required) that OAS exposes
793
794
  * outside the schema itself. Returns an empty object when the request body is missing or a `$ref`.
794
795
  */
795
796
  function getRequestBodyMeta(operation: Operation): {
796
797
  description?: string
797
798
  required: boolean
798
- contentType?: string
799
799
  } {
800
800
  const body = operation.schema.requestBody
801
801
  if (!body || isReference(body)) return { required: false }
@@ -803,12 +803,11 @@ function createSchemaParser(ctx: OasParserContext) {
803
803
  const inline = body as {
804
804
  description?: string
805
805
  required?: boolean
806
- content?: Record<string, unknown>
807
806
  }
807
+
808
808
  return {
809
809
  description: inline.description,
810
810
  required: inline.required === true,
811
- contentType: inline.content ? Object.keys(inline.content)[0] : undefined,
812
811
  }
813
812
  }
814
813
 
@@ -853,21 +852,33 @@ function createSchemaParser(ctx: OasParserContext) {
853
852
  parseParameter(options, param as unknown as Record<string, unknown>),
854
853
  )
855
854
 
856
- const requestBodySchema = getRequestSchema(document, operation, {
857
- contentType: ctx.contentType,
858
- })
859
- const requestBodySchemaNode = requestBodySchema ? parseSchema({ schema: requestBodySchema }, options) : undefined
855
+ // Determine which content types to include in requestBody.content.
856
+ // When a global contentType is configured, restrict to that single type.
857
+ // Otherwise include every content type declared in the spec.
858
+ const allContentTypes = ctx.contentType ? [ctx.contentType] : getRequestBodyContentTypes(document, operation)
859
+
860
860
  const requestBodyMeta = getRequestBodyMeta(operation)
861
861
 
862
- const requestBody = requestBodySchemaNode
863
- ? {
864
- description: requestBodyMeta.description,
865
- schema: ast.syncOptionality(requestBodySchemaNode, requestBodyMeta.required),
866
- keysToOmit: collectPropertyKeysByFlag(requestBodySchema, 'readOnly'),
867
- required: requestBodyMeta.required || undefined,
868
- contentType: requestBodyMeta.contentType,
869
- }
870
- : undefined
862
+ const content = allContentTypes.flatMap((ct) => {
863
+ const schema = getRequestSchema(document, operation, { contentType: ct })
864
+ if (!schema) return []
865
+ return [
866
+ {
867
+ contentType: ct,
868
+ schema: ast.syncOptionality(parseSchema({ schema }, options), requestBodyMeta.required),
869
+ keysToOmit: collectPropertyKeysByFlag(schema, 'readOnly'),
870
+ },
871
+ ]
872
+ })
873
+
874
+ const requestBody =
875
+ content.length > 0 || requestBodyMeta.description
876
+ ? {
877
+ description: requestBodyMeta.description,
878
+ required: requestBodyMeta.required || undefined,
879
+ content: content.length > 0 ? content : undefined,
880
+ }
881
+ : undefined
871
882
 
872
883
  const responses: Array<ast.ResponseNode> = operation.getResponseStatusCodes().map((statusCode) => {
873
884
  const responseObj = operation.getResponseByStatusCode(statusCode)
package/src/resolvers.ts CHANGED
@@ -524,3 +524,28 @@ export function buildSchemaNode(schema: SchemaObject, name: string | null | unde
524
524
  example: schema.example,
525
525
  } as const
526
526
  }
527
+
528
+ /**
529
+ * Returns all request body content type keys for an operation.
530
+ *
531
+ * The requestBody is dereferenced **in-place** when it is a `$ref` — the same mutation
532
+ * that `getRequestSchema` already performs — so that the returned list accurately reflects
533
+ * the available content types even for referenced bodies.
534
+ *
535
+ * @example
536
+ * ```ts
537
+ * getRequestBodyContentTypes(document, operation)
538
+ * // ['application/json', 'multipart/form-data']
539
+ * ```
540
+ */
541
+ export function getRequestBodyContentTypes(document: Document, operation: Operation): string[] {
542
+ if (operation.schema.requestBody) {
543
+ operation.schema.requestBody = dereferenceWithRef(document, operation.schema.requestBody)
544
+ }
545
+
546
+ const body = operation.schema.requestBody
547
+ if (!body || isReference(body)) return []
548
+
549
+ const inline = body as { content?: Record<string, unknown> }
550
+ return inline.content ? Object.keys(inline.content) : []
551
+ }