diff --git a/api/measurement.yaml b/api/measurement.yaml index 84e6237..53fe973 100644 --- a/api/measurement.yaml +++ b/api/measurement.yaml @@ -76,6 +76,7 @@ post: summary: TODO add measurement description: 'Auth: basic, levels: write, maintain, dev, admin' + x-doc: 'Adds status: 0 automatically' tags: - /measurement security: diff --git a/src/api.ts b/src/api.ts new file mode 100644 index 0000000..77a60ca --- /dev/null +++ b/src/api.ts @@ -0,0 +1,42 @@ +import swagger from 'swagger-ui-express'; +import jsonRefParser, {JSONSchema} from '@apidevtools/json-schema-ref-parser'; + + +// modifies the normal swagger-ui-express package +// usage: app.use('/api', 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 class api { + static serve () { + return swagger.serve; + } + + static setup () { + let apiDoc: JSONSchema = {}; + jsonRefParser.bundle('api/api.yaml', (err, doc) => { // parse yaml + if(err) throw err; + apiDoc = doc; + apiDoc.paths = apiDoc.paths.allOf.reduce((s, e) => Object.assign(s, e)); // bundle routes + apiDoc = this.resolveXDoc(apiDoc); + swagger.setup(apiDoc); + }); + return swagger.setup(apiDoc, {customCssUrl: '/static/styles/swagger.css'}) + } + + private static resolveXDoc (doc) { // resolve x-doc properties recursively + Object.keys(doc).forEach(key => { + if (doc[key] !== null && doc[key].hasOwnProperty('x-doc')) { + doc[key].description += this.addHtml(doc[key]['x-doc']); + } + else if (typeof doc[key] === 'object' && doc[key] !== null) { // go deeper into recursion + doc[key] = this.resolveXDoc(doc[key]); + } + }); + return doc; + } + + private static addHtml (text) { // add docs HTML + return '
docs' + text + '
'; + } +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 4c0beca..fc1b149 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,8 @@ import express from 'express'; import bodyParser from 'body-parser'; -import swagger from 'swagger-ui-express'; -import jsonRefParser, {JSONSchema} from '@apidevtools/json-schema-ref-parser'; import contentFilter from 'content-filter'; import mongoSanitize from 'mongo-sanitize'; +import api from './api'; import db from './db'; @@ -56,14 +55,7 @@ app.use('/', require('./routes/measurement')); app.use('/static', express.static('static')); // Swagger UI -let apiDoc: JSONSchema = {}; -jsonRefParser.bundle('api/api.yaml', (err, doc) => { - if(err) throw err; - apiDoc = doc; - apiDoc.paths = apiDoc.paths.allOf.reduce((s, e) => Object.assign(s, e)); - swagger.setup(apiDoc, {defaultModelsExpandDepth: -1, customCss: '.swagger-ui .topbar { display: none }'}); -}); -app.use('/api', swagger.serve, swagger.setup(apiDoc, {customCssUrl: '/static/styles/swagger.css'})); +app.use('/api', api.serve(), api.setup()); app.use((req, res) => { // 404 error handling res.status(404).json({status: 'Not found'}); diff --git a/static/styles/swagger.css b/static/styles/swagger.css index 33bebe1..9760ed4 100644 --- a/static/styles/swagger.css +++ b/static/styles/swagger.css @@ -52,6 +52,23 @@ body:after { font-family: "Bosch Sans", sans-serif; } +/*custom docs*/ +.docs { + position: relative; + font-size: 14px; +} + +.docs > summary { + position: absolute; + right: 0; + top: -25px; + cursor: pointer; +} + +.docs-open:hover { + text-decoration: underline; +} + /*Remove topbar*/ .swagger-ui .topbar { display: none