diet for reducing lib size

This commit is contained in:
Camel Aissani 2017-01-14 15:02:50 +01:00
parent 41b4a5ed19
commit a9b90040bd
13 changed files with 144 additions and 313 deletions

View File

@ -2,5 +2,6 @@ index.js
frontexpress.js frontexpress.js
frontexpress.min.js frontexpress.min.js
frontexpress.min.js.map frontexpress.min.js.map
gzipsize.js
test test
coverage coverage

View File

@ -8,7 +8,7 @@
[![Code Climate](https://codeclimate.com/github/camelaissani/frontexpress/badges/gpa.svg)](https://codeclimate.com/github/camelaissani/frontexpress) [![Code Climate](https://codeclimate.com/github/camelaissani/frontexpress/badges/gpa.svg)](https://codeclimate.com/github/camelaissani/frontexpress)
[![Coverage Status](https://coveralls.io/repos/github/camelaissani/frontexpress/badge.svg?branch=master)](https://coveralls.io/github/camelaissani/frontexpress?branch=master) [![Coverage Status](https://coveralls.io/repos/github/camelaissani/frontexpress/badge.svg?branch=master)](https://coveralls.io/github/camelaissani/frontexpress?branch=master)
![dependencies](https://img.shields.io/gemnasium/mathiasbynens/he.svg) ![dependencies](https://img.shields.io/gemnasium/mathiasbynens/he.svg)
![Size Shield](https://img.shields.io/badge/size-3.3kb-brightgreen.svg) ![Size Shield](https://img.shields.io/badge/size-3.07kb-brightgreen.svg)
Code the front-end logic with the same style than on the back-end with express Code the front-end logic with the same style than on the back-end with express

View File

@ -163,8 +163,6 @@ var Requester = function () {
statusText = _ref.statusText, statusText = _ref.statusText,
errorThrown = _ref.errorThrown; errorThrown = _ref.errorThrown;
// Removed for reducing size of frontexpress
// const errors = this._analyzeErrors({status, statusText, errorThrown});
reject(request, { reject(request, {
status: status, status: status,
statusText: statusText, statusText: statusText,
@ -220,48 +218,6 @@ var Requester = function () {
fail({ errorThrown: errorThrown }); fail({ errorThrown: errorThrown });
} }
} }
// Removed for reducing size of frontexpress
// /**
// * Analyse response errors.
// *
// * @private
// */
// _analyzeErrors(response) {
// // manage exceptions
// if (response.errorThrown) {
// if (response.errorThrown.name === 'SyntaxError') {
// return 'Problem during data decoding [JSON]';
// }
// if (response.errorThrown.name === 'TimeoutError') {
// return 'Server is taking too long to reply';
// }
// if (response.errorThrown.name === 'AbortError') {
// return 'Request cancelled on server';
// }
// if (response.errorThrown.name === 'NetworkError') {
// return 'A network error occurred';
// }
// throw response.errorThrown;
// }
// // manage status
// if (response.status === 0) {
// return 'Server access problem. Check your network connection';
// }
// if (response.status === 401) {
// return 'Your session has expired, Please reconnect. [code: 401]';
// }
// if (response.status === 404) {
// return 'Page not found on server. [code: 404]';
// }
// if (response.status === 500) {
// return 'Internal server error. [code: 500]';
// }
// return `Unknown error. ${response.statusText?response.statusText:''}`;
// }
}]); }]);
return Requester; return Requester;
}(); }();
@ -509,12 +465,12 @@ var Route = function () {
return this.router.baseUri; return this.router.baseUri;
} }
if (this.router.baseUri && this.uriPart) {
return (this.router.baseUri.trim() + this.uriPart.trim()).replace(/\/{2,}/, '/');
}
if (this.router.baseUri) { if (this.router.baseUri) {
return this.router.baseUri.trim(); var baseUri = this.router.baseUri.trim();
if (this.uriPart) {
return (baseUri + this.uriPart.trim()).replace(/\/{2,}/, '/');
}
return baseUri;
} }
return this.uriPart; return this.uriPart;
@ -528,6 +484,8 @@ var Route = function () {
* @public * @public
*/ */
var error_middleware_message = 'method takes at least a middleware';
var Router = function () { var Router = function () {
/** /**
@ -539,9 +497,7 @@ var Router = function () {
function Router(uri) { function Router(uri) {
classCallCheck(this, Router); classCallCheck(this, Router);
if (uri) { this._baseUri = uri;
this._baseUri = uri;
}
this._routes = []; this._routes = [];
} }
@ -576,36 +532,24 @@ var Router = function () {
key: 'routes', key: 'routes',
value: function routes(uri, method) { value: function routes(uri, method) {
return this._routes.filter(function (route) { return this._routes.filter(function (route) {
if (!route.uri && !route.method) { if (route.method && route.method !== method) {
return true;
}
if (route.method !== method) {
return false; return false;
} }
if (!route.uri) { if (!route.uri || !uri) {
return true; return true;
} }
var uriToCheck = uri;
//remove query string from uri to test //remove query string from uri to test
var questionMarkIndex = uriToCheck.indexOf('?');
if (questionMarkIndex >= 0) {
uriToCheck = uriToCheck.slice(0, questionMarkIndex);
}
//remove anchor from uri to test //remove anchor from uri to test
var hashIndex = uriToCheck.indexOf('#'); var match = /^(.*)\?.*#.*|(.*)(?=\?|#)|(.*[^\?#])$/.exec(uri);
if (hashIndex >= 0) { var baseUriToCheck = match[1] || match[2] || match[3];
uriToCheck = uriToCheck.slice(0, hashIndex);
}
if (route.uri instanceof RegExp) { if (route.uri instanceof RegExp) {
return uriToCheck.match(route.uri); return baseUriToCheck.match(route.uri);
} }
return route.uri === uriToCheck; return route.uri === baseUriToCheck;
}); });
} }
@ -642,7 +586,7 @@ var Router = function () {
key: 'use', key: 'use',
value: function use(middleware) { value: function use(middleware) {
if (!(middleware instanceof Middleware) && typeof middleware !== 'function') { if (!(middleware instanceof Middleware) && typeof middleware !== 'function') {
throw new TypeError('use method takes at least a middleware'); throw new TypeError(error_middleware_message);
} }
this._add(new Route(this, undefined, undefined, middleware)); this._add(new Route(this, undefined, undefined, middleware));
@ -673,19 +617,11 @@ var Router = function () {
args[_key] = arguments[_key]; args[_key] = arguments[_key];
} }
if (args.length === 0) { var _toParameters = toParameters(args),
throw new TypeError('use all method takes at least a middleware'); middleware = _toParameters.middleware;
}
var middleware = void 0;
if (args.length === 1) { if (!middleware) {
middleware = args[0]; throw new TypeError(error_middleware_message);
} else {
middleware = args[1];
}
if (!(middleware instanceof Middleware) && typeof middleware !== 'function') {
throw new TypeError('use all method takes at least a middleware');
} }
var _iteratorNormalCompletion = true; var _iteratorNormalCompletion = true;
@ -718,22 +654,10 @@ var Router = function () {
}, { }, {
key: 'baseUri', key: 'baseUri',
set: function set$$1(uri) { set: function set$$1(uri) {
if (!uri) { if (this._baseUri) {
return; throw new TypeError('base uri is already set');
}
if (!this._baseUri) {
this._baseUri = uri;
return;
}
if (this._baseUri instanceof RegExp) {
throw new TypeError('the router already contains a regexp uri ' + this._baseUri.toString() + ' It cannot be mixed with ' + uri.toString());
}
if (uri instanceof RegExp) {
throw new TypeError('the router already contains an uri ' + this._baseUri.toString() + ' It cannot be mixed with regexp ' + uri.toString());
} }
this._baseUri = uri;
} }
/** /**
@ -788,28 +712,19 @@ try {
args[_key2] = arguments[_key2]; args[_key2] = arguments[_key2];
} }
if (args.length === 0) { var _toParameters2 = toParameters(args),
throw new TypeError('use ' + methodName + ' method takes at least a middleware'); baseUri = _toParameters2.baseUri,
} middleware = _toParameters2.middleware;
var uri = void 0,
middleware = void 0;
if (args.length === 1) { if (!middleware) {
middleware = args[0]; throw new TypeError(error_middleware_message);
} else {
uri = args[0];
middleware = args[1];
} }
if (!(middleware instanceof Middleware) && typeof middleware !== 'function') { if (baseUri && this._baseUri && this._baseUri instanceof RegExp) {
throw new TypeError('use ' + methodName + ' method takes at least a middleware'); throw new TypeError('router cannot mix uri/regexp');
} }
if (uri && this._baseUri && this._baseUri instanceof RegExp) { this._add(new Route(this, baseUri, method, middleware));
throw new TypeError('router contains a regexp cannot mix with route uri/regexp');
}
this._add(new Route(this, uri, method, middleware));
return this; return this;
}; };
@ -1000,25 +915,14 @@ var Application = function () {
args[_key2] = arguments[_key2]; args[_key2] = arguments[_key2];
} }
var errorMsg = 'use method takes at least a middleware or a router'; var _toParameters = toParameters(args),
var baseUri = void 0, baseUri = _toParameters.baseUri,
middleware = void 0, router = _toParameters.router,
router = void 0, middleware = _toParameters.middleware;
which = void 0;
if (!args || args.length === 0) {
throw new TypeError(errorMsg);
} else if (args.length === 1) {
which = args[0];
} else {
baseUri = args[0];
which = args[1];
}
if (which instanceof Router) { if (router) {
router = which;
router.baseUri = baseUri; router.baseUri = baseUri;
} else if (which instanceof Middleware || typeof which === 'function') { } else if (middleware) {
middleware = which;
router = new Router(baseUri); router = new Router(baseUri);
var _iteratorNormalCompletion = true; var _iteratorNormalCompletion = true;
var _didIteratorError = false; var _didIteratorError = false;
@ -1045,7 +949,7 @@ var Application = function () {
} }
} }
} else { } else {
throw new TypeError(errorMsg); throw new TypeError('method takes at least a middleware or a router');
} }
this.routers.push(router); this.routers.push(router);
@ -1287,27 +1191,17 @@ HTTP_METHODS.reduce(function (reqProto, method) {
args[_key3] = arguments[_key3]; args[_key3] = arguments[_key3];
} }
var baseUri = void 0, var _toParameters2 = toParameters(args),
middleware = void 0, baseUri = _toParameters2.baseUri,
which = void 0; middleware = _toParameters2.middleware,
if (!args || args.length === 0) { which = _toParameters2.which;
throw new TypeError(middlewareMethodName + ' method takes at least a middleware ' + (middlewareMethodName === 'get' ? 'or a string' : ''));
} else if (args.length === 1) {
which = args[0];
if (middlewareMethodName === 'get' && typeof which === 'string') { if (middlewareMethodName === 'get' && typeof which === 'string') {
return this.settings.get(which); return this.settings.get(which);
}
} else {
baseUri = args[0];
which = args[1];
} }
if (!middleware) {
if (!(which instanceof Middleware) && typeof which !== 'function') { throw new TypeError('method takes a middleware ' + (middlewareMethodName === 'get' ? 'or a string' : ''));
throw new TypeError(middlewareMethodName + ' method takes at least a middleware');
} }
middleware = which;
var router = new Router(); var router = new Router();
router[middlewareMethodName](baseUri, middleware); router[middlewareMethodName](baseUri, middleware);
@ -1358,6 +1252,32 @@ HTTP_METHODS.reduce(function (reqProto, method) {
return reqProto; return reqProto;
}, Application.prototype); }, Application.prototype);
function toParameters(args) {
var baseUri = void 0,
middleware = void 0,
router = void 0,
which = void 0;
if (args && args.length > 0) {
if (args.length === 1) {
var _args = slicedToArray(args, 1);
which = _args[0];
} else {
var _args2 = slicedToArray(args, 2);
baseUri = _args2[0];
which = _args2[1];
}
if (which instanceof Router) {
router = which;
} else if (which instanceof Middleware || typeof which === 'function') {
middleware = which;
}
}
return { baseUri: baseUri, middleware: middleware, router: router, which: which };
}
/** /**
* Module dependencies. * Module dependencies.
*/ */

2
frontexpress.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

5
gzipsize.js Normal file
View File

@ -0,0 +1,5 @@
import bytesize from 'bytesize';
bytesize.gzipSize(__dirname + '/frontexpress.min.js', true, (err, size) => {
console.log(`frontexpress size: ${size}(min+gzip)`);
});

View File

@ -151,27 +151,16 @@ export default class Application {
*/ */
use(...args) { use(...args) {
const errorMsg = 'use method takes at least a middleware or a router'; let {baseUri, router, middleware} = toParameters(args);
let baseUri, middleware, router, which; if (router) {
if (!args || args.length === 0) {
throw new TypeError(errorMsg);
} else if (args.length === 1) {
[which,] = args;
} else {
[baseUri, which,] = args;
}
if (which instanceof Router) {
router = which;
router.baseUri = baseUri; router.baseUri = baseUri;
} else if ((which instanceof Middleware) || (typeof which === 'function')) { } else if (middleware) {
middleware = which;
router = new Router(baseUri); router = new Router(baseUri);
for (const method of HTTP_METHODS) { for (const method of HTTP_METHODS) {
router[method.toLowerCase()](middleware); router[method.toLowerCase()](middleware);
} }
} else { } else {
throw new TypeError(errorMsg); throw new TypeError('method takes at least a middleware or a router');
} }
this.routers.push(router); this.routers.push(router);
@ -313,23 +302,13 @@ HTTP_METHODS.reduce((reqProto, method) => {
const middlewareMethodName = method.toLowerCase(); const middlewareMethodName = method.toLowerCase();
reqProto[middlewareMethodName] = function(...args) { reqProto[middlewareMethodName] = function(...args) {
let baseUri, middleware, which; let {baseUri, middleware, which} = toParameters(args);
if (!args || args.length === 0) { if (middlewareMethodName === 'get' && typeof which === 'string') {
throw new TypeError(`${middlewareMethodName} method takes at least a middleware ${middlewareMethodName === 'get' ? 'or a string' : ''}`); return this.settings.get(which);
} else if (args.length === 1) {
[which] = args;
if (middlewareMethodName === 'get' && typeof which === 'string') {
return this.settings.get(which);
}
} else {
[baseUri, which,] = args;
} }
if (!middleware) {
if (!(which instanceof Middleware) && (typeof which !== 'function')) { throw new TypeError(`method takes a middleware ${middlewareMethodName === 'get' ? 'or a string' : ''}`);
throw new TypeError(`${middlewareMethodName} method takes at least a middleware`);
} }
middleware = which;
const router = new Router(); const router = new Router();
router[middlewareMethodName](baseUri, middleware); router[middlewareMethodName](baseUri, middleware);
@ -375,3 +354,22 @@ HTTP_METHODS.reduce((reqProto, method) => {
return reqProto; return reqProto;
}, Application.prototype); }, Application.prototype);
export function toParameters(args) {
let baseUri, middleware, router, which;
if (args && args.length > 0) {
if (args.length === 1) {
[which,] = args;
} else {
[baseUri, which,] = args;
}
if (which instanceof Router) {
router = which;
} else if ((which instanceof Middleware) || (typeof which === 'function')) {
middleware = which;
}
}
return {baseUri, middleware, router, which};
}

View File

@ -29,8 +29,6 @@ export default class Requester {
}; };
const fail = ({status, statusText, errorThrown}) => { const fail = ({status, statusText, errorThrown}) => {
// Removed for reducing size of frontexpress
// const errors = this._analyzeErrors({status, statusText, errorThrown});
reject( reject(
request, request,
{ {
@ -68,45 +66,4 @@ export default class Requester {
fail({errorThrown}); fail({errorThrown});
} }
} }
// Removed for reducing size of frontexpress
// /**
// * Analyse response errors.
// *
// * @private
// */
// _analyzeErrors(response) {
// // manage exceptions
// if (response.errorThrown) {
// if (response.errorThrown.name === 'SyntaxError') {
// return 'Problem during data decoding [JSON]';
// }
// if (response.errorThrown.name === 'TimeoutError') {
// return 'Server is taking too long to reply';
// }
// if (response.errorThrown.name === 'AbortError') {
// return 'Request cancelled on server';
// }
// if (response.errorThrown.name === 'NetworkError') {
// return 'A network error occurred';
// }
// throw response.errorThrown;
// }
// // manage status
// if (response.status === 0) {
// return 'Server access problem. Check your network connection';
// }
// if (response.status === 401) {
// return 'Your session has expired, Please reconnect. [code: 401]';
// }
// if (response.status === 404) {
// return 'Page not found on server. [code: 404]';
// }
// if (response.status === 500) {
// return 'Internal server error. [code: 500]';
// }
// return `Unknown error. ${response.statusText?response.statusText:''}`;
// }
} }

View File

@ -4,6 +4,7 @@
*/ */
import HTTP_METHODS from './methods'; import HTTP_METHODS from './methods';
import {toParameters} from './application';
import Middleware from './middleware'; import Middleware from './middleware';
@ -49,12 +50,12 @@ export class Route {
return this.router.baseUri; return this.router.baseUri;
} }
if (this.router.baseUri && this.uriPart) {
return (this.router.baseUri.trim() + this.uriPart.trim()).replace(/\/{2,}/, '/');
}
if (this.router.baseUri) { if (this.router.baseUri) {
return this.router.baseUri.trim(); const baseUri = this.router.baseUri.trim();
if (this.uriPart) {
return ( baseUri + this.uriPart.trim()).replace(/\/{2,}/, '/');
}
return baseUri;
} }
return this.uriPart; return this.uriPart;
@ -67,6 +68,7 @@ export class Route {
* @public * @public
*/ */
const error_middleware_message = 'method takes at least a middleware';
export default class Router { export default class Router {
@ -77,9 +79,7 @@ export default class Router {
*/ */
constructor(uri) { constructor(uri) {
if (uri) { this._baseUri = uri;
this._baseUri = uri;
}
this._routes = []; this._routes = [];
} }
@ -91,22 +91,10 @@ export default class Router {
*/ */
set baseUri(uri) { set baseUri(uri) {
if (!uri) { if (this._baseUri) {
return; throw new TypeError('base uri is already set');
}
if (!this._baseUri) {
this._baseUri = uri;
return;
}
if (this._baseUri instanceof RegExp) {
throw new TypeError(`the router already contains a regexp uri ${this._baseUri.toString()} It cannot be mixed with ${uri.toString()}`);
}
if (uri instanceof RegExp) {
throw new TypeError(`the router already contains an uri ${this._baseUri.toString()} It cannot be mixed with regexp ${uri.toString()}`);
} }
this._baseUri = uri;
} }
@ -141,36 +129,24 @@ export default class Router {
routes(uri, method) { routes(uri, method) {
return this._routes.filter((route) => { return this._routes.filter((route) => {
if (!route.uri && !route.method) { if (route.method && route.method !== method) {
return true;
}
if (route.method !== method) {
return false; return false;
} }
if (!route.uri) { if (!route.uri || !uri) {
return true; return true;
} }
let uriToCheck = uri;
//remove query string from uri to test //remove query string from uri to test
const questionMarkIndex = uriToCheck.indexOf('?');
if (questionMarkIndex >= 0) {
uriToCheck = uriToCheck.slice(0, questionMarkIndex);
}
//remove anchor from uri to test //remove anchor from uri to test
const hashIndex = uriToCheck.indexOf('#'); const match = /^(.*)\?.*#.*|(.*)(?=\?|#)|(.*[^\?#])$/.exec(uri);
if (hashIndex >= 0) { const baseUriToCheck = match[1] || match[2] || match[3];
uriToCheck = uriToCheck.slice(0, hashIndex);
}
if (route.uri instanceof RegExp) { if (route.uri instanceof RegExp) {
return uriToCheck.match(route.uri); return baseUriToCheck.match(route.uri);
} }
return route.uri === uriToCheck; return route.uri === baseUriToCheck;
}); });
} }
@ -182,9 +158,7 @@ export default class Router {
*/ */
visited() { visited() {
return this._routes.filter((route) => { return this._routes.filter(route => route.visited);
return route.visited;
});
} }
@ -205,7 +179,7 @@ export default class Router {
use(middleware) { use(middleware) {
if (!(middleware instanceof Middleware) && (typeof middleware !== 'function') ) { if (!(middleware instanceof Middleware) && (typeof middleware !== 'function') ) {
throw new TypeError('use method takes at least a middleware'); throw new TypeError(error_middleware_message);
} }
this._add(new Route(this, undefined, undefined, middleware)); this._add(new Route(this, undefined, undefined, middleware));
@ -231,19 +205,9 @@ export default class Router {
*/ */
all(...args) { all(...args) {
if (args.length === 0) { const {middleware} = toParameters(args);
throw new TypeError('use all method takes at least a middleware'); if (!middleware) {
} throw new TypeError(error_middleware_message);
let middleware;
if (args.length === 1) {
[middleware,] = args;
} else {
[, middleware,] = args;
}
if (!(middleware instanceof Middleware) && (typeof middleware !== 'function') ) {
throw new TypeError('use all method takes at least a middleware');
} }
for (const method of HTTP_METHODS) { for (const method of HTTP_METHODS) {
@ -281,26 +245,16 @@ for (const method of HTTP_METHODS) {
const methodName = method.toLowerCase(); const methodName = method.toLowerCase();
Router.prototype[methodName] = function(...args) { Router.prototype[methodName] = function(...args) {
if (args.length === 0) { const {baseUri, middleware} = toParameters(args);
throw new TypeError(`use ${methodName} method takes at least a middleware`); if (!middleware) {
} throw new TypeError(error_middleware_message);
let uri, middleware;
if (args.length === 1) {
[middleware,] = args;
} else {
[uri, middleware,] = args;
} }
if (!(middleware instanceof Middleware) && (typeof middleware !== 'function') ) { if (baseUri && this._baseUri && this._baseUri instanceof RegExp) {
throw new TypeError(`use ${methodName} method takes at least a middleware`); throw new TypeError('router cannot mix uri/regexp');
} }
if (uri && this._baseUri && this._baseUri instanceof RegExp) { this._add(new Route(this, baseUri, method, middleware));
throw new TypeError('router contains a regexp cannot mix with route uri/regexp');
}
this._add(new Route(this, uri, method, middleware));
return this; return this;
}; };

View File

@ -7,7 +7,8 @@
"lint": "eslint .", "lint": "eslint .",
"only-test": "mocha --compilers js:babel-core/register", "only-test": "mocha --compilers js:babel-core/register",
"test": "npm run lint && babel-node node_modules/.bin/babel-istanbul cover node_modules/.bin/_mocha", "test": "npm run lint && babel-node node_modules/.bin/babel-istanbul cover node_modules/.bin/_mocha",
"frontpackage": "rollup -c rollup.config.dev.js && rollup -c rollup.config.prod.js", "gzipsize": "babel-node gzipsize.js",
"frontpackage": "rollup -c rollup.config.dev.js && rollup -c rollup.config.prod.js && npm run gzipsize",
"prepublish": "rimraf dist && babel lib -d dist" "prepublish": "rimraf dist && babel lib -d dist"
}, },
"author": "Camel Aissani <camel.aissani@gmail.com> (https://nuageprive.fr)", "author": "Camel Aissani <camel.aissani@gmail.com> (https://nuageprive.fr)",
@ -37,6 +38,7 @@
"babel-preset-es2015": "^6.18.0", "babel-preset-es2015": "^6.18.0",
"babel-preset-es2015-rollup": "^3.0.0", "babel-preset-es2015-rollup": "^3.0.0",
"babel-register": "^6.18.0", "babel-register": "^6.18.0",
"bytesize": "^0.2.0",
"chai": "^3.5.0", "chai": "^3.5.0",
"eslint": "^3.12.2", "eslint": "^3.12.2",
"eslint-loader": "^1.6.1", "eslint-loader": "^1.6.1",

View File

@ -6,10 +6,7 @@ export default {
moduleName:'frontexpress', moduleName:'frontexpress',
plugins: [babel({ plugins: [babel({
babelrc: false, babelrc: false,
// exclude: 'node_modules/**', presets: ['es2015-rollup']
presets: ['es2015-rollup'],
// externalHelpers: true,
// plugins: ['external-helpers']
})], })],
dest: 'frontexpress.js' dest: 'frontexpress.js'
}; };

View File

@ -11,10 +11,7 @@ export default {
plugins: [ plugins: [
babel({ babel({
babelrc: false, babelrc: false,
// exclude: 'node_modules/**', presets: ['es2015-rollup']
presets: ['es2015-rollup'],
// externalHelpers: true,
// plugins: ['external-helpers']
}), }),
uglify({ uglify({
compress: { compress: {

View File

@ -111,7 +111,7 @@ describe('Test sample from README', () => {
const router = frontexpress.Router(); const router = frontexpress.Router();
// middleware that is specific to this router // middleware which is specific to this router
router.use((req, res, next) => { router.use((req, res, next) => {
spy_log(`Time: ${Date.now()}`); spy_log(`Time: ${Date.now()}`);
next(); next();
@ -148,4 +148,4 @@ describe('Test sample from README', () => {
}); });
}); });
}); });