diff --git a/packages/explorer/.npmrc b/packages/explorer/.npmrc new file mode 100644 index 000000000000..43c97e719a5a --- /dev/null +++ b/packages/explorer/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/packages/explorer/LICENSE b/packages/explorer/LICENSE new file mode 100644 index 000000000000..3d49daf70323 --- /dev/null +++ b/packages/explorer/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) IBM Corp. 2018. All Rights Reserved. +Node module: @loopback/explorer +This project is licensed under the MIT License, full text below. + +-------- + +MIT license + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/explorer/README.md b/packages/explorer/README.md new file mode 100644 index 000000000000..86337fb86cad --- /dev/null +++ b/packages/explorer/README.md @@ -0,0 +1,27 @@ +# @loopback/explorer + +This module contains a handler to serve API Explorer + +## Installation + +```sh +npm install --save @loopback/explorer +``` + +## Contributions + +- [Guidelines](https://github.com/strongloop/loopback-next/blob/master/docs/CONTRIBUTING.md) +- [Join the team](https://github.com/strongloop/loopback-next/issues/110) + +## Tests + +Run `npm test` from the root folder. + +## Contributors + +See +[all contributors](https://github.com/strongloop/loopback-next/graphs/contributors). + +## License + +MIT diff --git a/packages/explorer/docs.json b/packages/explorer/docs.json new file mode 100644 index 000000000000..81a57a650369 --- /dev/null +++ b/packages/explorer/docs.json @@ -0,0 +1,7 @@ +{ + "content": [ + "index.ts", + "src/explorer.ts" + ], + "codeSectionDepth": 4 +} diff --git a/packages/explorer/index.d.ts b/packages/explorer/index.d.ts new file mode 100644 index 000000000000..880ff9799b52 --- /dev/null +++ b/packages/explorer/index.d.ts @@ -0,0 +1,6 @@ +// Copyright IBM Corp. 2018. All Rights Reserved. +// Node module: @loopback/explorer +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +export * from './dist8'; diff --git a/packages/explorer/index.js b/packages/explorer/index.js new file mode 100644 index 000000000000..512820ec0cdb --- /dev/null +++ b/packages/explorer/index.js @@ -0,0 +1,6 @@ +// Copyright IBM Corp. 2018. All Rights Reserved. +// Node module: @loopback/explorer +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +module.exports = require('@loopback/dist-util').loadDist(__dirname); diff --git a/packages/explorer/index.ts b/packages/explorer/index.ts new file mode 100644 index 000000000000..3a66043229fa --- /dev/null +++ b/packages/explorer/index.ts @@ -0,0 +1,8 @@ +// Copyright IBM Corp. 2018. All Rights Reserved. +// Node module: @loopback/explorer +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +// DO NOT EDIT THIS FILE +// Add any additional (re)exports to src/index.ts instead. +export * from './src'; diff --git a/packages/explorer/package.json b/packages/explorer/package.json new file mode 100644 index 000000000000..710f6fb1c27c --- /dev/null +++ b/packages/explorer/package.json @@ -0,0 +1,59 @@ +{ + "name": "@loopback/explorer", + "version": "0.1.0", + "description": "LoopBack's API Explorer", + "engines": { + "node": ">=8.9" + }, + "scripts": { + "build:all-dist": "npm run build:dist8 && npm run build:dist10", + "build:apidocs": "lb-apidocs", + "build": "lb-tsc", + "build:dist8": "lb-tsc es2017", + "build:dist10": "lb-tsc es2018", + "clean": "lb-clean loopback-explorer*.tgz dist* package api-docs", + "pretest": "npm run build", + "integration": "lb-mocha \"DIST/test/integration/**/*.js\"", + "test": "lb-mocha \"DIST/test/unit/**/*.js\" \"DIST/test/integration/**/*.js\"", + "unit": "lb-mocha \"DIST/test/unit/**/*.js\"", + "verify": "npm pack && tar xf loopback-explorer*.tgz && tree package && npm run clean" + }, + "author": "IBM", + "copyright.owner": "IBM Corp.", + "license": "MIT", + "dependencies": { + "@types/express": "^4.16.0", + "ejs": "^2.6.1", + "serve-static": "^1.13.2", + "swagger-ui-dist": "^3.18.2" + }, + "devDependencies": { + "@loopback/build": "^0.7.1", + "@loopback/dist-util": "^0.3.6", + "@loopback/testlab": "^0.11.5", + "@types/ejs": "^2.6.0", + "@types/node": "^10.1.1", + "@types/serve-static": "^1.13.2", + "express": "^4.16.3" + }, + "keywords": [ + "LoopBack", + "Explorer", + "Swagger" + ], + "files": [ + "README.md", + "index.js", + "index.d.ts", + "dist*/src", + "dist*/index*", + "src" + ], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/strongloop/loopback-next.git" + } +} diff --git a/packages/explorer/src/explorer.ts b/packages/explorer/src/explorer.ts new file mode 100644 index 000000000000..eb63a5bc46d2 --- /dev/null +++ b/packages/explorer/src/explorer.ts @@ -0,0 +1,64 @@ +// Copyright IBM Corp. 2018. All Rights Reserved. +// Node module: @loopback/explorer +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +const swaggerUI = require('swagger-ui-dist'); + +import * as path from 'path'; +import * as fs from 'fs'; + +import {Handler} from 'express'; +import * as serveStatic from 'serve-static'; +import * as ejs from 'ejs'; + +/** + * Options to configure API Explorer UI + */ +export type ApiExplorerUIOptions = { + /** + * URL to the OpenAPI spec + */ + openApiSpecUrl?: string; + + /** + * Custom EJS template for index.html + */ + indexHtmlTemplate?: string; + + /** + * Options for serve-static middleware + */ + serveStaticOptions?: serveStatic.ServeStaticOptions; +}; + +/** + * Mount the API Explorer UI (swagger-ui) to the given express router + * @param options + */ +export function apiExplorerUI(options: ApiExplorerUIOptions = {}): Handler { + const openApiSpecUrl = options.openApiSpecUrl || '/openapi.json'; + const indexHtml = + options.indexHtmlTemplate || path.resolve(__dirname, './index.html.ejs'); + const template = fs.readFileSync(indexHtml, 'utf-8'); + const templateFn = ejs.compile(template); + const uiHandler = serveStatic( + swaggerUI.getAbsoluteFSPath(), + options.serveStaticOptions, + ); + + return (req, res, next) => { + if (req.path === '/' || req.path === '/index.html') { + const data = { + openApiSpecUrl, + }; + const homePage = templateFn(data); + res + .status(200) + .contentType('text/html') + .send(homePage); + } else { + uiHandler(req, res, next); + } + }; +} diff --git a/packages/explorer/src/index.html.ejs b/packages/explorer/src/index.html.ejs new file mode 100644 index 000000000000..28ceaf371838 --- /dev/null +++ b/packages/explorer/src/index.html.ejs @@ -0,0 +1,64 @@ + + + + +
+ +