2020-05-12 14:05:47 +02:00
|
|
|
import swagger from 'swagger-ui-express';
|
|
|
|
import jsonRefParser, {JSONSchema} from '@apidevtools/json-schema-ref-parser';
|
2020-05-13 17:28:18 +02:00
|
|
|
import oasParser from '@apidevtools/swagger-parser';
|
2020-05-12 14:05:47 +02:00
|
|
|
|
|
|
|
|
|
|
|
// modifies the normal swagger-ui-express package
|
2020-05-26 09:07:01 +02:00
|
|
|
// usage: app.use('/api-doc', api.serve(), api.setup());
|
2020-05-12 14:05:47 +02:00
|
|
|
// the paths property can be split using allOf
|
|
|
|
// further route documentation can be included in the x-doc property
|
|
|
|
|
|
|
|
export default class api {
|
|
|
|
static serve () {
|
|
|
|
return swagger.serve;
|
|
|
|
}
|
|
|
|
|
|
|
|
static setup () {
|
|
|
|
let apiDoc: JSONSchema = {};
|
|
|
|
jsonRefParser.bundle('api/api.yaml', (err, doc) => { // parse yaml
|
2020-06-05 10:51:03 +02:00
|
|
|
if (err) throw err;
|
2020-05-12 14:05:47 +02:00
|
|
|
apiDoc = doc;
|
2020-07-09 13:48:27 +02:00
|
|
|
apiDoc.servers.splice(process.env.NODE_ENV === 'production', 1);
|
2020-05-12 14:05:47 +02:00
|
|
|
apiDoc.paths = apiDoc.paths.allOf.reduce((s, e) => Object.assign(s, e)); // bundle routes
|
|
|
|
apiDoc = this.resolveXDoc(apiDoc);
|
2020-05-18 14:47:22 +02:00
|
|
|
oasParser.validate(apiDoc, (err, api) => { // validate oas schema
|
2020-05-13 17:28:18 +02:00
|
|
|
if (err) {
|
|
|
|
console.error(err);
|
|
|
|
}
|
|
|
|
else {
|
2020-05-14 12:31:57 +02:00
|
|
|
console.info(process.env.NODE_ENV === 'test' ? '' : 'API ok, version ' + api.info.version);
|
2020-05-13 17:28:18 +02:00
|
|
|
swagger.setup(apiDoc);
|
|
|
|
}
|
|
|
|
});
|
2020-05-12 14:05:47 +02:00
|
|
|
});
|
|
|
|
return swagger.setup(apiDoc, {customCssUrl: '/static/styles/swagger.css'})
|
|
|
|
}
|
|
|
|
|
|
|
|
private static resolveXDoc (doc) { // resolve x-doc properties recursively
|
|
|
|
Object.keys(doc).forEach(key => {
|
2020-05-18 14:47:22 +02:00
|
|
|
if (doc[key] !== null && doc[key].hasOwnProperty('x-doc')) { // add x-doc to description, is styled via css
|
|
|
|
doc[key].description += '<details class="docs"><summary>docs</summary>' + doc[key]['x-doc'] + '</details>';
|
2020-05-12 14:05:47 +02:00
|
|
|
}
|
|
|
|
else if (typeof doc[key] === 'object' && doc[key] !== null) { // go deeper into recursion
|
|
|
|
doc[key] = this.resolveXDoc(doc[key]);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return doc;
|
|
|
|
}
|
|
|
|
}
|