Merge pull request #104 from strongloop/feature/refactor-as-component
[SEMVER-MAJOR] Rework the module to a loopback component
This commit is contained in:
commit
75ea3f928a
40
README.md
40
README.md
|
@ -16,13 +16,43 @@ var Product = loopback.Model.extend('product');
|
|||
Product.attachTo(loopback.memory());
|
||||
app.model(Product);
|
||||
|
||||
app.use('/explorer', explorer(app, {basePath: '/api'}));
|
||||
app.use('/api', loopback.rest());
|
||||
|
||||
// Register explorer using component-centric API:
|
||||
explorer(app, { basePath: '/api', mountPath: '/explorer' });
|
||||
// Alternatively, register as a middleware:
|
||||
app.use('/explorer', explorer.routes(app, { basePath: '/api' }));
|
||||
|
||||
console.log("Explorer mounted at localhost:" + port + "/explorer");
|
||||
|
||||
app.listen(port);
|
||||
```
|
||||
|
||||
## Upgrading from v1.x
|
||||
|
||||
To upgrade your application using loopback-explorer version 1.x, just replace
|
||||
`explorer()` with `explorer.routes()` in your server script:
|
||||
|
||||
```js
|
||||
var explorer = require('loopback-explorer');
|
||||
|
||||
// v1.x - does not work anymore
|
||||
app.use('/explorer', explorer(app, options);
|
||||
// v2.x
|
||||
app.use('/explorer', explorer.routes(app, options));
|
||||
```
|
||||
|
||||
In applications scaffolded by `slc loopback`, the idiomatic way is to register
|
||||
loopback-explorer via `component-config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"loopback-explorer": {
|
||||
"mountPath": "/explorer"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
Many aspects of the explorer are configurable.
|
||||
|
@ -32,7 +62,7 @@ See [options](#options) for a description of these options:
|
|||
```js
|
||||
// Mount middleware before calling `explorer()` to add custom headers, auth, etc.
|
||||
app.use('/explorer', loopback.basicAuth('user', 'password'));
|
||||
app.use('/explorer', explorer(app, {
|
||||
explorer(app, {
|
||||
basePath: '/custom-api-root',
|
||||
uiDirs: [
|
||||
path.resolve(__dirname, 'public'),
|
||||
|
@ -60,6 +90,12 @@ Options are passed to `explorer(app, options)`.
|
|||
> to a path different than '/api', e.g. with
|
||||
> `loopback.use('/custom-api-root', loopback.rest());
|
||||
|
||||
`mountPath`: **String**
|
||||
|
||||
> Default: `/explorer`
|
||||
|
||||
> Set the path where to mount the explorer component.
|
||||
|
||||
`protocol`: **String**
|
||||
|
||||
> Default: `null`
|
||||
|
|
37
index.js
37
index.js
|
@ -6,35 +6,46 @@ var url = require('url');
|
|||
var path = require('path');
|
||||
var urlJoin = require('./lib/url-join');
|
||||
var _defaults = require('lodash').defaults;
|
||||
var express = require('express');
|
||||
var swagger = require('./lib/swagger');
|
||||
var SWAGGER_UI_ROOT = require('strong-swagger-ui').dist;
|
||||
var STATIC_ROOT = path.join(__dirname, 'public');
|
||||
|
||||
module.exports = explorer;
|
||||
explorer.routes = routes;
|
||||
|
||||
/**
|
||||
* Example usage:
|
||||
*
|
||||
* var explorer = require('loopback-explorer');
|
||||
* app.use('/explorer', explorer(app, options));
|
||||
* explorer(app, options);
|
||||
*/
|
||||
|
||||
function explorer(loopbackApplication, options) {
|
||||
var mountPath = options.mountPath || '/explorer';
|
||||
loopbackApplication.use(mountPath, routes(loopbackApplication, options));
|
||||
}
|
||||
|
||||
function routes(loopbackApplication, options) {
|
||||
var loopback = loopbackApplication.loopback;
|
||||
var loopbackMajor = loopback && loopback.version &&
|
||||
loopback.version.split('.')[0] || 1;
|
||||
|
||||
if (loopbackMajor < 2) {
|
||||
throw new Error('loopback-explorer requires loopback 2.0 or newer');
|
||||
}
|
||||
|
||||
options = _defaults({}, options, {
|
||||
resourcePath: 'resources',
|
||||
apiInfo: loopbackApplication.get('apiInfo') || {}
|
||||
});
|
||||
|
||||
var app = express();
|
||||
var router = new loopback.Router();
|
||||
|
||||
swagger(loopbackApplication, app, options);
|
||||
|
||||
app.disable('x-powered-by');
|
||||
swagger(loopbackApplication, router, options);
|
||||
|
||||
// config.json is loaded by swagger-ui. The server should respond
|
||||
// with the relative URI of the resource doc.
|
||||
app.get('/config.json', function(req, res) {
|
||||
router.get('/config.json', function(req, res) {
|
||||
// Get the path we're mounted at. It's best to get this from the referer
|
||||
// in case we're proxied at a deep path.
|
||||
var source = url.parse(req.headers.referer || '').pathname;
|
||||
|
@ -53,10 +64,10 @@ function explorer(loopbackApplication, options) {
|
|||
// to worry about constantly pulling in JS updates.
|
||||
if (options.uiDirs) {
|
||||
if (typeof options.uiDirs === 'string') {
|
||||
app.use(express.static(options.uiDirs));
|
||||
router.use(loopback.static(options.uiDirs));
|
||||
} else if (Array.isArray(options.uiDirs)) {
|
||||
options.uiDirs.forEach(function(dir) {
|
||||
app.use(express.static(dir));
|
||||
router.use(loopback.static(dir));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -64,14 +75,14 @@ function explorer(loopbackApplication, options) {
|
|||
if (options.swaggerDistRoot) {
|
||||
console.warn('loopback-explorer: `swaggerDistRoot` is deprecated,' +
|
||||
' use `uiDirs` instead');
|
||||
app.use(express.static(options.swaggerDistRoot));
|
||||
router.use(loopback.static(options.swaggerDistRoot));
|
||||
}
|
||||
|
||||
// File in node_modules are overridden by a few customizations
|
||||
app.use(express.static(STATIC_ROOT));
|
||||
router.use(loopback.static(STATIC_ROOT));
|
||||
|
||||
// Swagger UI distribution
|
||||
app.use(express.static(SWAGGER_UI_ROOT));
|
||||
router.use(loopback.static(SWAGGER_UI_ROOT));
|
||||
|
||||
return app;
|
||||
return router;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
"dependencies": {
|
||||
"cors": "^2.7.1",
|
||||
"debug": "^2.2.0",
|
||||
"express": "4.x",
|
||||
"lodash": "^3.10.0",
|
||||
"strong-swagger-ui": "^20.0.2"
|
||||
}
|
||||
|
|
|
@ -106,9 +106,9 @@ describe('explorer', function() {
|
|||
var app;
|
||||
beforeEach(function setupExplorerWithUiDirs() {
|
||||
app = loopback();
|
||||
app.use('/explorer', explorer(app, {
|
||||
explorer(app, {
|
||||
uiDirs: [ path.resolve(__dirname, 'fixtures', 'dummy-swagger-ui') ]
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
it('overrides swagger-ui files', function(done) {
|
||||
|
@ -128,6 +128,27 @@ describe('explorer', function() {
|
|||
});
|
||||
});
|
||||
|
||||
describe('explorer.routes API', function() {
|
||||
var app;
|
||||
beforeEach(function() {
|
||||
app = loopback();
|
||||
var Product = loopback.PersistedModel.extend('product');
|
||||
Product.attachTo(loopback.memory());
|
||||
app.model(Product);
|
||||
});
|
||||
|
||||
it('creates explorer routes', function(done) {
|
||||
app.use('/explorer', explorer.routes(app));
|
||||
app.use(app.get('restApiRoot') || '/', loopback.rest());
|
||||
|
||||
request(app)
|
||||
.get('/explorer/config.json')
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
.end(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when specifying custom static file root directories', function() {
|
||||
var app;
|
||||
beforeEach(function() {
|
||||
|
@ -135,9 +156,9 @@ describe('explorer', function() {
|
|||
});
|
||||
|
||||
it('should allow `uiDirs` to be defined as an Array', function(done) {
|
||||
app.use('/explorer', explorer(app, {
|
||||
explorer(app, {
|
||||
uiDirs: [ path.resolve(__dirname, 'fixtures', 'dummy-swagger-ui') ]
|
||||
}));
|
||||
});
|
||||
|
||||
request(app).get('/explorer/')
|
||||
.expect(200)
|
||||
|
@ -147,9 +168,9 @@ describe('explorer', function() {
|
|||
});
|
||||
|
||||
it('should allow `uiDirs` to be defined as an String', function(done) {
|
||||
app.use('/explorer', explorer(app, {
|
||||
explorer(app, {
|
||||
uiDirs: path.resolve(__dirname, 'fixtures', 'dummy-swagger-ui')
|
||||
}));
|
||||
});
|
||||
|
||||
request(app).get('/explorer/')
|
||||
.expect(200)
|
||||
|
@ -172,7 +193,7 @@ describe('explorer', function() {
|
|||
Product.attachTo(loopback.memory());
|
||||
app.model(Product);
|
||||
|
||||
app.use(explorerBase || '/explorer', explorer(app));
|
||||
explorer(app, { mountPath: explorerBase });
|
||||
app.use(app.get('restApiRoot') || '/', loopback.rest());
|
||||
}
|
||||
});
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
var url = require('url');
|
||||
var urlJoin = require('../lib/url-join');
|
||||
var loopback = require('loopback');
|
||||
var express = require('express');
|
||||
var swagger = require('../lib/swagger');
|
||||
|
||||
var request = require('supertest');
|
||||
|
@ -387,7 +386,7 @@ describe('swagger definition', function() {
|
|||
}
|
||||
|
||||
function mountExplorer(app, options) {
|
||||
var swaggerApp = express();
|
||||
var swaggerApp = loopback();
|
||||
swagger(app, swaggerApp, options);
|
||||
app.use(app.get('explorerRoot') || '/explorer', swaggerApp);
|
||||
return app;
|
||||
|
|
Loading…
Reference in New Issue