From 5e5e23b2cc81b32c59a1b45d70e219493c55dfe7 Mon Sep 17 00:00:00 2001 From: Seth Wheeler <23089578+Megapixel99@users.noreply.github.com> Date: Wed, 1 Nov 2023 12:30:26 -0500 Subject: [PATCH 1/5] update readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7e10a93..82e9e1f 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,9 @@ Options: - `options.coerce`: Enable data type [`coercion`](https://www.npmjs.com/package/ajv#coercing-data-types) - `options.htmlui`: Turn on serving `redoc` or `swagger-ui` html ui - `options.basePath`: When set, will strip the value of `basePath` from the start of every path. -The options object can also accept configuration parameters for Swagger and Redoc. The full list of Swagger and Redoc configuration options can be found here: https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/ and here: https://redocly.com/docs/redoc/config/ respectively. + - `options.customScripts`: an array of strings where you can pass in custom scripts which modify the appearance and/or functionality of the Swagger UI. + - `options.plugins`: If you have a custom script, you need to pass the name of the script in here (as an array of strings). + - The options object can also accept configuration parameters for Swagger and Redoc. The full list of Swagger and Redoc configuration options can be found here: https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/ and here: https://redocly.com/docs/redoc/config/ respectively. ##### Coerce From 8b93c61829e2268663250f46f0e333f78788b2b8 Mon Sep 17 00:00:00 2001 From: Seth Wheeler <23089578+Megapixel99@users.noreply.github.com> Date: Wed, 1 Nov 2023 15:38:49 -0500 Subject: [PATCH 2/5] allow custom plugins via `customScripts` and `plugins` --- index.js | 4 ++-- lib/ui.js | 25 +++++++++++-------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/index.js b/index.js index 08b5626..d46a557 100644 --- a/index.js +++ b/index.js @@ -127,8 +127,8 @@ module.exports = function ExpressOpenApi (_routePrefix, _doc, _opts) { middleware.callbacks = middleware.component.bind(null, 'callbacks') // Expose ui middleware - middleware.redoc = ui.serveRedoc(`${routePrefix}.json`, opts) - middleware.swaggerui = ui.serveSwaggerUI(`${routePrefix}.json`, opts) + middleware.redoc = (options) => ui.serveRedoc(`${routePrefix}.json`, options) + middleware.swaggerui = (options) => ui.serveSwaggerUI(`${routePrefix}.json`, options) // OpenAPI document as json router.get(`${routePrefix}.json`, (req, res) => { diff --git a/lib/ui.js b/lib/ui.js index bffd4e8..78ef043 100644 --- a/lib/ui.js +++ b/lib/ui.js @@ -2,7 +2,7 @@ const path = require('path') const serve = require('serve-static') -module.exports.serveRedoc = function serveRedoc (documentUrl, opts) { +module.exports.serveRedoc = function serveRedoc (documentUrl, opts = {}) { const toKebabCase = (string) => string .replace(/([a-z])([A-Z])/g, '$1-$2') @@ -25,25 +25,22 @@ module.exports.serveRedoc = function serveRedoc (documentUrl, opts) { }] } -module.exports.serveSwaggerUI = function serveSwaggerUI (documentUrl, opts) { - const options = { - url: documentUrl, - dom_id: '#swagger-ui' - } - Object.keys(opts).forEach((key) => { - if (!['coerce', 'htmlui', 'basePath'].includes(key)) { - options[key] = opts[key] - } - }) +module.exports.serveSwaggerUI = function serveSwaggerUI (documentUrl, opts = {}) { + const { plugins, ...options } = opts return [serve(path.resolve(require.resolve('swagger-ui-dist'), '..'), { index: false }), function returnUiInit (req, res, next) { if (req.path.endsWith('/swagger-ui-init.js')) { res.type('.js') res.send(`window.onload = function () { - window.ui = SwaggerUIBundle(${JSON.stringify(options, null, 2)}) -} - `) + window.ui = SwaggerUIBundle({ + url: '${documentUrl}', + dom_id: '#swagger-ui', + plugins: [${plugins}], + ...${JSON.stringify(options)} + }) +}` + ) } else { next() } From 56912f5d97ec1e675fe1ae0a37a7155e6c9c4a63 Mon Sep 17 00:00:00 2001 From: Seth Wheeler <23089578+Megapixel99@users.noreply.github.com> Date: Wed, 1 Nov 2023 15:39:03 -0500 Subject: [PATCH 3/5] update tests --- test/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/index.js b/test/index.js index 30a5854..75196a8 100644 --- a/test/index.js +++ b/test/index.js @@ -106,7 +106,7 @@ suite(name, function () { test('create a basic valid Swagger UI document and check the HTML title', function (done) { const app = express() - app.use(openapi().swaggerui) + app.use(openapi().swaggerui()) supertest(app) .get(`${openapi.defaultRoutePrefix}.json`) .end((err, res) => { @@ -118,7 +118,7 @@ suite(name, function () { test('serves onload function in swagger-ui-init.js file', function (done) { const app = express() - app.use(openapi().swaggerui) + app.use(openapi().swaggerui()) supertest(app) .get(`${openapi.defaultRoutePrefix}/swagger-ui-init.js`) .end((err, res) => { @@ -130,7 +130,7 @@ suite(name, function () { test('create a basic valid ReDoc document and check the HTML title', function (done) { const app = express() - app.use(openapi().redoc) + app.use(openapi().redoc()) supertest(app) .get(`${openapi.defaultRoutePrefix}.json`) .end((err, res) => { From 4f2ee85d5d157fdd9026f1c14ca6b8fb614b6919 Mon Sep 17 00:00:00 2001 From: Seth Wheeler <23089578+Megapixel99@users.noreply.github.com> Date: Wed, 1 Nov 2023 15:45:49 -0500 Subject: [PATCH 4/5] add additional info to readme --- README.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 82e9e1f..17c57b8 100644 --- a/README.md +++ b/README.md @@ -132,9 +132,6 @@ Options: - `options.coerce`: Enable data type [`coercion`](https://www.npmjs.com/package/ajv#coercing-data-types) - `options.htmlui`: Turn on serving `redoc` or `swagger-ui` html ui - `options.basePath`: When set, will strip the value of `basePath` from the start of every path. - - `options.customScripts`: an array of strings where you can pass in custom scripts which modify the appearance and/or functionality of the Swagger UI. - - `options.plugins`: If you have a custom script, you need to pass the name of the script in here (as an array of strings). - - The options object can also accept configuration parameters for Swagger and Redoc. The full list of Swagger and Redoc configuration options can be found here: https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/ and here: https://redocly.com/docs/redoc/config/ respectively. ##### Coerce @@ -285,11 +282,11 @@ Serve an interactive UI for exploring the OpenAPI document. [Redoc](https://github.com/Rebilly/ReDoc/) and [SwaggerUI](https://www.npmjs.com/package/swagger-ui) are two of the most popular tools for viewing OpenAPI documents and are bundled with the middleware. They are not turned on by default but can be with the option mentioned above or by using one -of these middleware. +of these middleware. Both interactive UIs also accept an optional object as a function argument which accepts configuration parameters for Swagger and Redoc. The full list of Swagger and Redoc configuration options can be found here: https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/ and here: https://redocly.com/docs/redoc/config/ respectively. **Example:** ```javascript -app.use('/redoc', oapi.redoc) -app.use('/swaggerui', oapi.swaggerui) +app.use('/redoc', oapi.redoc()) +app.use('/swaggerui', oapi.swaggerui()) ``` From 6e2a198da8a90c1385b641896a3c47d4e854b438 Mon Sep 17 00:00:00 2001 From: Seth Wheeler <23089578+Megapixel99@users.noreply.github.com> Date: Wed, 1 Nov 2023 17:37:04 -0500 Subject: [PATCH 5/5] hide `plugin` if there are no plugins --- lib/ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ui.js b/lib/ui.js index 78ef043..34e113a 100644 --- a/lib/ui.js +++ b/lib/ui.js @@ -36,7 +36,7 @@ module.exports.serveSwaggerUI = function serveSwaggerUI (documentUrl, opts = {}) window.ui = SwaggerUIBundle({ url: '${documentUrl}', dom_id: '#swagger-ui', - plugins: [${plugins}], + ${plugins?.length ? `plugins: [${plugins}],` : ''} ...${JSON.stringify(options)} }) }`