diff --git a/.eslintignore b/.eslintignore index e69de29..33586bf 100644 --- a/.eslintignore +++ b/.eslintignore @@ -0,0 +1,2 @@ +public +coverage diff --git a/example/hidden.js b/example/hidden.js index 3ab579a..37ba033 100644 --- a/example/hidden.js +++ b/example/hidden.js @@ -3,24 +3,26 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -var g = require('strong-globalize')(); +'use strict'; -var loopback = require('loopback'); -var app = loopback(); -var explorer = require('../'); -var port = 3000; +const g = require('strong-globalize')(); -var User = loopback.Model.extend('user', { +const loopback = require('loopback'); +const app = loopback(); +const explorer = require('../'); +const port = 3000; + +const User = loopback.Model.extend('user', { username: 'string', email: 'string', sensitiveInternalProperty: 'string', -}, { hidden: ['sensitiveInternalProperty'] }); +}, {hidden: ['sensitiveInternalProperty']}); User.attachTo(loopback.memory()); app.model(User); -var apiPath = '/api'; -explorer(app, { basePath: apiPath }); +const apiPath = '/api'; +explorer(app, {basePath: apiPath}); app.use(apiPath, loopback.rest()); g.log('{{Explorer}} mounted at {{localhost:%s/explorer}}', port); diff --git a/example/simple.js b/example/simple.js index ef39372..011bcca 100644 --- a/example/simple.js +++ b/example/simple.js @@ -3,23 +3,25 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -var g = require('strong-globalize')(); +'use strict'; -var loopback = require('loopback'); -var app = loopback(); -var explorer = require('../'); -var port = 3000; +const g = require('strong-globalize')(); -var Product = loopback.PersistedModel.extend('product', { - foo: { type: 'string', required: true }, +const loopback = require('loopback'); +const app = loopback(); +const explorer = require('../'); +const port = 3000; + +const Product = loopback.PersistedModel.extend('product', { + foo: {type: 'string', required: true}, bar: 'string', - aNum: { type: 'number', min: 1, max: 10, required: true, default: 5 }, + aNum: {type: 'number', min: 1, max: 10, required: true, default: 5}, }); Product.attachTo(loopback.memory()); app.model(Product); -var apiPath = '/api'; -explorer(app, { basePath: apiPath }); +const apiPath = '/api'; +explorer(app, {basePath: apiPath}); app.use(apiPath, loopback.rest()); g.log('{{Explorer}} mounted at {{http://localhost:%s/explorer}}', port); diff --git a/index.js b/index.js index 5f3d0d5..395f6be 100644 --- a/index.js +++ b/index.js @@ -5,20 +5,20 @@ 'use strict'; -var SG = require('strong-globalize'); +const SG = require('strong-globalize'); SG.SetRootDir(__dirname); -var g = SG(); +const g = SG(); /*! * Adds dynamically-updated docs as /explorer */ -var url = require('url'); -var path = require('path'); -var urlJoin = require('./lib/url-join'); -var _defaults = require('lodash').defaults; -var createSwaggerObject = require('loopback-swagger').generateSwaggerSpec; -var SWAGGER_UI_ROOT = require('swagger-ui/index').dist; -var STATIC_ROOT = path.join(__dirname, 'public'); +const url = require('url'); +const path = require('path'); +const urlJoin = require('./lib/url-join'); +const _defaults = require('lodash').defaults; +const createSwaggerObject = require('loopback-swagger').generateSwaggerSpec; +const SWAGGER_UI_ROOT = require('swagger-ui/index').dist; +const STATIC_ROOT = path.join(__dirname, 'public'); module.exports = explorer; explorer.routes = routes; @@ -31,7 +31,7 @@ explorer.routes = routes; */ function explorer(loopbackApplication, options) { - options = _defaults({}, options, { mountPath: '/explorer' }); + options = _defaults({}, options, {mountPath: '/explorer'}); loopbackApplication.use( options.mountPath, routes(loopbackApplication, options) @@ -40,8 +40,8 @@ function explorer(loopbackApplication, options) { } function routes(loopbackApplication, options) { - var loopback = loopbackApplication.loopback; - var loopbackMajor = + const loopback = loopbackApplication.loopback; + const loopbackMajor = (loopback && loopback.version && loopback.version.split('.')[0]) || 1; if (loopbackMajor < 2) { @@ -59,7 +59,7 @@ function routes(loopbackApplication, options) { swaggerUI: true, }); - var router = new loopback.Router(); + const router = new loopback.Router(); mountSwagger(loopbackApplication, router, options); @@ -68,7 +68,7 @@ function routes(loopbackApplication, options) { 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; + let source = url.parse(req.headers.referer || '').pathname; // strip index.html if present in referer if (source && /\/index\.html$/.test(source)) { source = source.replace(/\/index\.html$/, ''); @@ -118,7 +118,7 @@ function routes(loopbackApplication, options) { * @param {Object} opts Options. */ function mountSwagger(loopbackApplication, swaggerApp, opts) { - var swaggerObject = createSwaggerObject(loopbackApplication, opts); + let swaggerObject = createSwaggerObject(loopbackApplication, opts); // listening to modelRemoted event for updating the swaggerObject // with the newly created model to appear in the Swagger UI. @@ -135,7 +135,7 @@ function mountSwagger(loopbackApplication, swaggerApp, opts) { // when a remote method is disabled to hide that method in the Swagger UI. loopbackApplication.on('remoteMethodDisabled', rebuildSwaggerObject); - var resourcePath = (opts && opts.resourcePath) || 'swagger.json'; + let resourcePath = (opts && opts.resourcePath) || 'swagger.json'; if (resourcePath[0] !== '/') resourcePath = '/' + resourcePath; swaggerApp.get(resourcePath, function sendSwaggerObject(req, res) { diff --git a/lib/url-join.js b/lib/url-join.js index 2d64731..00bb251 100644 --- a/lib/url-join.js +++ b/lib/url-join.js @@ -8,6 +8,6 @@ // Simple url joiner. Ensure we don't have to care about whether or not // we are fed paths with leading/trailing slashes. module.exports = function urlJoin() { - var args = Array.prototype.slice.call(arguments); + const args = Array.prototype.slice.call(arguments); return args.join('/').replace(/\/+/g, '/'); }; diff --git a/package.json b/package.json index 5d2859f..5b7697d 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,8 @@ }, "devDependencies": { "chai": "^3.2.0", - "eslint": "^2.13.1", - "eslint-config-loopback": "^2.0.0", + "eslint": "^5.13.0", + "eslint-config-loopback": "^13.0.0", "loopback": "^3.19.0", "mocha": "^5.2.0", "supertest": "^3.1.0" diff --git a/test/explorer.test.js b/test/explorer.test.js index e9ddf12..c88b28e 100644 --- a/test/explorer.test.js +++ b/test/explorer.test.js @@ -3,14 +3,16 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -var loopback = require('loopback'); -var explorer = require('../'); -var request = require('supertest'); -var assert = require('assert'); -var path = require('path'); -var expect = require('chai').expect; -var urlJoin = require('../lib/url-join'); -var os = require('os'); +'use strict'; + +const loopback = require('loopback'); +const explorer = require('../'); +const request = require('supertest'); +const assert = require('assert'); +const path = require('path'); +const expect = require('chai').expect; +const urlJoin = require('../lib/url-join'); +const os = require('os'); describe('explorer', function() { describe('with default config', function() { @@ -18,7 +20,7 @@ describe('explorer', function() { it('should register "loopback-component-explorer" to the app', function() { expect(this.app.get('loopback-component-explorer')) - .to.have.property('mountPath', '/explorer'); + .to.have.property('mountPath', '/explorer'); }); it('should redirect to /explorer/', function(done) { @@ -99,7 +101,7 @@ describe('explorer', function() { it('should register "loopback-component-explorer" to the app', function() { expect(this.app.get('loopback-component-explorer')) - .to.have.property('mountPath', '/swagger'); + .to.have.property('mountPath', '/swagger'); }); it('should serve correct swagger-ui config', function(done) { @@ -120,9 +122,9 @@ describe('explorer', function() { describe('with custom app.restApiRoot', function() { it('should serve correct swagger-ui config', function(done) { - var app = loopback(); + const app = loopback(); app.set('restApiRoot', '/rest-api-root'); - app.set('remoting', { cors: false }); + app.set('remoting', {cors: false}); configureRestApiAndExplorer(app); request(app) @@ -142,9 +144,9 @@ describe('explorer', function() { // SwaggerUI builds resource URL by concatenating basePath + resourcePath // Since the resource paths are always startign with a slash, // if the basePath ends with a slash too, an incorrect URL is produced - var app = loopback(); + const app = loopback(); app.set('restApiRoot', '/apis/'); - app.set('remoting', { cors: false }); + app.set('remoting', {cors: false}); configureRestApiAndExplorer(app); request(app) @@ -153,8 +155,8 @@ describe('explorer', function() { .end(function(err, res) { if (err) return done(err); - var baseUrl = res.body.basePath; - var apiPath = Object.keys(res.body.paths)[0]; + const baseUrl = res.body.basePath; + const apiPath = Object.keys(res.body.paths)[0]; expect(baseUrl + apiPath).to.equal('/apis/products'); done(); @@ -163,10 +165,10 @@ describe('explorer', function() { }); describe('with custom front-end files', function() { - var app; + let app; beforeEach(function setupExplorerWithUiDirs() { app = loopback(); - app.set('remoting', { cors: false }); + app.set('remoting', {cors: false}); explorer(app, { uiDirs: [path.resolve(__dirname, 'fixtures', 'dummy-swagger-ui')], }); @@ -189,7 +191,7 @@ describe('explorer', function() { request(app).get('/explorer/') .expect(200) .end(function(err, res) { - if (err) return done(er); + if (err) return done(err); // expect the content of `dummy-swagger-ui/index.html` expect(res.text).to.contain('custom index.html'); done(); @@ -198,10 +200,10 @@ describe('explorer', function() { }); describe('with swaggerUI option', function() { - var app; + let app; beforeEach(function setupExplorerWithoutUI() { app = loopback(); - app.set('remoting', { cors: false }); + app.set('remoting', {cors: false}); explorer(app, { swaggerUI: false, }); @@ -234,11 +236,11 @@ describe('explorer', function() { }); describe('explorer.routes API', function() { - var app; + let app; beforeEach(function() { app = loopback(); - app.set('remoting', { cors: false }); - var Product = loopback.PersistedModel.extend('product'); + app.set('remoting', {cors: false}); + const Product = loopback.PersistedModel.extend('product'); Product.attachTo(loopback.memory()); app.model(Product); }); @@ -256,10 +258,10 @@ describe('explorer', function() { }); describe('when specifying custom static file root directories', function() { - var app; + let app; beforeEach(function() { app = loopback(); - app.set('remoting', { cors: false }); + app.set('remoting', {cors: false}); }); it('should allow `uiDirs` to be defined as an Array', function(done) { @@ -294,8 +296,8 @@ describe('explorer', function() { }); it('updates swagger object when a new model is added', function(done) { - var app = loopback(); - app.set('remoting', { cors: false }); + const app = loopback(); + app.set('remoting', {cors: false}); configureRestApiAndExplorer(app, '/explorer'); // Ensure the swagger object was built @@ -306,7 +308,7 @@ describe('explorer', function() { if (err) return done(err); // Create a new model - var Model = loopback.PersistedModel.extend('Customer'); + const Model = loopback.PersistedModel.extend('Customer'); Model.attachTo(loopback.memory()); app.model(Model); @@ -317,9 +319,9 @@ describe('explorer', function() { .end(function(err, res) { if (err) return done(err); - var modelNames = Object.keys(res.body.definitions); + const modelNames = Object.keys(res.body.definitions); expect(modelNames).to.contain('Customer'); - var paths = Object.keys(res.body.paths); + const paths = Object.keys(res.body.paths); expect(paths).to.have.contain('/Customers'); done(); @@ -328,11 +330,11 @@ describe('explorer', function() { }); it('updates swagger object when a model is removed', function(done) { - var app = loopback(); - app.set('remoting', { cors: false }); + const app = loopback(); + app.set('remoting', {cors: false}); configureRestApiAndExplorer(app, '/explorer'); - var Model = loopback.PersistedModel.extend('Customer'); + const Model = loopback.PersistedModel.extend('Customer'); Model.attachTo(loopback.memory()); app.model(Model); @@ -352,9 +354,9 @@ describe('explorer', function() { .end(function(err, res) { if (err) return done(err); - var modelNames = Object.keys(res.body.definitions); + const modelNames = Object.keys(res.body.definitions); expect(modelNames).to.not.contain('Customer'); - var paths = Object.keys(res.body.paths); + const paths = Object.keys(res.body.paths); expect(paths).to.not.contain('/Customers'); done(); @@ -363,8 +365,8 @@ describe('explorer', function() { }); it('updates swagger object when a remote method is disabled', function(done) { - var app = loopback(); - app.set('remoting', { cors: false }); + const app = loopback(); + app.set('remoting', {cors: false}); configureRestApiAndExplorer(app, '/explorer'); // Ensure the swagger object was built @@ -375,10 +377,10 @@ describe('explorer', function() { if (err) return done(err); // Check the method that will be disabled - var paths = Object.keys(res.body.paths); + const paths = Object.keys(res.body.paths); expect(paths).to.contain('/products/findOne'); - var Product = app.models.Product; + const Product = app.models.Product; Product.disableRemoteMethodByName('findOne'); // Request swagger.json again @@ -388,7 +390,7 @@ describe('explorer', function() { .end(function(err, res) { if (err) return done(err); - var paths = Object.keys(res.body.paths); + const paths = Object.keys(res.body.paths); expect(paths).to.not.contain('/products/findOne'); done(); @@ -397,8 +399,8 @@ describe('explorer', function() { }); it('updates swagger object when a remote method is added', function(done) { - var app = loopback(); - app.set('remoting', { cors: false }); + const app = loopback(); + app.set('remoting', {cors: false}); configureRestApiAndExplorer(app, '/explorer'); // Ensure the swagger object was built @@ -409,10 +411,10 @@ describe('explorer', function() { if (err) return done(err); // Check the method that will be disabled - var paths = Object.keys(res.body.paths); + const paths = Object.keys(res.body.paths); expect(paths).to.contain('/products/findOne'); - var Product = app.models.Product; + const Product = app.models.Product; Product.findOne2 = function(cb) { cb(null, 1); }; Product.remoteMethod('findOne2', {}); @@ -423,7 +425,7 @@ describe('explorer', function() { .end(function(err, res) { if (err) return done(err); - var paths = Object.keys(res.body.paths); + const paths = Object.keys(res.body.paths); expect(paths).to.contain('/products/findOne2'); done(); @@ -433,8 +435,8 @@ describe('explorer', function() { function givenLoopBackAppWithExplorer(explorerBase) { return function(done) { - var app = this.app = loopback(); - app.set('remoting', { cors: false }); + const app = this.app = loopback(); + app.set('remoting', {cors: false}); configureRestApiAndExplorer(app, explorerBase); done(); @@ -442,11 +444,11 @@ describe('explorer', function() { } function configureRestApiAndExplorer(app, explorerBase) { - var Product = loopback.PersistedModel.extend('product'); + const Product = loopback.PersistedModel.extend('product'); Product.attachTo(loopback.memory()); app.model(Product); - explorer(app, { mountPath: explorerBase }); + explorer(app, {mountPath: explorerBase}); app.set('legacyExplorer', false); app.use(app.get('restApiRoot') || '/', loopback.rest()); }