import express from 'express';
import swaggerUi from 'swagger-ui-dist';
import jsonRefParser, {JSONSchema} from '@apidevtools/json-schema-ref-parser';
import oasParser from '@apidevtools/swagger-parser';
// modified from https://github.com/scottie1984/swagger-ui-express
// usage: app.use('/api-doc', api.serve(), api.setup());
// the paths property can be split using allOf
// further route documentation can be included in the x-doc property
export default function api () {
// generate apiDoc
let apiDoc: JSONSchema = {};
jsonRefParser.bundle('api/api.yaml', (err, doc) => { // parse yaml
if (err) throw err;
apiDoc = doc;
apiDoc.servers.splice(process.env.NODE_ENV === 'production', 1);
apiDoc.paths = apiDoc.paths.allOf.reduce((s, e) => Object.assign(s, e)); // bundle routes
apiDoc = resolveXDoc(apiDoc);
oasParser.validate(apiDoc, (err, api) => { // validate oas schema
if (err) {
console.error(err);
}
else {
console.info(process.env.NODE_ENV === 'test' ? '' : 'API ok, version ' + api.info.version);
}
});
});
return [
(req, res, next) => { // serve init js and apiDoc file
switch (req.url) {
case '/swagger-ui-init.js':
res.set('Content-Type', 'application/javascript');
res.send(jsTplString);
break;
case '/apidoc.json':
res.set('Content-Type', 'application/json');
res.send(apiDoc);
break;
default:
next();
}
}, // serve swagger files
express.static(swaggerUi.getAbsoluteFSPath(), {index: false}),
(req, res) => { // serve html file as default
res.send(htmlTplString);
}
];
}
function resolveXDoc (doc) { // resolve x-doc properties recursively
Object.keys(doc).forEach(key => {
if (doc[key] !== null && doc[key].hasOwnProperty('x-doc')) { // add x-doc to description, is styled via css
doc[key].description += 'docs
' + doc[key]['x-doc'] + '