Skip to content

Commit

Permalink
swap definitions with properties at defsToComponents transformer
Browse files Browse the repository at this point in the history
  • Loading branch information
asc11cat committed Oct 8, 2022
1 parent 04cd48a commit e2d1a8b
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 26 deletions.
27 changes: 8 additions & 19 deletions lib/spec/openapi/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ function transformDefsToComponents (jsonSchema) {
Object.keys(jsonSchema[key]).forEach(function (prop) {
jsonSchema[key][prop] = transformDefsToComponents(jsonSchema[key][prop])
})
// definitions are not allowed in openapi schema, so we mutate them to properties
} else if (key === 'definitions') {
jsonSchema.properties = {
...transformDefsToComponents(jsonSchema[key]),
...jsonSchema.properties
}
delete jsonSchema[key]
} else if (key === '$ref') {
// replace the top-lvl path
jsonSchema[key] = jsonSchema[key].replace('definitions', 'components/schemas')
Expand Down Expand Up @@ -406,29 +413,11 @@ function prepareOpenapiSchemas (schemas, ref) {
.reduce((res, [name, schema]) => {
const _ = { ...schema }

// 'definitions' keyword is not supported by openapi in schema item
// but we can receive it from json-schema input
if (_.definitions) {
_.properties = {
..._.definitions,
..._.properties
}
}

// ref.resolve call does 3 things:
// modifies underlying cache of ref
// adds 'definitions' with resolved schema(which we don't need here anymore)
// mutates $ref to point to the resolved schema
// ($ref will be mutated again by transformDefsToComponents)
const resolvedRef = ref.resolve(_, { externalSchemas: [schemas] })

// swagger doesn't accept $id on components schemas
// $ids are needed by ref.resolve to check the URI
// definitions are added by resolve, but they are not needed, as we resolve
// the $ref to already existing schemas in components.schemas using method below
// therefore, we delete both $id and definitions at the end of the process
// $ids are needed only for ref.resolve to check the URI
delete resolvedRef.$id
delete resolvedRef.definitions

const components = transformDefsToComponents(resolvedRef)

Expand Down
9 changes: 2 additions & 7 deletions test/spec/openapi/refs.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,34 +283,29 @@ test('uses examples if has property required in body', async (t) => {
t.same(schema.parameters[0].in, 'query')
})

test('support schema $ref inside the json-schema definitions', async (t) => {
test('support absolute $ref inside the json-schema definitions', async (t) => {
const fastify = Fastify()

await fastify.register(fastifySwagger, openapiOption)
fastify.register(async (instance) => {
instance.addSchema({
$id: 'NestedSchema',
properties: {
id: { type: 'string' }
},
definitions: {
SchemaA: {
$id: 'SchemaA',
type: 'object',
properties: {
id: { type: 'string' }
}
},
SchemaB: {
$id: 'SchemaB',
type: 'object',
properties: {
example: { $ref: 'NestedSchema#/definitions/SchemaA' }
}
}
}
})
instance.post('/url1', { schema: { body: { $ref: 'NestedSchema#/definitions/SchemaB' }, response: { 200: { $ref: 'NestedSchema#/definitions/SchemaA' } } } }, () => {})
instance.post('/url1/:test', { schema: { body: { $ref: 'NestedSchema#/definitions/SchemaB' }, params: { $ref: 'NestedSchema#/definitions/SchemaA' }, response: { 200: { $ref: 'NestedSchema#/definitions/SchemaA' } } } }, () => {})
})

await fastify.ready()
Expand Down

0 comments on commit e2d1a8b

Please sign in to comment.