diff --git a/bookshop/package.json b/bookshop/package.json index ff55612a..e7125251 100644 --- a/bookshop/package.json +++ b/bookshop/package.json @@ -5,15 +5,13 @@ "dependencies": { "@capire/common": "*", "@sap/cds": "^5.0.4", - "cors": "^2.8.5", "express": "^4.17.1", "passport": "0.4.1" }, "scripts": { "genres": "cds serve test/genres.cds", "start": "cds run", - "watch": "cds watch", - "to-openapi": "cds compile srv --to openapi -s all -o srv --openapi:diagram" + "watch": "cds watch" }, "cds": { "requires": { diff --git a/bookshop/server.js b/bookshop/server.js deleted file mode 100644 index c8a91310..00000000 --- a/bookshop/server.js +++ /dev/null @@ -1,68 +0,0 @@ -// Serves a Swagger UI with API definitions either created on the fly -// or loaded from file system. -// -// Needs @sap/cds-dk >= 3.3.0 installed - -const {resolve} = require ('path') -const {promisify} = require('util') -const readFile = promisify(require('fs').readFile) -const swaggerUi = require ('swagger-ui-express') -const cds = require ('@sap/cds') -const cors = require('cors') - -const debug = cds.debug('openapi') -let app, docCache={} - -cds - .on ('bootstrap', _app => { - app = _app - app.use(cors()) // allow to be called from e.g. editor.swagger.io - }) - .on ('serving', service => { - const apiPath = '/api-docs'+service.path - console.log (`[Open API] - serving ${service.name} at ${apiPath}`) - app.use(apiPath, async (req, _, next) => { - req.swaggerDoc = await toOpenApiDoc(service, docCache) - next() - }, swaggerUi.serve, swaggerUi.setup()) - addLinkToIndexHtml(service, apiPath) - }) - -async function toOpenApiDoc(service, cache) { - if (!cache[service.name]) { - const spec = await openApiFromFile(service) - if (spec) { // pre-compiled spec file available? - cache[service.name] = spec - } - // On-the-fly exporter available? Needs @sap/cds-dk >= 3.3.0 - else if (cds.compile.to.openapi) { - debug && debug ('Compiling Open API spec for', service.name) - cache[service.name] = cds.compile.to.openapi (service.model, { - service: service.name, - 'openapi:url': service.path, - 'openapi:diagram': true - }) - } - } - return cache[service.name] -} - -async function openApiFromFile(service) { - const fileName = resolve(`srv/${service.name}.openapi3.json`) - const file = await readFile(fileName).catch(()=>{/*no such file*/}) - if (file) { - debug && debug ('Using Open API spec from file', fileName) - return JSON.parse(file) - } -} - -function addLinkToIndexHtml(service, apiPath) { - const provider = (entity) => { - if (entity) return // avoid link on entity level, looks too messy - return { href:apiPath, name:'Swagger UI', title:'Show in Swagger UI' } - } - // Needs @sap/cds >= 4.4.0 - service.$linkProviders ? service.$linkProviders.push(provider) : service.$linkProviders = [provider] -} - -module.exports = cds.server diff --git a/fiori/server.js b/fiori/server.js index a8dc4298..0a7f34ed 100644 --- a/fiori/server.js +++ b/fiori/server.js @@ -1,4 +1,5 @@ const cds = require ('@sap/cds') +module.exports = cds.server cds.once('bootstrap',(app)=>{ app.use ('/orders/webapp', _from('@capire/orders/app/orders/webapp/manifest.json')) @@ -8,7 +9,11 @@ cds.once('bootstrap',(app)=>{ cds.once('served', require('./srv/mashup')) -module.exports = cds.server +// Swagger UI - see https://cap.cloud.sap/docs/advanced/openapi +if (process.env.NODE_ENV !== 'production') { + const cds_swagger = require ('cds-swagger-ui-express') + cds.once ('bootstrap', app => app.use (cds_swagger()) ) +} // ----------------------------------------------------------------------- diff --git a/package.json b/package.json index a756611e..a1f077cf 100644 --- a/package.json +++ b/package.json @@ -14,11 +14,11 @@ "@capire/reviews": "./reviews" }, "devDependencies": { + "cds-swagger-ui-express": "^0.1.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "chai-subset": "^1.6.0", - "sqlite3": "^5.0.0", - "swagger-ui-express": "^4.1.4" + "sqlite3": "^5.0.0" }, "scripts": { "cleanup": "rm -rf node_modules && rm -rf */node_modules && rm -rf */*/node_modules", diff --git a/samples.md b/samples.md index cf9a60b4..516d3fa6 100644 --- a/samples.md +++ b/samples.md @@ -63,6 +63,7 @@ Each sub directory essentially is an individual npm package arranged in an [all- - Support for [Value Helps](https://cap.cloud.sap/docs/guides/fiori#value-help) - Serving SAP Fiori apps locally - [The Vue.js app](bookshop/app/vue) imported from bookshop is served as well +- [OpenAPI export + Swagger UI](https://cap.cloud.sap/docs/advanced/openapi)