83 lines
2.3 KiB
JavaScript
83 lines
2.3 KiB
JavaScript
'use strict'
|
|
|
|
const Ref = require('json-schema-resolver')
|
|
const cloner = require('rfdc')({ proto: true, circles: false })
|
|
|
|
function addHook (fastify, pluginOptions) {
|
|
const routes = []
|
|
const sharedSchemasMap = new Map()
|
|
let hookRun = false
|
|
|
|
fastify.addHook('onRoute', (routeOptions) => {
|
|
const routeConfig = routeOptions.config || {}
|
|
const swaggerConfig = routeConfig.swagger || {}
|
|
if (routeOptions.method === 'HEAD' && pluginOptions.exposeHeadRoutes !== true && swaggerConfig.exposeHeadRoute !== true) {
|
|
return
|
|
}
|
|
|
|
if (
|
|
routeOptions.method === 'HEAD' &&
|
|
routeOptions.schema !== undefined &&
|
|
routeOptions.schema.operationId !== undefined
|
|
) {
|
|
routes.push(
|
|
// If two routes with operationId are added to the swagger
|
|
// object, it is no longer valid.
|
|
// therefore we suffix the operationId with `-head`.
|
|
Object.assign({}, routeOptions, {
|
|
schema: Object.assign({}, routeOptions.schema, {
|
|
operationId: `${routeOptions.schema.operationId}-head`
|
|
})
|
|
})
|
|
)
|
|
return
|
|
}
|
|
|
|
routes.push(routeOptions)
|
|
})
|
|
|
|
fastify.addHook('onRegister', async (instance) => {
|
|
// we need to wait the ready event to get all the .getSchemas()
|
|
// otherwise it will be empty
|
|
// TODO: better handle for schemaId
|
|
// when schemaId is the same in difference instance
|
|
// the latter will lost
|
|
instance.addHook('onReady', (done) => {
|
|
const allSchemas = instance.getSchemas()
|
|
for (const schemaId of Object.keys(allSchemas)) {
|
|
sharedSchemasMap.set(schemaId, allSchemas[schemaId])
|
|
}
|
|
done()
|
|
})
|
|
})
|
|
|
|
fastify.addHook('onReady', (done) => {
|
|
hookRun = true
|
|
const allSchemas = fastify.getSchemas()
|
|
for (const schemaId of Object.keys(allSchemas)) {
|
|
// it is the top-level, we do not expect to have duplicate id
|
|
sharedSchemasMap.set(schemaId, allSchemas[schemaId])
|
|
}
|
|
done()
|
|
})
|
|
|
|
return {
|
|
routes,
|
|
Ref () {
|
|
if (hookRun === false) {
|
|
throw new Error('.swagger() must be called after .ready()')
|
|
}
|
|
const externalSchemas = cloner(Array.from(sharedSchemasMap.values()))
|
|
return Ref(Object.assign(
|
|
{ applicationUri: 'todo.com' },
|
|
pluginOptions.refResolver,
|
|
{ clone: true, externalSchemas })
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
addHook
|
|
}
|