Skip to content

Commit

Permalink
fix: nested examples in OpenAPI schemas for request body & response (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
shfrmn authored Jan 15, 2024
1 parent d960bcb commit b1258ca
Show file tree
Hide file tree
Showing 3 changed files with 899 additions and 213 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1000,7 +1000,7 @@ Will generate this in the OpenAPI v3 schema's `path`:
"foo": { "type": "string" },
"bar": { "type": "string" }
},
"examples": [{ "foo": "bar", "bar": "baz" }]
"example": { "foo": "bar", "bar": "baz" }
}
}
},
Expand Down
44 changes: 42 additions & 2 deletions lib/spec/openapi/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,40 @@ function plainJsonObjectToOpenapi3 (container, jsonSchema, externalSchemas, secu
})
}

const schemaTypeToNestedSchemas = {
object: (schema) => {
return [
...Object.values(schema.properties || {}),
...Object.values(schema.patternProperties || {}),
...Object.values(schema.additionalProperties || {})
]
},
array: (schema) => {
return [
...(schema.items ? [schema.items] : []),
...(schema.contains ? [schema.contains] : [])
]
}
}

function resolveSchemaExamples (schema) {
const example = schema[xExamples] ?? schema.examples?.[0]
if (typeof example !== 'undefined') {
schema.example = example
}
delete schema[xExamples]
delete schema.examples
}

function resolveSchemaExamplesRecursive (schema) {
resolveSchemaExamples(schema)
const getNestedSchemas = schemaTypeToNestedSchemas[schema.type]
const nestedSchemas = getNestedSchemas?.(schema) ?? []
for (const nestedSchema of nestedSchemas) {
resolveSchemaExamplesRecursive(nestedSchema)
}
}

function schemaToMedia (schema) {
const media = { schema }

Expand All @@ -251,13 +285,19 @@ function schemaToMedia (schema) {
return media
}

function schemaToMediaRecursive (schema) {
const media = schemaToMedia(schema)
resolveSchemaExamplesRecursive(schema)
return media
}

function resolveBodyParams (body, schema, consumes, ref) {
const resolved = transformDefsToComponents(ref.resolve(schema))
if ((Array.isArray(consumes) && consumes.length === 0) || consumes === undefined) {
consumes = ['application/json']
}

const media = schemaToMedia(resolved)
const media = schemaToMediaRecursive(resolved)
consumes.forEach((consume) => {
body.content[consume] = media
})
Expand Down Expand Up @@ -346,7 +386,7 @@ function resolveResponse (fastifyResponseJson, produces, ref) {

delete resolved[xResponseDescription]

const media = schemaToMedia(resolved)
const media = schemaToMediaRecursive(resolved)

for (const produce of produces) {
content[produce] = media
Expand Down
Loading

0 comments on commit b1258ca

Please sign in to comment.