'use strict' var express = require('express') var getAbsoluteSwaggerFsPath = require('swagger-ui-dist/absolute-path') var favIconHtml = '' + '' var swaggerInit = '' function trimQuery(q) { return q && q.split('?')[0] } var htmlTplString = ` <% robotsMetaString %> <% title %> <% favIconString %>
<% customJs %> <% customJsStr %> <% customCssUrl %> ` var jsTplString = ` window.onload = function() { // Build a system var url = window.location.search.match(/url=([^&]+)/); if (url && url.length > 1) { url = decodeURIComponent(url[1]); } else { url = window.location.origin; } <% swaggerOptions %> url = options.swaggerUrl || url var urls = options.swaggerUrls var customOptions = options.customOptions var spec1 = options.swaggerDoc var swaggerOptions = { spec: spec1, url: url, urls: urls, dom_id: '#swagger-ui', deepLinking: true, presets: [ SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset ], plugins: [ SwaggerUIBundle.plugins.DownloadUrl ], layout: "StandaloneLayout" } for (var attrname in customOptions) { swaggerOptions[attrname] = customOptions[attrname]; } var ui = SwaggerUIBundle(swaggerOptions) if (customOptions.oauth) { ui.initOAuth(customOptions.oauth) } if (customOptions.preauthorizeApiKey) { const key = customOptions.preauthorizeApiKey.authDefinitionKey; const value = customOptions.preauthorizeApiKey.apiKeyValue; if (!!key && !!value) { const pid = setInterval(() => { const authorized = ui.preauthorizeApiKey(key, value); if(!!authorized) clearInterval(pid); }, 500) } } if (customOptions.authAction) { ui.authActions.authorize(customOptions.authAction) } window.ui = ui } ` function toExternalScriptTag(url) { return `` } function toInlineScriptTag(jsCode) { return `` } function toExternalStylesheetTag(url) { return `` } function toTags(customCode, toScript) { if (typeof customCode === 'string') { return toScript(customCode) } else if (Array.isArray(customCode)) { return customCode.map(toScript).join('\n') } else { return '' } } var generateHTML = function (swaggerDoc, opts, options, customCss, customfavIcon, swaggerUrl, customSiteTitle, _htmlTplString, _jsTplString) { var isExplorer var customJs var customJsStr var swaggerUrls var customCssUrl var customRobots if (opts && typeof opts === 'object') { options = opts.swaggerOptions customCss = opts.customCss customJs = opts.customJs customJsStr = opts.customJsStr customfavIcon = opts.customfavIcon customRobots = opts.customRobots swaggerUrl = opts.swaggerUrl swaggerUrls = opts.swaggerUrls isExplorer = opts.explorer || !!swaggerUrls customSiteTitle = opts.customSiteTitle customCssUrl = opts.customCssUrl } else { //support legacy params based function isExplorer = opts } options = options || {} var explorerString = isExplorer ? '' : '.swagger-ui .topbar .download-url-wrapper { display: none }' customCss = explorerString + ' ' + customCss || explorerString customfavIcon = customfavIcon || false customSiteTitle = customSiteTitle || 'Swagger UI' _htmlTplString = _htmlTplString || htmlTplString _jsTplString = _jsTplString || jsTplString var robotsMetaString = customRobots ? '' : '' var favIconString = customfavIcon ? '' : favIconHtml var htmlWithCustomCss = _htmlTplString.toString().replace('<% customCss %>', customCss) var htmlWithCustomRobots = htmlWithCustomCss.replace('<% robotsMetaString %>', robotsMetaString) var htmlWithFavIcon = htmlWithCustomRobots.replace('<% favIconString %>', favIconString) var htmlWithCustomJsUrl = htmlWithFavIcon.replace('<% customJs %>', toTags(customJs, toExternalScriptTag)) var htmlWithCustomJs = htmlWithCustomJsUrl.replace('<% customJsStr %>', toTags(customJsStr, toInlineScriptTag)) var htmlWithCustomCssUrl = htmlWithCustomJs.replace('<% customCssUrl %>', toTags(customCssUrl, toExternalStylesheetTag)) var initOptions = { swaggerDoc: swaggerDoc || undefined, customOptions: options, swaggerUrl: swaggerUrl || undefined, swaggerUrls: swaggerUrls || undefined } swaggerInit = _jsTplString.toString().replace('<% swaggerOptions %>', stringify(initOptions)) return htmlWithCustomCssUrl.replace('<% title %>', customSiteTitle) } var setup = function (swaggerDoc, opts, options, customCss, customfavIcon, swaggerUrl, customSiteTitle) { var html = generateHTML(swaggerDoc, opts, options, customCss, customfavIcon, swaggerUrl, customSiteTitle, htmlTplString, jsTplString) return function (req, res) { if (req.swaggerDoc) { var reqHtml = generateHTML(req.swaggerDoc, opts, options, customCss, customfavIcon, swaggerUrl, customSiteTitle, htmlTplString, jsTplString) res.send(reqHtml) } else { res.send(html) } } } function swaggerInitFn(req, res, next) { if (trimQuery(req.url).endsWith('/package.json')) { res.sendStatus(404) } else if (trimQuery(req.url).endsWith('/swagger-ui-init.js')) { res.set('Content-Type', 'application/javascript') res.send(swaggerInit) } else { next() } } var swaggerInitFunction = function (swaggerDoc, opts) { var swaggerInitFile = jsTplString.toString().replace('<% swaggerOptions %>', stringify(opts)) return function (req, res, next) { if (trimQuery(req.url).endsWith('/package.json')) { res.sendStatus(404) } else if (trimQuery(req.url).endsWith('/swagger-ui-init.js')) { if (req.swaggerDoc) { opts.swaggerDoc = req.swaggerDoc swaggerInitFile = jsTplString.toString().replace('<% swaggerOptions %>', stringify(opts)) } res.set('Content-Type', 'application/javascript') res.send(swaggerInitFile) } else { next() } } } var swaggerAssetMiddleware = options => { var opts = options || {} opts.index = false return express.static(getAbsoluteSwaggerFsPath(), opts) } var serveFiles = function (swaggerDoc, opts) { opts = opts || {} var initOptions = { swaggerDoc: swaggerDoc || undefined, customOptions: opts.swaggerOptions || {}, swaggerUrl: opts.swaggerUrl || {}, swaggerUrls: opts.swaggerUrls || undefined } var swaggerInitWithOpts = swaggerInitFunction(swaggerDoc, initOptions) return [swaggerInitWithOpts, swaggerAssetMiddleware()] } var serve = [swaggerInitFn, swaggerAssetMiddleware()] var serveWithOptions = options => [swaggerInitFn, swaggerAssetMiddleware(options)] var stringify = function (obj, prop) { var placeholder = '____FUNCTIONPLACEHOLDER____' var fns = [] var json = JSON.stringify(obj, function (key, value) { if (typeof value === 'function') { fns.push(value) return placeholder } return value }, 2) json = json.replace(new RegExp('"' + placeholder + '"', 'g'), function (_) { return fns.shift() }) return 'var options = ' + json + ';' } module.exports = { setup: setup, serve: serve, serveWithOptions: serveWithOptions, generateHTML: generateHTML, serveFiles: serveFiles }