From 7c3d58c062e7fec10574ef4b7c06c4a2ba7b1e15 Mon Sep 17 00:00:00 2001 From: Kira <46629148+KiraPC@users.noreply.github.com> Date: Thu, 22 Apr 2021 05:36:45 +0200 Subject: [PATCH] feat: added option to hide untagged routes (#406) * added option to hide untagged routes * shouldRouteHide function accept options parameter * Use the right naming in swagger test case --- README.md | 1 + examples/dynamic-openapi.js | 39 +++++++++++++++++++++++++++++++++++++ examples/dynamic-swagger.js | 39 +++++++++++++++++++++++++++++++++++++ lib/mode/dynamic.js | 1 + lib/spec/openapi/index.js | 7 ++++++- lib/spec/openapi/utils.js | 4 +++- lib/spec/swagger/index.js | 7 ++++++- lib/spec/swagger/utils.js | 4 +++- lib/util/common.js | 14 +++++++++++-- test/spec/openapi/option.js | 33 +++++++++++++++++++++++++++++++ test/spec/swagger/option.js | 33 +++++++++++++++++++++++++++++++ 11 files changed, 176 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c33d8014..2b1ce7fd 100644 --- a/README.md +++ b/README.md @@ -177,6 +177,7 @@ fastify.ready(err => { | ------------------ | --------- | ------------------------------------------------------------------------------------------------------------------------- | | exposeRoute | false | Exposes documentation route. | | hiddenTag | X-HIDDEN | Tag to control hiding of routes. | + | hideUntagged | false | If true remove routes without tags in schema from resulting swagger file | | stripBasePath | true | Strips base path from routes in docs. | | swagger | {} | Swagger configuration. | | openapi | {} | OpenAPI configuration. | diff --git a/examples/dynamic-openapi.js b/examples/dynamic-openapi.js index a1a9f9ee..00201941 100644 --- a/examples/dynamic-openapi.js +++ b/examples/dynamic-openapi.js @@ -22,6 +22,7 @@ fastify.register(require('../index'), { } } }, + hideUntagged: true, exposeRoute: true }) @@ -64,6 +65,44 @@ fastify.put('/some-route/:id', { } }, (req, reply) => { reply.send({ hello: `Hello ${req.body.hello}` }) }) +fastify.post('/some-route/:id', { + schema: { + description: 'post some data', + summary: 'qwerty', + security: [{ apiKey: [] }], + params: { + type: 'object', + properties: { + id: { + type: 'string', + description: 'user id' + } + } + }, + body: { + type: 'object', + properties: { + hello: { type: 'string' }, + obj: { + type: 'object', + properties: { + some: { type: 'string' } + } + } + } + }, + response: { + 201: { + description: 'Succesful response', + type: 'object', + properties: { + hello: { type: 'string' } + } + } + } + } +}, (req, reply) => { reply.send({ hello: `Hello ${req.body.hello}` }) }) + fastify.listen(3000, err => { if (err) throw err console.log('listening') diff --git a/examples/dynamic-swagger.js b/examples/dynamic-swagger.js index d04f7f48..f9bc9e53 100644 --- a/examples/dynamic-swagger.js +++ b/examples/dynamic-swagger.js @@ -21,6 +21,7 @@ fastify.register(require('../index'), { consumes: ['application/json'], produces: ['application/json'] }, + hideUntagged: true, exposeRoute: true }) @@ -63,6 +64,44 @@ fastify.put('/some-route/:id', { } }, (req, reply) => { reply.send({ hello: `Hello ${req.body.hello}` }) }) +fastify.post('/some-route/:id', { + schema: { + description: 'post some data', + summary: 'qwerty', + security: [{ apiKey: [] }], + params: { + type: 'object', + properties: { + id: { + type: 'string', + description: 'user id' + } + } + }, + body: { + type: 'object', + properties: { + hello: { type: 'string' }, + obj: { + type: 'object', + properties: { + some: { type: 'string' } + } + } + } + }, + response: { + 201: { + description: 'Succesful response', + type: 'object', + properties: { + hello: { type: 'string' } + } + } + } + } +}, (req, reply) => { reply.send({ hello: `Hello ${req.body.hello}` }) }) + fastify.listen(3000, err => { if (err) throw err console.log('listening') diff --git a/lib/mode/dynamic.js b/lib/mode/dynamic.js index 4e2675eb..6a1b31b4 100644 --- a/lib/mode/dynamic.js +++ b/lib/mode/dynamic.js @@ -8,6 +8,7 @@ module.exports = function (fastify, opts, done) { opts = Object.assign({}, { exposeRoute: false, hiddenTag: 'X-HIDDEN', + hideUntagged: false, stripBasePath: true, openapi: null, swagger: {}, diff --git a/lib/spec/openapi/index.js b/lib/spec/openapi/index.js index 49711a51..8992a6b5 100644 --- a/lib/spec/openapi/index.js +++ b/lib/spec/openapi/index.js @@ -36,7 +36,12 @@ module.exports = function (opts, cache, routes, Ref, done) { ? defOpts.transform(route.schema) : route.schema - if (shouldRouteHide(schema, defOpts.hiddenTag)) continue + const shouldRouteHideOpts = { + hiddenTag: defOpts.hiddenTag, + hideUntagged: defOpts.hideUntagged + } + + if (shouldRouteHide(schema, shouldRouteHideOpts)) continue const url = normalizeUrl(route.url, defOpts.servers, defOpts.stripBasePath) diff --git a/lib/spec/openapi/utils.js b/lib/spec/openapi/utils.js index b1f51f0a..6fa4809b 100644 --- a/lib/spec/openapi/utils.js +++ b/lib/spec/openapi/utils.js @@ -15,6 +15,7 @@ function prepareDefaultOptions (opts) { const stripBasePath = opts.stripBasePath const transform = opts.transform const hiddenTag = opts.hiddenTag + const hideUntagged = opts.hideUntagged const extensions = [] for (const [key, value] of Object.entries(opts.openapi)) { @@ -33,7 +34,8 @@ function prepareDefaultOptions (opts) { stripBasePath, transform, hiddenTag, - extensions + extensions, + hideUntagged } } diff --git a/lib/spec/swagger/index.js b/lib/spec/swagger/index.js index 2b1181ee..fa358e41 100644 --- a/lib/spec/swagger/index.js +++ b/lib/spec/swagger/index.js @@ -36,7 +36,12 @@ module.exports = function (opts, cache, routes, Ref, done) { ? defOpts.transform(route.schema) : route.schema - if (shouldRouteHide(schema, defOpts.hiddenTag)) continue + const shouldRouteHideOpts = { + hiddenTag: defOpts.hiddenTag, + hideUntagged: defOpts.hideUntagged + } + + if (shouldRouteHide(schema, shouldRouteHideOpts)) continue const url = normalizeUrl(route.url, defOpts.basePath, defOpts.stripBasePath) diff --git a/lib/spec/swagger/utils.js b/lib/spec/swagger/utils.js index b2483f91..777b280f 100644 --- a/lib/spec/swagger/utils.js +++ b/lib/spec/swagger/utils.js @@ -19,6 +19,7 @@ function prepareDefaultOptions (opts) { const stripBasePath = opts.stripBasePath const transform = opts.transform const hiddenTag = opts.hiddenTag + const hideUntagged = opts.hideUntagged const extensions = [] for (const [key, value] of Object.entries(opts.swagger)) { @@ -42,7 +43,8 @@ function prepareDefaultOptions (opts) { stripBasePath, transform, hiddenTag, - extensions + extensions, + hideUntagged } } diff --git a/lib/util/common.js b/lib/util/common.js index 38f09c2c..a727db25 100644 --- a/lib/util/common.js +++ b/lib/util/common.js @@ -41,13 +41,23 @@ function addHook (fastify) { } } -function shouldRouteHide (schema, hiddenTag) { +function shouldRouteHide (schema, opts) { + const { hiddenTag, hideUntagged } = opts + if (schema && schema.hide) { return true } - if (schema && schema.tags && schema.tags.includes(hiddenTag)) { + + const tags = (schema && schema.tags) || [] + + if (tags.length === 0 && hideUntagged) { + return true + } + + if (tags.includes(hiddenTag)) { return schema.tags.includes(hiddenTag) } + return false } diff --git a/test/spec/openapi/option.js b/test/spec/openapi/option.js index 31abe9fb..ec646931 100644 --- a/test/spec/openapi/option.js +++ b/test/spec/openapi/option.js @@ -213,6 +213,39 @@ test('hide support - tags Custom', t => { }) }) +test('hide support - hidden untagged', t => { + t.plan(2) + const fastify = Fastify() + + fastify.register(fastifySwagger, { ...openapiOption, hideUntagged: true }) + + const opts = { + schema: { + body: { + type: 'object', + properties: { + hello: { type: 'string' }, + obj: { + type: 'object', + properties: { + some: { type: 'string' } + } + } + } + } + } + } + + fastify.get('/', opts, () => {}) + + fastify.ready(err => { + t.error(err) + + const openapiObject = fastify.swagger() + t.notOk(openapiObject.paths['/']) + }) +}) + test('basePath support', t => { t.plan(3) const fastify = Fastify() diff --git a/test/spec/swagger/option.js b/test/spec/swagger/option.js index 48df9494..fdf21e30 100644 --- a/test/spec/swagger/option.js +++ b/test/spec/swagger/option.js @@ -386,6 +386,39 @@ test('hide support - tags Custom', t => { }) }) +test('hide support - hidden untagged', t => { + t.plan(2) + const fastify = Fastify() + + fastify.register(fastifySwagger, { ...swaggerOption, hideUntagged: true }) + + const opts = { + schema: { + body: { + type: 'object', + properties: { + hello: { type: 'string' }, + obj: { + type: 'object', + properties: { + some: { type: 'string' } + } + } + } + } + } + } + + fastify.get('/', opts, () => {}) + + fastify.ready(err => { + t.error(err) + + const swaggerObject = fastify.swagger() + t.notOk(swaggerObject.paths['/']) + }) +}) + test('cache - json', t => { t.plan(3) const fastify = Fastify()