forked from chgeo/cds-swagger-ui-express
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
47 lines (41 loc) · 1.5 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
const cds = require ('@sap/cds-dk')
const swaggerUi = require('swagger-ui-express')
const express = require('express')
module.exports = (options={}) => {
options = Object.assign({ basePath:'/$api-docs' }, options)
const router = express.Router()
cds.on ('serving', service => {
if (!isOData (service)) return
const apiPath = options.basePath+service.path
const mount = apiPath.replace('$','[\\$]')
console.log ('[cds] - serving Swagger UI for ', {service: service.name, at: apiPath})
router.use(mount, (req, _, next) => {
req.swaggerDoc = toOpenApiDoc(service, options)
next()
}, swaggerUi.serve, swaggerUi.setup())
addLinkToIndexHtml(service, apiPath)
})
return router
}
const cache={}
function toOpenApiDoc(service, options={}) {
if (!cache[service.name]) {
cache[service.name] = cds.compile.to.openapi (service.model, {
service: service.name,
'openapi:url': service.path,
'openapi:diagram': ('diagram' in options ? options.diagram : true)
})
}
return cache[service.name]
}
function addLinkToIndexHtml(service, apiPath) {
const provider = (entity) => {
if (entity) return // avoid link on entity level, looks too messy
return { href:apiPath, name:'Open API', title:'Show in Swagger UI' }
}
service.$linkProviders ? service.$linkProviders.push(provider) : service.$linkProviders = [provider]
}
function isOData(service) {
return Object.keys(service._adapters) .find (a => a.startsWith ('odata'))
}
/* eslint no-console:off */