diff --git a/README.md b/README.md index e3a7cf4a..ad863059 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,10 @@ fastify.register(require('fastify-swagger'), { } } }, + uiConfig: { + docExpansion: 'full', + deepLinking: false + }, exposeRoute: true }) @@ -167,14 +171,17 @@ fastify.ready(err => { ##### options - | option | default | description | - |---------------|----------|---------------------------------------| - | exposeRoute | false | Exposes documentation route. | - | hiddenTag | X-HIDDEN | Tag to control hiding of routes. | - | stripBasePath | true | Strips base path from routes in docs. | - | swagger | {} | Swagger configuration. | - | openapi | {} | Openapi configuration. | - | transform | null | Transform method for schema. | + | option | default | description | + | ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------- | + | exposeRoute | false | Exposes documentation route. | + | hiddenTag | X-HIDDEN | Tag to control hiding of routes. | + | stripBasePath | true | Strips base path from routes in docs. | + | swagger | {} | Swagger configuration. | + | openapi | {} | Openapi configuration. | + | transform | null | Transform method for schema. | + | uiConfig* | {} | Configuration options for [Swagger UI](https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md) | + +> `uiConfig` accepts only literal (number/string/object) configuration values since they are serialized in order to pass them to the generated UI. For more details see: [#5710](https://github.com/swagger-api/swagger-ui/issues/5710). ##### 2XX status code `fastify` itself support the `2xx`, `3xx` status, however `swagger` itself do not support this featuer. We will help you to transform the `2xx` status code into `200` and we will omit `2xx` status code when you already declared `200` status code. @@ -226,17 +233,20 @@ Example: By default, this is the directory where the main spec file is located. Provided value should be an absolute path **without** trailing slash. #### additional + If you pass `{ exposeRoute: true }` during the registration the plugin will expose the documentation with the following apis: -| url | description | -|-------|----------------| -|`'/documentation/json'` | the json object representing the api | -|`'/documentation/yaml'` | the yaml object representing the api | -|`'/documentation/'` | the swagger ui | -|`'/documentation/*'`| external files which you may use in `$ref`| +| url | description | +| ----------------------- | ------------------------------------------ | +| `'/documentation/json'` | the json object representing the api | +| `'/documentation/yaml'` | the yaml object representing the api | +| `'/documentation/'` | the swagger ui | +| `'/documentation/*'` | external files which you may use in `$ref` | ##### Overwrite swagger url end-point + If you would like to overwrite the `/documentation` url you can use the `routePrefix` option. + ```js fastify.register(require('fastify-swagger'), { swagger: { @@ -254,7 +264,9 @@ fastify.register(require('fastify-swagger'), { ``` ##### Convert routes schema + If you would like to use different schemas like, let's say [Joi](https://github.com/hapijs/joi), you can pass a synchronous `transform` method in the options to convert them back to standard JSON schemas expected by this plugin to generate the documentation (`dynamic` mode only). + ```js const convert = require('joi-to-json-schema') @@ -280,7 +292,9 @@ fastify.register(require('fastify-swagger'), { ``` + ### swagger options + Calling `fastify.swagger` will return to you a JSON object representing your api, if you pass `{ yaml: true }` to `fastify.swagger`, it will return you a yaml string. ### Open API (OA) Parameter Options diff --git a/lib/mode/dynamic.js b/lib/mode/dynamic.js index bd0b7019..e0a00e0f 100644 --- a/lib/mode/dynamic.js +++ b/lib/mode/dynamic.js @@ -16,7 +16,8 @@ module.exports = function (fastify, opts, done) { if (opts.exposeRoute === true) { const prefix = opts.routePrefix || '/documentation' - fastify.register(require('../routes'), { prefix }) + const uiConfig = opts.uiConfig || {} + fastify.register(require('../routes'), { prefix, uiConfig }) } const cache = { diff --git a/lib/routes.js b/lib/routes.js index 011055d3..9fc74022 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -29,6 +29,15 @@ function fastifySwagger (fastify, opts, done) { } }) + fastify.route({ + url: '/uiConfig', + method: 'GET', + schema: { hide: true }, + handler: (req, reply) => { + reply.send(opts.uiConfig) + } + }) + fastify.route({ url: '/json', method: 'GET', diff --git a/lib/util/prepare-swagger-ui.js b/lib/util/prepare-swagger-ui.js index 7f41c828..5124e042 100644 --- a/lib/util/prepare-swagger-ui.js +++ b/lib/util/prepare-swagger-ui.js @@ -24,18 +24,51 @@ filesToCopy.forEach(filename => { }) const newIndex = fs.readFileSync(resolve('./static/index.html'), 'utf8') - .replace('window.ui = ui', `window.ui = ui + .replace(/ + `) fse.writeFileSync(resolve('./static/index.html'), newIndex) diff --git a/package.json b/package.json index 0d643190..5df2c01a 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,8 @@ "scripts": { "prepare": "node lib/util/prepare-swagger-ui", "prepublishOnly": "npm run prepare", - "test": "standard && tap --100 test/**/*.js && npm run typescript", - "test:ci": "standard && tap test/**/*.js --coverage-report=lcovonly && npm run typescript", + "test": "standard && tap --100 'test/**/*.js' && npm run typescript", + "test:ci": "standard && tap 'test/**/*.js' --coverage-report=lcovonly && npm run typescript", "typescript": "tsd" }, "repository": { @@ -41,7 +41,7 @@ "standard": "^16.0.1", "swagger-parser": "^10.0.2", "swagger-ui-dist": "3.41.1", - "tap": "^14.10.8", + "tap": "^14.11.0", "tsd": "^0.14.0" }, "dependencies": { @@ -60,4 +60,4 @@ "tsd": { "directory": "test/types" } -} +} \ No newline at end of file diff --git a/test/route.js b/test/route.js index 0aaf75e6..003fc7dd 100644 --- a/test/route.js +++ b/test/route.js @@ -86,6 +86,40 @@ test('/documentation/json route', t => { }) }) +test('/documentation/uiConfig route', t => { + t.plan(2) + const fastify = Fastify() + + const uiConfig = { + docExpansion: 'full' + } + + const opts = { + ...swaggerOption, + uiConfig + } + + fastify.register(fastifySwagger, opts) + + fastify.get('/', () => {}) + fastify.post('/', () => {}) + fastify.get('/example', schemaQuerystring, () => {}) + fastify.post('/example', schemaBody, () => {}) + fastify.get('/parameters/:id', schemaParams, () => {}) + fastify.get('/example1', schemaSecurity, () => {}) + + fastify.inject({ + method: 'GET', + url: '/documentation/uiConfig' + }, (err, res) => { + t.error(err) + + const payload = JSON.parse(res.payload) + + t.match(payload, uiConfig, 'uiConfig should be valid') + }) +}) + test('fastify.swagger should return a valid swagger yaml', t => { t.plan(4) const fastify = Fastify()