Add an option `uiDirs`

The `uiDirs` option allows users to provide their own set of directories
with UI files, e.g. to provide a custom swagger-ui fork and a custom
set of style/font overrides:

    explorer(app, {
      uiDirs: [
        path.resolve(__dirname, 'public'),
        path.resolve(__dirname, 'node_modules', 'swagger-ui')
      ]
    });

The existing option `swaggerDistRoot` is deprecated now.
This commit is contained in:
Miroslav Bajtoš 2014-10-22 10:55:25 +02:00
parent d18d64b41d
commit 2ec096a278
5 changed files with 55 additions and 13 deletions

View File

@ -25,7 +25,7 @@ app.listen(port);
## Advanced Usage ## Advanced Usage
Many aspects of the explorer are configurable. Many aspects of the explorer are configurable.
See [options](#options) for a description of these options: See [options](#options) for a description of these options:
@ -34,7 +34,10 @@ See [options](#options) for a description of these options:
app.use('/explorer', loopback.basicAuth('user', 'password')); app.use('/explorer', loopback.basicAuth('user', 'password'));
app.use('/explorer', explorer(app, { app.use('/explorer', explorer(app, {
basePath: '/custom-api-root', basePath: '/custom-api-root',
swaggerDistRoot: '/swagger', uiDirs: [
path.resolve(__dirname, 'public'),
path.resolve(__dirname, 'node_modules', 'swagger-ui')
]
apiInfo: { apiInfo: {
'title': 'My API', 'title': 'My API',
'description': 'Explorer example app.' 'description': 'Explorer example app.'
@ -67,27 +70,27 @@ Options are passed to `explorer(app, options)`.
> and thus needs to report its endpoints as `https`, even though incoming traffic is auto-detected > and thus needs to report its endpoints as `https`, even though incoming traffic is auto-detected
> as `http`. > as `http`.
`swaggerDistRoot`: **String** `uiDirs`: **Array of Strings**
> Sets a path within your application for overriding Swagger UI files. > Sets a list of paths within your application for overriding Swagger UI files.
> If present, will search `swaggerDistRoot` first when attempting to load Swagger UI, allowing > If present, will search `uiDirs` first when attempting to load Swagger UI,
> you to pick and choose overrides to the interface. Use this to style your explorer or > allowing you to pick and choose overrides to the interface. Use this to
> add additional functionality. > style your explorer or add additional functionality.
> See [index.html](public/index.html), where you may want to begin your overrides. > See [index.html](public/index.html), where you may want to begin your overrides.
> The rest of the UI is provided by [Swagger UI](https://github.com/wordnik/swagger-ui). > The rest of the UI is provided by [Swagger UI](https://github.com/wordnik/swagger-ui).
`apiInfo`: **Object** `apiInfo`: **Object**
> Additional information about your API. See the > Additional information about your API. See the
> [spec](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#513-info-object). > [spec](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#513-info-object).
`resourcePath`: **String** `resourcePath`: **String**
> Default: `'resources'` > Default: `'resources'`
> Sets a different path for the > Sets a different path for the
> [resource listing](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#51-resource-listing). > [resource listing](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#51-resource-listing).
> You generally shouldn't have to change this. > You generally shouldn't have to change this.

View File

@ -47,15 +47,25 @@ function explorer(loopbackApplication, options) {
}); });
}); });
// Allow specifying a static file root for swagger files. Any files in // Allow specifying a static file roots for swagger files. Any files in
// that folder will override those in the swagger-ui distribution. // these folders will override those in the swagger-ui distribution.
// In this way one could e.g. make changes to index.html without having // In this way one could e.g. make changes to index.html without having
// to worry about constantly pulling in JS updates. // to worry about constantly pulling in JS updates.
if (options.uiDirs) {
options.uiDirs.forEach(function(dir) {
app.use(express.static(dir));
});
}
if (options.swaggerDistRoot) { if (options.swaggerDistRoot) {
console.warn('loopback-explorer: `swaggerDistRoot` is deprecated,' +
' use `uiDirs` instead');
app.use(express.static(options.swaggerDistRoot)); app.use(express.static(options.swaggerDistRoot));
} }
// File in node_modules are overridden by a few customizations // File in node_modules are overridden by a few customizations
app.use(express.static(STATIC_ROOT)); app.use(express.static(STATIC_ROOT));
// Swagger UI distribution // Swagger UI distribution
app.use(express.static(SWAGGER_UI_ROOT)); app.use(express.static(SWAGGER_UI_ROOT));

View File

@ -2,6 +2,7 @@ var loopback = require('loopback');
var explorer = require('../'); var explorer = require('../');
var request = require('supertest'); var request = require('supertest');
var assert = require('assert'); var assert = require('assert');
var path = require('path');
var expect = require('chai').expect; var expect = require('chai').expect;
describe('explorer', function() { describe('explorer', function() {
@ -24,7 +25,7 @@ describe('explorer', function() {
.end(function(err, res) { .end(function(err, res) {
if (err) throw err; if (err) throw err;
assert(!!~res.text.indexOf('<title>StrongLoop API Explorer</title>'), assert(!!~res.text.indexOf('<title>StrongLoop API Explorer</title>'),
'text does not contain expected string'); 'text does not contain expected string');
done(); done();
}); });
@ -79,6 +80,32 @@ describe('explorer', function() {
}); });
}); });
describe('with custom front-end files', function() {
var app;
beforeEach(function setupExplorerWithUiDirs() {
app = loopback();
app.use('/explorer', explorer(app, {
uiDirs: [ path.resolve(__dirname, 'fixtures', 'dummy-swagger-ui') ]
}));
});
it('overrides swagger-ui files', function(done) {
request(app).get('/explorer/swagger-ui.js')
.expect(200)
// expect the content of `dummy-swagger-ui/swagger-ui.js`
.expect('/* custom swagger-ui file */\n')
.end(done);
});
it('overrides strongloop overrides', function(done) {
request(app).get('/explorer/')
.expect(200)
// expect the content of `dummy-swagger-ui/index.html`
.expect('custom index.html\n')
.end(done);
});
});
function givenLoopBackAppWithExplorer(explorerBase) { function givenLoopBackAppWithExplorer(explorerBase) {
return function(done) { return function(done) {
var app = this.app = loopback(); var app = this.app = loopback();

View File

@ -0,0 +1 @@
custom index.html

View File

@ -0,0 +1 @@
/* custom swagger-ui file */