From a9b90040bd30301c8016250d00468326b6abdcc9 Mon Sep 17 00:00:00 2001 From: Camel Aissani Date: Sat, 14 Jan 2017 15:02:50 +0100 Subject: [PATCH] diet for reducing lib size --- .npmignore | 3 +- README.md | 2 +- frontexpress.js | 222 +++++++++++++--------------------------- frontexpress.min.js | 2 +- frontexpress.min.js.map | 2 +- gzipsize.js | 5 + lib/application.js | 58 +++++------ lib/requester.js | 43 -------- lib/router.js | 102 +++++------------- package.json | 4 +- rollup.config.dev.js | 5 +- rollup.config.prod.js | 5 +- test/readme-test.js | 4 +- 13 files changed, 144 insertions(+), 313 deletions(-) create mode 100644 gzipsize.js diff --git a/.npmignore b/.npmignore index 9036932..136a3d5 100644 --- a/.npmignore +++ b/.npmignore @@ -2,5 +2,6 @@ index.js frontexpress.js frontexpress.min.js frontexpress.min.js.map +gzipsize.js test -coverage \ No newline at end of file +coverage diff --git a/README.md b/README.md index e9da676..00d68da 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![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) ![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 diff --git a/frontexpress.js b/frontexpress.js index 07bfa38..1c2f23a 100644 --- a/frontexpress.js +++ b/frontexpress.js @@ -163,8 +163,6 @@ var Requester = function () { statusText = _ref.statusText, errorThrown = _ref.errorThrown; - // Removed for reducing size of frontexpress - // const errors = this._analyzeErrors({status, statusText, errorThrown}); reject(request, { status: status, statusText: statusText, @@ -220,48 +218,6 @@ var Requester = function () { 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; }(); @@ -509,12 +465,12 @@ var Route = function () { return this.router.baseUri; } - if (this.router.baseUri && this.uriPart) { - return (this.router.baseUri.trim() + this.uriPart.trim()).replace(/\/{2,}/, '/'); - } - 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; @@ -528,6 +484,8 @@ var Route = function () { * @public */ +var error_middleware_message = 'method takes at least a middleware'; + var Router = function () { /** @@ -539,9 +497,7 @@ var Router = function () { function Router(uri) { classCallCheck(this, Router); - if (uri) { - this._baseUri = uri; - } + this._baseUri = uri; this._routes = []; } @@ -576,36 +532,24 @@ var Router = function () { key: 'routes', value: function routes(uri, method) { return this._routes.filter(function (route) { - if (!route.uri && !route.method) { - return true; - } - if (route.method !== method) { + if (route.method && route.method !== method) { return false; } - if (!route.uri) { + if (!route.uri || !uri) { return true; } - var uriToCheck = uri; - //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 - var hashIndex = uriToCheck.indexOf('#'); - if (hashIndex >= 0) { - uriToCheck = uriToCheck.slice(0, hashIndex); - } + var match = /^(.*)\?.*#.*|(.*)(?=\?|#)|(.*[^\?#])$/.exec(uri); + var baseUriToCheck = match[1] || match[2] || match[3]; 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', value: function use(middleware) { 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)); @@ -673,19 +617,11 @@ var Router = function () { args[_key] = arguments[_key]; } - if (args.length === 0) { - throw new TypeError('use all method takes at least a middleware'); - } - var middleware = void 0; + var _toParameters = toParameters(args), + middleware = _toParameters.middleware; - if (args.length === 1) { - middleware = args[0]; - } else { - middleware = args[1]; - } - - if (!(middleware instanceof Middleware) && typeof middleware !== 'function') { - throw new TypeError('use all method takes at least a middleware'); + if (!middleware) { + throw new TypeError(error_middleware_message); } var _iteratorNormalCompletion = true; @@ -718,22 +654,10 @@ var Router = function () { }, { key: 'baseUri', set: function set$$1(uri) { - if (!uri) { - return; - } - - 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()); + if (this._baseUri) { + throw new TypeError('base uri is already set'); } + this._baseUri = uri; } /** @@ -788,28 +712,19 @@ try { args[_key2] = arguments[_key2]; } - if (args.length === 0) { - throw new TypeError('use ' + methodName + ' method takes at least a middleware'); - } - var uri = void 0, - middleware = void 0; + var _toParameters2 = toParameters(args), + baseUri = _toParameters2.baseUri, + middleware = _toParameters2.middleware; - if (args.length === 1) { - middleware = args[0]; - } else { - uri = args[0]; - middleware = args[1]; + if (!middleware) { + throw new TypeError(error_middleware_message); } - if (!(middleware instanceof Middleware) && typeof middleware !== 'function') { - throw new TypeError('use ' + methodName + ' method takes at least a middleware'); + if (baseUri && this._baseUri && this._baseUri instanceof RegExp) { + throw new TypeError('router cannot mix uri/regexp'); } - if (uri && this._baseUri && this._baseUri instanceof RegExp) { - throw new TypeError('router contains a regexp cannot mix with route uri/regexp'); - } - - this._add(new Route(this, uri, method, middleware)); + this._add(new Route(this, baseUri, method, middleware)); return this; }; @@ -1000,25 +915,14 @@ var Application = function () { args[_key2] = arguments[_key2]; } - var errorMsg = 'use method takes at least a middleware or a router'; - var baseUri = void 0, - middleware = void 0, - router = void 0, - 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]; - } + var _toParameters = toParameters(args), + baseUri = _toParameters.baseUri, + router = _toParameters.router, + middleware = _toParameters.middleware; - if (which instanceof Router) { - router = which; + if (router) { router.baseUri = baseUri; - } else if (which instanceof Middleware || typeof which === 'function') { - middleware = which; + } else if (middleware) { router = new Router(baseUri); var _iteratorNormalCompletion = true; var _didIteratorError = false; @@ -1045,7 +949,7 @@ var Application = function () { } } } else { - throw new TypeError(errorMsg); + throw new TypeError('method takes at least a middleware or a router'); } this.routers.push(router); @@ -1287,27 +1191,17 @@ HTTP_METHODS.reduce(function (reqProto, method) { args[_key3] = arguments[_key3]; } - var baseUri = void 0, - middleware = void 0, - which = void 0; - if (!args || args.length === 0) { - throw new TypeError(middlewareMethodName + ' method takes at least a middleware ' + (middlewareMethodName === 'get' ? 'or a string' : '')); - } else if (args.length === 1) { - which = args[0]; + var _toParameters2 = toParameters(args), + baseUri = _toParameters2.baseUri, + middleware = _toParameters2.middleware, + which = _toParameters2.which; - if (middlewareMethodName === 'get' && typeof which === 'string') { - return this.settings.get(which); - } - } else { - baseUri = args[0]; - which = args[1]; + if (middlewareMethodName === 'get' && typeof which === 'string') { + return this.settings.get(which); } - - if (!(which instanceof Middleware) && typeof which !== 'function') { - throw new TypeError(middlewareMethodName + ' method takes at least a middleware'); + if (!middleware) { + throw new TypeError('method takes a middleware ' + (middlewareMethodName === 'get' ? 'or a string' : '')); } - - middleware = which; var router = new Router(); router[middlewareMethodName](baseUri, middleware); @@ -1358,6 +1252,32 @@ HTTP_METHODS.reduce(function (reqProto, method) { return reqProto; }, 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. */ diff --git a/frontexpress.min.js b/frontexpress.min.js index a2abec2..f05fda5 100644 --- a/frontexpress.min.js +++ b/frontexpress.min.js @@ -1,2 +1,2 @@ -var frontexpress=function(){"use strict";var t=["GET","POST","PUT","DELETE"],e=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},r=function(){function t(t,e){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:"";e(this,t),this.name=r}return r(t,[{key:"next",value:function(){return!0}}]),t}(),u=function(){function t(r,i,n,a){e(this,t),this.router=r,this.uriPart=i,this.method=n,this.middleware=a,this.visited=!1}return r(t,[{key:"uri",get:function(){if(this.uriPart||this.method)return this.uriPart instanceof RegExp?this.uriPart:this.router.baseUri instanceof RegExp?this.router.baseUri:this.router.baseUri&&this.uriPart?(this.router.baseUri.trim()+this.uriPart.trim()).replace(/\/{2,}/,"/"):this.router.baseUri?this.router.baseUri.trim():this.uriPart}}]),t}(),d=function(){function i(t){e(this,i),t&&(this._baseUri=t),this._routes=[]}return r(i,[{key:"_add",value:function(t){return this._routes.push(t),this}},{key:"routes",value:function(t,e){return this._routes.filter(function(r){if(!r.uri&&!r.method)return!0;if(r.method!==e)return!1;if(!r.uri)return!0;var i=t,n=i.indexOf("?");n>=0&&(i=i.slice(0,n));var a=i.indexOf("#");return a>=0&&(i=i.slice(0,a)),r.uri instanceof RegExp?i.match(r.uri):r.uri===i})}},{key:"visited",value:function(){return this._routes.filter(function(t){return t.visited})}},{key:"use",value:function(t){if(!(t instanceof s)&&"function"!=typeof t)throw new TypeError("use method takes at least a middleware");return this._add(new u(this,void 0,void 0,t)),this}},{key:"all",value:function(){for(var e=arguments.length,r=Array(e),i=0;i0&&void 0!==arguments[0]?arguments[0]:window.location.pathname+window.location.search,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"GET",r=[],i=!0,a=!1,o=void 0;try{for(var s,u=this.routers[Symbol.iterator]();!(i=(s=u.next()).done);i=!0){var d=s.value;r.push.apply(r,n(d.routes(t,e)))}}catch(t){a=!0,o=t}finally{try{!i&&u.return&&u.return()}finally{if(a)throw o}}return r}},{key:"_callMiddlewareMethod",value:function(t,e,r,i){if("exited"!==t){var n=!0,a=!1,o=void 0;try{for(var s,u=e[Symbol.iterator]();!(n=(s=u.next()).done);n=!0){var d=s.value;if("updated"===t&&(d.visited=r),d.middleware[t]){if(d.middleware[t](r,i),d.middleware.next&&!d.middleware.next())break}else if("entered"!==t){var h=!0,l=function(){h=!1};if(d.middleware(r,i,l),h)break}}}catch(t){a=!0,o=t}finally{try{!n&&u.return&&u.return()}finally{if(a)throw o}}}else{var f=!0,c=!1,v=void 0;try{for(var y,w=this.routers[Symbol.iterator]();!(f=(y=w.next()).done);f=!0){var p=y.value,m=!0,g=!1,x=void 0;try{for(var b,T=p.visited()[Symbol.iterator]();!(m=(b=T.next()).done);m=!0){var _=b.value;_.middleware.exited&&(_.middleware.exited(_.visited),_.visited=null)}}catch(t){g=!0,x=t}finally{try{!m&&T.return&&T.return()}finally{if(g)throw x}}}}catch(t){c=!0,v=t}finally{try{!f&&w.return&&w.return()}finally{if(c)throw v}}}}},{key:"_fetch",value:function(t,e,r){var i=this,n=t.method,a=t.uri,o=t.headers,s=t.data,u=t.history,d=this.get("http "+n+" transformer");d&&(a=d.uri?d.uri({uri:a,headers:o,data:s}):a,o=d.headers?d.headers({uri:a,headers:o,data:s}):o,s=d.data?d.data({uri:a,headers:o,data:s}):s),this._callMiddlewareMethod("exited");var h=this._routes(a,n);this._callMiddlewareMethod("entered",h,t),this.settings.get("http requester").fetch(t,function(t,r){u&&window.history.pushState({request:t,response:r},u.title,u.uri),i._callMiddlewareMethod("updated",h,t,r),e&&e(t,r)},function(t,e){i._callMiddlewareMethod("failed",h,t,e),r&&r(t,e)})}}]),i}();t.reduce(function(t,e){var r=e.toLowerCase();t[r]=function(){for(var t=arguments.length,e=Array(t),i=0;i0){if(1===t.length){var o=n(t,1);a=o[0]}else{var s=n(t,2);e=s[0],a=s[1]}a instanceof l?i=a:(a instanceof u||"function"==typeof a)&&(r=a)}return{baseUri:e,middleware:r,router:i,which:a}}var e=["GET","POST","PUT","DELETE"],r=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},i=function(){function t(t,e){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:"";r(this,t),this.name=e}return i(t,[{key:"next",value:function(){return!0}}]),t}(),d=function(){function t(e,i,n,a){r(this,t),this.router=e,this.uriPart=i,this.method=n,this.middleware=a,this.visited=!1}return i(t,[{key:"uri",get:function(){if(this.uriPart||this.method){if(this.uriPart instanceof RegExp)return this.uriPart;if(this.router.baseUri instanceof RegExp)return this.router.baseUri;if(this.router.baseUri){var t=this.router.baseUri.trim();return this.uriPart?(t+this.uriPart.trim()).replace(/\/{2,}/,"/"):t}return this.uriPart}}}]),t}(),h="method takes at least a middleware",l=function(){function n(t){r(this,n),this._baseUri=t,this._routes=[]}return i(n,[{key:"_add",value:function(t){return this._routes.push(t),this}},{key:"routes",value:function(t,e){return this._routes.filter(function(r){if(r.method&&r.method!==e)return!1;if(!r.uri||!t)return!0;var i=/^(.*)\?.*#.*|(.*)(?=\?|#)|(.*[^\?#])$/.exec(t),n=i[1]||i[2]||i[3];return r.uri instanceof RegExp?n.match(r.uri):r.uri===n})}},{key:"visited",value:function(){return this._routes.filter(function(t){return t.visited})}},{key:"use",value:function(t){if(!(t instanceof u)&&"function"!=typeof t)throw new TypeError(h);return this._add(new d(this,void 0,void 0,t)),this}},{key:"all",value:function(){for(var r=arguments.length,i=Array(r),n=0;n0&&void 0!==arguments[0]?arguments[0]:window.location.pathname+window.location.search,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"GET",r=[],i=!0,n=!1,o=void 0;try{for(var s,u=this.routers[Symbol.iterator]();!(i=(s=u.next()).done);i=!0){var d=s.value;r.push.apply(r,a(d.routes(t,e)))}}catch(t){n=!0,o=t}finally{try{!i&&u.return&&u.return()}finally{if(n)throw o}}return r}},{key:"_callMiddlewareMethod",value:function(t,e,r,i){if("exited"!==t){var n=!0,a=!1,o=void 0;try{for(var s,u=e[Symbol.iterator]();!(n=(s=u.next()).done);n=!0){var d=s.value;if("updated"===t&&(d.visited=r),d.middleware[t]){if(d.middleware[t](r,i),d.middleware.next&&!d.middleware.next())break}else if("entered"!==t){var h=!0,l=function(){h=!1};if(d.middleware(r,i,l),h)break}}}catch(t){a=!0,o=t}finally{try{!n&&u.return&&u.return()}finally{if(a)throw o}}}else{var f=!0,c=!1,v=void 0;try{for(var y,w=this.routers[Symbol.iterator]();!(f=(y=w.next()).done);f=!0){var p=y.value,m=!0,g=!1,b=void 0;try{for(var x,M=p.visited()[Symbol.iterator]();!(m=(x=M.next()).done);m=!0){var T=x.value;T.middleware.exited&&(T.middleware.exited(T.visited),T.visited=null)}}catch(t){g=!0,b=t}finally{try{!m&&M.return&&M.return()}finally{if(g)throw b}}}}catch(t){c=!0,v=t}finally{try{!f&&w.return&&w.return()}finally{if(c)throw v}}}}},{key:"_fetch",value:function(t,e,r){var i=this,n=t.method,a=t.uri,o=t.headers,s=t.data,u=t.history,d=this.get("http "+n+" transformer");d&&(a=d.uri?d.uri({uri:a,headers:o,data:s}):a,o=d.headers?d.headers({uri:a,headers:o,data:s}):o,s=d.data?d.data({uri:a,headers:o,data:s}):s),this._callMiddlewareMethod("exited");var h=this._routes(a,n);this._callMiddlewareMethod("entered",h,t),this.settings.get("http requester").fetch(t,function(t,r){u&&window.history.pushState({request:t,response:r},u.title,u.uri),i._callMiddlewareMethod("updated",h,t,r),e&&e(t,r)},function(t,e){i._callMiddlewareMethod("failed",h,t,e),r&&r(t,e)})}}]),n}();e.reduce(function(e,r){var i=r.toLowerCase();e[i]=function(){for(var e=arguments.length,r=Array(e),n=0;n {\n resolve(\n request,\n {\n status: 200,\n statusText: 'OK',\n responseText\n }\n );\n };\n\n const fail = ({status, statusText, errorThrown}) => {\n // Removed for reducing size of frontexpress\n // const errors = this._analyzeErrors({status, statusText, errorThrown});\n reject(\n request,\n {\n status,\n statusText,\n errorThrown,\n errors: `HTTP ${status} ${statusText?statusText:''}`\n }\n );\n };\n\n const xmlhttp = new XMLHttpRequest();\n xmlhttp.onreadystatechange = () => {\n if (xmlhttp.readyState === 4) {\n if (xmlhttp.status === 200) {\n success(xmlhttp.responseText);\n } else {\n fail({status: xmlhttp.status, statusText: xmlhttp.statusText});\n }\n }\n };\n try {\n xmlhttp.open(method, uri, true);\n if (headers) {\n for (const header of Object.keys(headers)) {\n xmlhttp.setRequestHeader(header, headers[header]);\n }\n }\n if (data) {\n xmlhttp.send(data);\n } else {\n xmlhttp.send();\n }\n } catch (errorThrown) {\n fail({errorThrown});\n }\n }\n\n // Removed for reducing size of frontexpress\n // /**\n // * Analyse response errors.\n // *\n // * @private\n // */\n\n // _analyzeErrors(response) {\n // // manage exceptions\n // if (response.errorThrown) {\n // if (response.errorThrown.name === 'SyntaxError') {\n // return 'Problem during data decoding [JSON]';\n // }\n // if (response.errorThrown.name === 'TimeoutError') {\n // return 'Server is taking too long to reply';\n // }\n // if (response.errorThrown.name === 'AbortError') {\n // return 'Request cancelled on server';\n // }\n // if (response.errorThrown.name === 'NetworkError') {\n // return 'A network error occurred';\n // }\n // throw response.errorThrown;\n // }\n\n // // manage status\n // if (response.status === 0) {\n // return 'Server access problem. Check your network connection';\n // }\n // if (response.status === 401) {\n // return 'Your session has expired, Please reconnect. [code: 401]';\n // }\n // if (response.status === 404) {\n // return 'Page not found on server. [code: 404]';\n // }\n // if (response.status === 500) {\n // return 'Internal server error. [code: 500]';\n // }\n // return `Unknown error. ${response.statusText?response.statusText:''}`;\n // }\n}\n","/**\n * Module dependencies.\n * @private\n */\n\nimport Requester from './requester';\n\n\n/**\n * Settings object.\n * @private\n */\n\nexport default class Settings {\n\n\n /**\n * Initialize the settings.\n *\n * - setup default configuration\n *\n * @private\n */\n\n constructor() {\n // default settings\n this.settings = {\n 'http requester': new Requester(),\n\n 'http GET transformer': {\n uri({uri, headers, data}) {\n if (!data) {\n return uri;\n }\n let [uriWithoutAnchor, anchor] = [uri, ''];\n const match = /^(.*)(#.*)$/.exec(uri);\n if (match) {\n [,uriWithoutAnchor, anchor] = /^(.*)(#.*)$/.exec(uri);\n }\n uriWithoutAnchor = Object.keys(data).reduce((gUri, d, index) => {\n gUri += `${(index === 0 && gUri.indexOf('?') === -1)?'?':'&'}${d}=${data[d]}`;\n return gUri;\n }, uriWithoutAnchor);\n return uriWithoutAnchor + anchor;\n }\n }\n };\n\n this.rules = {\n 'http requester': (requester) => {\n if(typeof requester.fetch !== 'function') {\n throw new TypeError('setting http requester has no fetch method');\n }\n }\n };\n }\n\n\n /**\n * Assign `setting` to `val`\n *\n * @param {String} setting\n * @param {*} [val]\n * @private\n */\n\n set(name, value) {\n const checkRules = this.rules[name];\n if (checkRules) {\n checkRules(value);\n }\n this.settings[name] = value;\n }\n\n\n /**\n * Return `setting`'s value.\n *\n * @param {String} setting\n * @private\n */\n\n get(name) {\n return this.settings[name];\n }\n};\n","/**\n * Middleware object.\n * @public\n */\n\nexport default class Middleware {\n\n\n /**\n * Middleware initialization\n *\n * @param {String} middleware name\n */\n\n constructor(name='') {\n this.name = name;\n }\n\n /**\n * Invoked by the app before an ajax request is sent or\n * during the DOM loading (document.readyState === 'loading').\n * See Application#_callMiddlewareEntered documentation for details.\n *\n * Override this method to add your custom behaviour\n *\n * @param {Object} request\n * @public\n */\n\n // entered(request) { }\n\n\n /**\n * Invoked by the app before a new ajax request is sent or before the DOM is unloaded.\n * See Application#_callMiddlewareExited documentation for details.\n *\n * Override this method to add your custom behaviour\n *\n * @param {Object} request\n * @public\n */\n\n // exited(request) { }\n\n\n /**\n * Invoked by the app after an ajax request has responded or on DOM ready\n * (document.readyState === 'interactive').\n * See Application#_callMiddlewareUpdated documentation for details.\n *\n * Override this method to add your custom behaviour\n *\n * @param {Object} request\n * @param {Object} response\n * @public\n */\n\n // updated(request, response) { }\n\n\n /**\n * Invoked by the app when an ajax request has failed.\n *\n * Override this method to add your custom behaviour\n *\n * @param {Object} request\n * @param {Object} response\n * @public\n */\n // failed(request, response) { }\n\n\n /**\n * Allow the hand over to the next middleware object or function.\n *\n * Override this method and return `false` to break execution of\n * middleware chain.\n *\n * @return {Boolean} `true` by default\n *\n * @public\n */\n\n next() {\n return true;\n }\n}\n","/**\n * Module dependencies.\n * @private\n */\n\nimport HTTP_METHODS from './methods';\nimport Middleware from './middleware';\n\n\n/**\n * Route object.\n * @private\n */\n\nexport class Route {\n\n\n /**\n * Initialize the route.\n *\n * @private\n */\n\n constructor(router, uriPart, method, middleware) {\n this.router = router;\n this.uriPart = uriPart;\n this.method = method;\n this.middleware = middleware;\n this.visited = false;\n }\n\n\n /**\n * Return route's uri.\n *\n * @private\n */\n\n get uri() {\n if (!this.uriPart && !this.method) {\n return undefined;\n }\n\n if (this.uriPart instanceof RegExp) {\n return this.uriPart;\n }\n\n if (this.router.baseUri instanceof RegExp) {\n return this.router.baseUri;\n }\n\n if (this.router.baseUri && this.uriPart) {\n return (this.router.baseUri.trim() + this.uriPart.trim()).replace(/\\/{2,}/, '/');\n }\n\n if (this.router.baseUri) {\n return this.router.baseUri.trim();\n }\n\n return this.uriPart;\n }\n}\n\n\n/**\n * Router object.\n * @public\n */\n\nexport default class Router {\n\n\n /**\n * Initialize the router.\n *\n * @private\n */\n\n constructor(uri) {\n if (uri) {\n this._baseUri = uri;\n }\n this._routes = [];\n }\n\n\n /**\n * Do some checks and set _baseUri.\n *\n * @private\n */\n\n set baseUri(uri) {\n if (!uri) {\n return;\n }\n\n if (!this._baseUri) {\n this._baseUri = uri;\n return;\n }\n\n if (this._baseUri instanceof RegExp) {\n throw new TypeError(`the router already contains a regexp uri ${this._baseUri.toString()} It cannot be mixed with ${uri.toString()}`);\n }\n\n if (uri instanceof RegExp) {\n throw new TypeError(`the router already contains an uri ${this._baseUri.toString()} It cannot be mixed with regexp ${uri.toString()}`);\n }\n }\n\n\n /**\n * Return router's _baseUri.\n *\n * @private\n */\n\n get baseUri() {\n return this._baseUri;\n }\n\n\n /**\n * Add a route to the router.\n *\n * @private\n */\n\n _add(route) {\n this._routes.push(route);\n return this;\n }\n\n\n /**\n * Gather routes from routers filtered by _uri_ and HTTP _method_.\n *\n * @private\n */\n\n routes(uri, method) {\n return this._routes.filter((route) => {\n if (!route.uri && !route.method) {\n return true;\n }\n if (route.method !== method) {\n return false;\n }\n\n if (!route.uri) {\n return true;\n }\n\n let uriToCheck = uri;\n\n //remove query string from uri to test\n const questionMarkIndex = uriToCheck.indexOf('?');\n if (questionMarkIndex >= 0) {\n uriToCheck = uriToCheck.slice(0, questionMarkIndex);\n }\n\n //remove anchor from uri to test\n const hashIndex = uriToCheck.indexOf('#');\n if (hashIndex >= 0) {\n uriToCheck = uriToCheck.slice(0, hashIndex);\n }\n\n if (route.uri instanceof RegExp) {\n return uriToCheck.match(route.uri);\n }\n\n return route.uri === uriToCheck;\n });\n }\n\n\n /**\n * Gather visited routes from routers.\n *\n * @private\n */\n\n visited() {\n return this._routes.filter((route) => {\n return route.visited;\n });\n }\n\n\n /**\n * Use the given middleware function or object on this router.\n *\n * // middleware function\n * router.use((req, res, next) => {console.log('Hello')});\n *\n * // middleware object\n * router.use(new Middleware());\n *\n * @param {Middleware|Function} middleware object or function\n * @return {Router} for chaining\n *\n * @public\n */\n\n use(middleware) {\n if (!(middleware instanceof Middleware) && (typeof middleware !== 'function') ) {\n throw new TypeError('use method takes at least a middleware');\n }\n\n this._add(new Route(this, undefined, undefined, middleware));\n\n return this;\n }\n\n\n /**\n * Use the given middleware function or object on this router for\n * all HTTP methods.\n *\n * // middleware function\n * router.all((req, res, next) => {console.log('Hello')});\n *\n * // middleware object\n * router.all(new Middleware());\n *\n * @param {Middleware|Function} middleware object or function\n * @return {Router} for chaining\n *\n * @public\n */\n\n all(...args) {\n if (args.length === 0) {\n throw new TypeError('use all method takes at least a middleware');\n }\n let middleware;\n\n if (args.length === 1) {\n [middleware,] = args;\n } else {\n [, middleware,] = args;\n }\n\n if (!(middleware instanceof Middleware) && (typeof middleware !== 'function') ) {\n throw new TypeError('use all method takes at least a middleware');\n }\n\n for (const method of HTTP_METHODS) {\n this[method.toLowerCase()](...args);\n }\n return this;\n }\n}\n\nfor (const method of HTTP_METHODS) {\n\n\n /**\n * Use the given middleware function or object, with optional _uri_ on\n * HTTP methods: get, post, put, delete...\n * Default _uri_ is \"/\".\n *\n * // middleware function will be applied on path \"/\"\n * router.get((req, res, next) => {console.log('Hello')});\n *\n * // middleware object will be applied on path \"/\" and\n * router.get(new Middleware());\n *\n * // middleware function will be applied on path \"/user\"\n * router.post('/user', (req, res, next) => {console.log('Hello')});\n *\n * // middleware object will be applied on path \"/user\" and\n * router.post('/user', new Middleware());\n *\n * @param {String} uri\n * @param {Middleware|Function} middleware object or function\n * @return {Router} for chaining\n * @public\n */\n\n const methodName = method.toLowerCase();\n Router.prototype[methodName] = function(...args) {\n if (args.length === 0) {\n throw new TypeError(`use ${methodName} method takes at least a middleware`);\n }\n let uri, middleware;\n\n if (args.length === 1) {\n [middleware,] = args;\n } else {\n [uri, middleware,] = args;\n }\n\n if (!(middleware instanceof Middleware) && (typeof middleware !== 'function') ) {\n throw new TypeError(`use ${methodName} method takes at least a middleware`);\n }\n\n if (uri && this._baseUri && this._baseUri instanceof RegExp) {\n throw new TypeError('router contains a regexp cannot mix with route uri/regexp');\n }\n\n this._add(new Route(this, uri, method, middleware));\n\n return this;\n };\n}\n","/**\n * Module dependencies.\n * @private\n */\n\nimport HTTP_METHODS from './methods';\nimport Settings from './settings';\nimport Router, {Route} from './router';\nimport Middleware from './middleware';\n\n\n/**\n * Application class.\n */\n\nexport default class Application {\n\n\n /**\n * Initialize the application.\n *\n * - setup default configuration\n *\n * @private\n */\n\n constructor() {\n this.routers = [];\n this.isDOMLoaded = false;\n this.isDOMReady = false;\n this.settings = new Settings();\n }\n\n\n /**\n * Assign `setting` to `val`, or return `setting`'s value.\n *\n * app.set('foo', 'bar');\n * app.set('foo');\n * // => \"bar\"\n *\n * @param {String} setting\n * @param {*} [val]\n * @return {app} for chaining\n * @public\n */\n\n set(...args) {\n // get behaviour\n if (args.length === 1) {\n return this.settings.get([args]);\n }\n\n // set behaviour\n const [name, value] = args;\n this.settings.set(name, value);\n\n return this;\n }\n\n\n /**\n * Listen for DOM initialization and history state changes.\n *\n * The callback function is called once the DOM has\n * the `document.readyState` equals to 'interactive'.\n *\n * app.listen(()=> {\n * console.log('App is listening requests');\n * console.log('DOM is ready!');\n * });\n *\n *\n * @param {Function} callback\n * @public\n */\n\n listen(callback) {\n window.onbeforeunload = () => {\n this._callMiddlewareMethod('exited');\n };\n\n window.onpopstate = (event) => {\n if (event.state) {\n const {request, response} = event.state;\n const currentRoutes = this._routes(request.uri, request.method);\n\n this._callMiddlewareMethod('entered', currentRoutes, request);\n this._callMiddlewareMethod('updated', currentRoutes, request, response);\n }\n };\n\n document.onreadystatechange = () => {\n const request = {method: 'GET', uri: window.location.pathname + window.location.search};\n const response = {status: 200, statusText: 'OK'};\n const currentRoutes = this._routes();\n // DOM state\n if (document.readyState === 'loading' && !this.isDOMLoaded) {\n this.isDOMLoaded = true;\n this._callMiddlewareMethod('entered', currentRoutes, request);\n } else if (document.readyState === 'interactive' && !this.isDOMReady) {\n if (!this.isDOMLoaded) {\n this.isDOMLoaded = true;\n this._callMiddlewareMethod('entered', currentRoutes, request);\n }\n this.isDOMReady = true;\n this._callMiddlewareMethod('updated', currentRoutes, request, response);\n if (callback) {\n callback(request, response);\n }\n }\n };\n }\n\n\n /**\n * Returns a new `Router` instance for the _uri_.\n * See the Router api docs for details.\n *\n * app.route('/');\n * // => new Router instance\n *\n * @param {String} uri\n * @return {Router} for chaining\n *\n * @public\n */\n\n route(uri) {\n const router = new Router(uri);\n this.routers.push(router);\n return router;\n }\n\n\n /**\n * Use the given middleware function or object, with optional _uri_.\n * Default _uri_ is \"/\".\n *\n * // middleware function will be applied on path \"/\"\n * app.use((req, res, next) => {console.log('Hello')});\n *\n * // middleware object will be applied on path \"/\"\n * app.use(new Middleware());\n *\n * @param {String} uri\n * @param {Middleware|Function} middleware object or function\n * @return {app} for chaining\n *\n * @public\n */\n\n use(...args) {\n const errorMsg = 'use method takes at least a middleware or a router';\n let baseUri, middleware, router, which;\n if (!args || args.length === 0) {\n throw new TypeError(errorMsg);\n } else if (args.length === 1) {\n [which,] = args;\n } else {\n [baseUri, which,] = args;\n }\n\n if (which instanceof Router) {\n router = which;\n router.baseUri = baseUri;\n } else if ((which instanceof Middleware) || (typeof which === 'function')) {\n middleware = which;\n router = new Router(baseUri);\n for (const method of HTTP_METHODS) {\n router[method.toLowerCase()](middleware);\n }\n } else {\n throw new TypeError(errorMsg);\n }\n this.routers.push(router);\n\n return this;\n }\n\n\n /**\n * Gather routes from all routers filtered by _uri_ and HTTP _method_.\n * See Router#routes() documentation for details.\n *\n * @private\n */\n\n _routes(uri=window.location.pathname + window.location.search, method='GET') {\n const currentRoutes = [];\n for (const router of this.routers) {\n currentRoutes.push(...router.routes(uri, method));\n }\n\n return currentRoutes;\n }\n\n\n /**\n * Call `Middleware` method or middleware function on _currentRoutes_.\n *\n * @private\n */\n\n _callMiddlewareMethod(meth, currentRoutes, request, response) {\n if (meth === 'exited') {\n // currentRoutes, request, response params not needed\n for (const router of this.routers) {\n for (const route of router.visited()) {\n if (route.middleware.exited) {\n route.middleware.exited(route.visited);\n route.visited = null;\n }\n }\n }\n return;\n }\n\n for (const route of currentRoutes) {\n if (meth === 'updated') {\n route.visited = request;\n }\n\n if (route.middleware[meth]) {\n route.middleware[meth](request, response);\n if (route.middleware.next && !route.middleware.next()) {\n break;\n }\n } else if (meth !== 'entered') {\n // calls middleware method\n let breakMiddlewareLoop = true;\n const next = () => {\n breakMiddlewareLoop = false;\n };\n route.middleware(request, response, next);\n if (breakMiddlewareLoop) {\n break;\n }\n }\n }\n }\n\n\n /**\n * Make an ajax request. Manage History#pushState if history object set.\n *\n * @private\n */\n\n _fetch(request, resolve, reject) {\n let {method, uri, headers, data, history} = request;\n\n const httpMethodTransformer = this.get(`http ${method} transformer`);\n if (httpMethodTransformer) {\n uri = httpMethodTransformer.uri ? httpMethodTransformer.uri({uri, headers, data}) : uri;\n headers = httpMethodTransformer.headers ? httpMethodTransformer.headers({uri, headers, data}) : headers;\n data = httpMethodTransformer.data ? httpMethodTransformer.data({uri, headers, data}) : data;\n }\n\n // calls middleware exited method\n this._callMiddlewareMethod('exited');\n\n // gathers all routes impacted by the uri\n const currentRoutes = this._routes(uri, method);\n\n // calls middleware entered method\n this._callMiddlewareMethod('entered', currentRoutes, request);\n\n // invokes http request\n this.settings.get('http requester').fetch(request,\n (req, res) => {\n if (history) {\n window.history.pushState({request: req, response: res}, history.title, history.uri);\n }\n this._callMiddlewareMethod('updated', currentRoutes, req, res);\n if (resolve) {\n resolve(req, res);\n }\n },\n (req, res) => {\n this._callMiddlewareMethod('failed', currentRoutes, req, res);\n if (reject) {\n reject(req, res);\n }\n });\n }\n}\n\nHTTP_METHODS.reduce((reqProto, method) => {\n\n\n /**\n * Use the given middleware function or object, with optional _uri_ on\n * HTTP methods: get, post, put, delete...\n * Default _uri_ is \"/\".\n *\n * // middleware function will be applied on path \"/\"\n * app.get((req, res, next) => {console.log('Hello')});\n *\n * // middleware object will be applied on path \"/\" and\n * app.get(new Middleware());\n *\n * // get a setting value\n * app.set('foo', 'bar');\n * app.get('foo');\n * // => \"bar\"\n *\n * @param {String} uri or setting\n * @param {Middleware|Function} middleware object or function\n * @return {app} for chaining\n * @public\n */\n\n const middlewareMethodName = method.toLowerCase();\n reqProto[middlewareMethodName] = function(...args) {\n let baseUri, middleware, which;\n if (!args || args.length === 0) {\n throw new TypeError(`${middlewareMethodName} method takes at least a middleware ${middlewareMethodName === 'get' ? 'or a string' : ''}`);\n } else if (args.length === 1) {\n [which] = args;\n if (middlewareMethodName === 'get' && typeof which === 'string') {\n return this.settings.get(which);\n }\n } else {\n [baseUri, which,] = args;\n }\n\n if (!(which instanceof Middleware) && (typeof which !== 'function')) {\n throw new TypeError(`${middlewareMethodName} method takes at least a middleware`);\n }\n\n middleware = which;\n const router = new Router();\n router[middlewareMethodName](baseUri, middleware);\n\n this.routers.push(router);\n\n return this;\n };\n\n /**\n * Ajax request (get, post, put, delete...).\n *\n * // HTTP GET method\n * httpGet('/route1');\n *\n * // HTTP GET method\n * httpGet({uri: '/route1', data: {'p1': 'val1'});\n * // uri invoked => /route1?p1=val1\n *\n * // HTTP GET method with browser history management\n * httpGet({uri: '/api/users', history: {state: {foo: \"bar\"}, title: 'users page', uri: '/view/users'});\n *\n * Samples above can be applied on other HTTP methods.\n *\n * @param {String|Object} uri or object containing uri, http headers, data, history\n * @param {Function} success callback\n * @param {Function} failure callback\n * @public\n */\n const httpMethodName = 'http'+method.charAt(0).toUpperCase() + method.slice(1).toLowerCase();\n reqProto[httpMethodName] = function(request, resolve, reject) {\n let {uri, headers, data, history} = request;\n if (!uri) {\n uri = request;\n }\n return this._fetch({\n uri,\n method,\n headers,\n data,\n history\n }, resolve, reject);\n };\n\n return reqProto;\n}, Application.prototype);\n","/**\n * Module dependencies.\n */\n\nimport Application from './application';\nimport Router from './router';\nimport Middleware from './middleware';\n\n\n/**\n * Create a frontexpress application.\n *\n * @return {Function}\n * @api public\n */\n\nconst frontexpress = () => new Application();\n\n/**\n * Expose Router, Middleware constructors.\n */\nfrontexpress.Router = (baseUri) => new Router(baseUri);\nfrontexpress.Middleware = Middleware;\n\nexport default frontexpress;\n"],"names":["Requester","request","resolve","reject","method","uri","headers","data","success","responseText","fail","status","statusText","errorThrown","xmlhttp","XMLHttpRequest","onreadystatechange","readyState","open","Object","keys","header","setRequestHeader","send","Settings","settings","uriWithoutAnchor","anchor","match","exec","reduce","gUri","d","index","indexOf","rules","requester","fetch","TypeError","name","value","checkRules","this","Middleware","Route","router","uriPart","middleware","visited","RegExp","baseUri","trim","replace","Router","_baseUri","_routes","route","push","filter","uriToCheck","questionMarkIndex","slice","hashIndex","_add","undefined","args","length","HTTP_METHODS","toLowerCase","toString","methodName","prototype","Application","routers","isDOMLoaded","isDOMReady","get","set","callback","onbeforeunload","_callMiddlewareMethod","onpopstate","event","state","response","currentRoutes","_this","window","location","pathname","search","document","errorMsg","which","routes","meth","next","breakMiddlewareLoop","exited","history","httpMethodTransformer","req","res","pushState","title","reqProto","middlewareMethodName","httpMethodName","charAt","toUpperCase","_fetch","frontexpress"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":null,"sources":["lib/application.js","lib/methods.js","lib/requester.js","lib/settings.js","lib/middleware.js","lib/router.js","lib/frontexpress.js"],"sourcesContent":["/**\n * Module dependencies.\n * @private\n */\n\nimport HTTP_METHODS from './methods';\nimport Settings from './settings';\nimport Router, {Route} from './router';\nimport Middleware from './middleware';\n\n\n/**\n * Application class.\n */\n\nexport default class Application {\n\n\n /**\n * Initialize the application.\n *\n * - setup default configuration\n *\n * @private\n */\n\n constructor() {\n this.routers = [];\n this.isDOMLoaded = false;\n this.isDOMReady = false;\n this.settings = new Settings();\n }\n\n\n /**\n * Assign `setting` to `val`, or return `setting`'s value.\n *\n * app.set('foo', 'bar');\n * app.set('foo');\n * // => \"bar\"\n *\n * @param {String} setting\n * @param {*} [val]\n * @return {app} for chaining\n * @public\n */\n\n set(...args) {\n // get behaviour\n if (args.length === 1) {\n return this.settings.get([args]);\n }\n\n // set behaviour\n const [name, value] = args;\n this.settings.set(name, value);\n\n return this;\n }\n\n\n /**\n * Listen for DOM initialization and history state changes.\n *\n * The callback function is called once the DOM has\n * the `document.readyState` equals to 'interactive'.\n *\n * app.listen(()=> {\n * console.log('App is listening requests');\n * console.log('DOM is ready!');\n * });\n *\n *\n * @param {Function} callback\n * @public\n */\n\n listen(callback) {\n window.onbeforeunload = () => {\n this._callMiddlewareMethod('exited');\n };\n\n window.onpopstate = (event) => {\n if (event.state) {\n const {request, response} = event.state;\n const currentRoutes = this._routes(request.uri, request.method);\n\n this._callMiddlewareMethod('entered', currentRoutes, request);\n this._callMiddlewareMethod('updated', currentRoutes, request, response);\n }\n };\n\n document.onreadystatechange = () => {\n const request = {method: 'GET', uri: window.location.pathname + window.location.search};\n const response = {status: 200, statusText: 'OK'};\n const currentRoutes = this._routes();\n // DOM state\n if (document.readyState === 'loading' && !this.isDOMLoaded) {\n this.isDOMLoaded = true;\n this._callMiddlewareMethod('entered', currentRoutes, request);\n } else if (document.readyState === 'interactive' && !this.isDOMReady) {\n if (!this.isDOMLoaded) {\n this.isDOMLoaded = true;\n this._callMiddlewareMethod('entered', currentRoutes, request);\n }\n this.isDOMReady = true;\n this._callMiddlewareMethod('updated', currentRoutes, request, response);\n if (callback) {\n callback(request, response);\n }\n }\n };\n }\n\n\n /**\n * Returns a new `Router` instance for the _uri_.\n * See the Router api docs for details.\n *\n * app.route('/');\n * // => new Router instance\n *\n * @param {String} uri\n * @return {Router} for chaining\n *\n * @public\n */\n\n route(uri) {\n const router = new Router(uri);\n this.routers.push(router);\n return router;\n }\n\n\n /**\n * Use the given middleware function or object, with optional _uri_.\n * Default _uri_ is \"/\".\n *\n * // middleware function will be applied on path \"/\"\n * app.use((req, res, next) => {console.log('Hello')});\n *\n * // middleware object will be applied on path \"/\"\n * app.use(new Middleware());\n *\n * @param {String} uri\n * @param {Middleware|Function} middleware object or function\n * @return {app} for chaining\n *\n * @public\n */\n\n use(...args) {\n let {baseUri, router, middleware} = toParameters(args);\n if (router) {\n router.baseUri = baseUri;\n } else if (middleware) {\n router = new Router(baseUri);\n for (const method of HTTP_METHODS) {\n router[method.toLowerCase()](middleware);\n }\n } else {\n throw new TypeError('method takes at least a middleware or a router');\n }\n this.routers.push(router);\n\n return this;\n }\n\n\n /**\n * Gather routes from all routers filtered by _uri_ and HTTP _method_.\n * See Router#routes() documentation for details.\n *\n * @private\n */\n\n _routes(uri=window.location.pathname + window.location.search, method='GET') {\n const currentRoutes = [];\n for (const router of this.routers) {\n currentRoutes.push(...router.routes(uri, method));\n }\n\n return currentRoutes;\n }\n\n\n /**\n * Call `Middleware` method or middleware function on _currentRoutes_.\n *\n * @private\n */\n\n _callMiddlewareMethod(meth, currentRoutes, request, response) {\n if (meth === 'exited') {\n // currentRoutes, request, response params not needed\n for (const router of this.routers) {\n for (const route of router.visited()) {\n if (route.middleware.exited) {\n route.middleware.exited(route.visited);\n route.visited = null;\n }\n }\n }\n return;\n }\n\n for (const route of currentRoutes) {\n if (meth === 'updated') {\n route.visited = request;\n }\n\n if (route.middleware[meth]) {\n route.middleware[meth](request, response);\n if (route.middleware.next && !route.middleware.next()) {\n break;\n }\n } else if (meth !== 'entered') {\n // calls middleware method\n let breakMiddlewareLoop = true;\n const next = () => {\n breakMiddlewareLoop = false;\n };\n route.middleware(request, response, next);\n if (breakMiddlewareLoop) {\n break;\n }\n }\n }\n }\n\n\n /**\n * Make an ajax request. Manage History#pushState if history object set.\n *\n * @private\n */\n\n _fetch(request, resolve, reject) {\n let {method, uri, headers, data, history} = request;\n\n const httpMethodTransformer = this.get(`http ${method} transformer`);\n if (httpMethodTransformer) {\n uri = httpMethodTransformer.uri ? httpMethodTransformer.uri({uri, headers, data}) : uri;\n headers = httpMethodTransformer.headers ? httpMethodTransformer.headers({uri, headers, data}) : headers;\n data = httpMethodTransformer.data ? httpMethodTransformer.data({uri, headers, data}) : data;\n }\n\n // calls middleware exited method\n this._callMiddlewareMethod('exited');\n\n // gathers all routes impacted by the uri\n const currentRoutes = this._routes(uri, method);\n\n // calls middleware entered method\n this._callMiddlewareMethod('entered', currentRoutes, request);\n\n // invokes http request\n this.settings.get('http requester').fetch(request,\n (req, res) => {\n if (history) {\n window.history.pushState({request: req, response: res}, history.title, history.uri);\n }\n this._callMiddlewareMethod('updated', currentRoutes, req, res);\n if (resolve) {\n resolve(req, res);\n }\n },\n (req, res) => {\n this._callMiddlewareMethod('failed', currentRoutes, req, res);\n if (reject) {\n reject(req, res);\n }\n });\n }\n}\n\nHTTP_METHODS.reduce((reqProto, method) => {\n\n\n /**\n * Use the given middleware function or object, with optional _uri_ on\n * HTTP methods: get, post, put, delete...\n * Default _uri_ is \"/\".\n *\n * // middleware function will be applied on path \"/\"\n * app.get((req, res, next) => {console.log('Hello')});\n *\n * // middleware object will be applied on path \"/\" and\n * app.get(new Middleware());\n *\n * // get a setting value\n * app.set('foo', 'bar');\n * app.get('foo');\n * // => \"bar\"\n *\n * @param {String} uri or setting\n * @param {Middleware|Function} middleware object or function\n * @return {app} for chaining\n * @public\n */\n\n const middlewareMethodName = method.toLowerCase();\n reqProto[middlewareMethodName] = function(...args) {\n let {baseUri, middleware, which} = toParameters(args);\n if (middlewareMethodName === 'get' && typeof which === 'string') {\n return this.settings.get(which);\n }\n if (!middleware) {\n throw new TypeError(`method takes a middleware ${middlewareMethodName === 'get' ? 'or a string' : ''}`);\n }\n const router = new Router();\n router[middlewareMethodName](baseUri, middleware);\n\n this.routers.push(router);\n\n return this;\n };\n\n /**\n * Ajax request (get, post, put, delete...).\n *\n * // HTTP GET method\n * httpGet('/route1');\n *\n * // HTTP GET method\n * httpGet({uri: '/route1', data: {'p1': 'val1'});\n * // uri invoked => /route1?p1=val1\n *\n * // HTTP GET method with browser history management\n * httpGet({uri: '/api/users', history: {state: {foo: \"bar\"}, title: 'users page', uri: '/view/users'});\n *\n * Samples above can be applied on other HTTP methods.\n *\n * @param {String|Object} uri or object containing uri, http headers, data, history\n * @param {Function} success callback\n * @param {Function} failure callback\n * @public\n */\n const httpMethodName = 'http'+method.charAt(0).toUpperCase() + method.slice(1).toLowerCase();\n reqProto[httpMethodName] = function(request, resolve, reject) {\n let {uri, headers, data, history} = request;\n if (!uri) {\n uri = request;\n }\n return this._fetch({\n uri,\n method,\n headers,\n data,\n history\n }, resolve, reject);\n };\n\n return reqProto;\n}, Application.prototype);\n\n\nexport function toParameters(args) {\n let baseUri, middleware, router, which;\n if (args && args.length > 0) {\n if (args.length === 1) {\n [which,] = args;\n } else {\n [baseUri, which,] = args;\n }\n\n if (which instanceof Router) {\n router = which;\n } else if ((which instanceof Middleware) || (typeof which === 'function')) {\n middleware = which;\n }\n }\n return {baseUri, middleware, router, which};\n}\n","/**\n * HTTP method list\n * @private\n */\n\n export default ['GET', 'POST', 'PUT', 'DELETE'];\n // not supported yet\n // HEAD', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH';\n","/**\n * Module dependencies.\n * @private\n */\n\nexport default class Requester {\n\n /**\n * Make an ajax request.\n *\n * @param {Object} request\n * @param {Function} success callback\n * @param {Function} failure callback\n * @private\n */\n\n fetch(request, resolve, reject) {\n const {method, uri, headers, data} = request;\n\n const success = (responseText) => {\n resolve(\n request,\n {\n status: 200,\n statusText: 'OK',\n responseText\n }\n );\n };\n\n const fail = ({status, statusText, errorThrown}) => {\n reject(\n request,\n {\n status,\n statusText,\n errorThrown,\n errors: `HTTP ${status} ${statusText?statusText:''}`\n }\n );\n };\n\n const xmlhttp = new XMLHttpRequest();\n xmlhttp.onreadystatechange = () => {\n if (xmlhttp.readyState === 4) {\n if (xmlhttp.status === 200) {\n success(xmlhttp.responseText);\n } else {\n fail({status: xmlhttp.status, statusText: xmlhttp.statusText});\n }\n }\n };\n try {\n xmlhttp.open(method, uri, true);\n if (headers) {\n for (const header of Object.keys(headers)) {\n xmlhttp.setRequestHeader(header, headers[header]);\n }\n }\n if (data) {\n xmlhttp.send(data);\n } else {\n xmlhttp.send();\n }\n } catch (errorThrown) {\n fail({errorThrown});\n }\n }\n}\n","/**\n * Module dependencies.\n * @private\n */\n\nimport Requester from './requester';\n\n\n/**\n * Settings object.\n * @private\n */\n\nexport default class Settings {\n\n\n /**\n * Initialize the settings.\n *\n * - setup default configuration\n *\n * @private\n */\n\n constructor() {\n // default settings\n this.settings = {\n 'http requester': new Requester(),\n\n 'http GET transformer': {\n uri({uri, headers, data}) {\n if (!data) {\n return uri;\n }\n let [uriWithoutAnchor, anchor] = [uri, ''];\n const match = /^(.*)(#.*)$/.exec(uri);\n if (match) {\n [,uriWithoutAnchor, anchor] = /^(.*)(#.*)$/.exec(uri);\n }\n uriWithoutAnchor = Object.keys(data).reduce((gUri, d, index) => {\n gUri += `${(index === 0 && gUri.indexOf('?') === -1)?'?':'&'}${d}=${data[d]}`;\n return gUri;\n }, uriWithoutAnchor);\n return uriWithoutAnchor + anchor;\n }\n }\n };\n\n this.rules = {\n 'http requester': (requester) => {\n if(typeof requester.fetch !== 'function') {\n throw new TypeError('setting http requester has no fetch method');\n }\n }\n };\n }\n\n\n /**\n * Assign `setting` to `val`\n *\n * @param {String} setting\n * @param {*} [val]\n * @private\n */\n\n set(name, value) {\n const checkRules = this.rules[name];\n if (checkRules) {\n checkRules(value);\n }\n this.settings[name] = value;\n }\n\n\n /**\n * Return `setting`'s value.\n *\n * @param {String} setting\n * @private\n */\n\n get(name) {\n return this.settings[name];\n }\n};\n","/**\n * Middleware object.\n * @public\n */\n\nexport default class Middleware {\n\n\n /**\n * Middleware initialization\n *\n * @param {String} middleware name\n */\n\n constructor(name='') {\n this.name = name;\n }\n\n /**\n * Invoked by the app before an ajax request is sent or\n * during the DOM loading (document.readyState === 'loading').\n * See Application#_callMiddlewareEntered documentation for details.\n *\n * Override this method to add your custom behaviour\n *\n * @param {Object} request\n * @public\n */\n\n // entered(request) { }\n\n\n /**\n * Invoked by the app before a new ajax request is sent or before the DOM is unloaded.\n * See Application#_callMiddlewareExited documentation for details.\n *\n * Override this method to add your custom behaviour\n *\n * @param {Object} request\n * @public\n */\n\n // exited(request) { }\n\n\n /**\n * Invoked by the app after an ajax request has responded or on DOM ready\n * (document.readyState === 'interactive').\n * See Application#_callMiddlewareUpdated documentation for details.\n *\n * Override this method to add your custom behaviour\n *\n * @param {Object} request\n * @param {Object} response\n * @public\n */\n\n // updated(request, response) { }\n\n\n /**\n * Invoked by the app when an ajax request has failed.\n *\n * Override this method to add your custom behaviour\n *\n * @param {Object} request\n * @param {Object} response\n * @public\n */\n // failed(request, response) { }\n\n\n /**\n * Allow the hand over to the next middleware object or function.\n *\n * Override this method and return `false` to break execution of\n * middleware chain.\n *\n * @return {Boolean} `true` by default\n *\n * @public\n */\n\n next() {\n return true;\n }\n}\n","/**\n * Module dependencies.\n * @private\n */\n\nimport HTTP_METHODS from './methods';\nimport {toParameters} from './application';\nimport Middleware from './middleware';\n\n\n/**\n * Route object.\n * @private\n */\n\nexport class Route {\n\n\n /**\n * Initialize the route.\n *\n * @private\n */\n\n constructor(router, uriPart, method, middleware) {\n this.router = router;\n this.uriPart = uriPart;\n this.method = method;\n this.middleware = middleware;\n this.visited = false;\n }\n\n\n /**\n * Return route's uri.\n *\n * @private\n */\n\n get uri() {\n if (!this.uriPart && !this.method) {\n return undefined;\n }\n\n if (this.uriPart instanceof RegExp) {\n return this.uriPart;\n }\n\n if (this.router.baseUri instanceof RegExp) {\n return this.router.baseUri;\n }\n\n if (this.router.baseUri) {\n const baseUri = this.router.baseUri.trim();\n if (this.uriPart) {\n return ( baseUri + this.uriPart.trim()).replace(/\\/{2,}/, '/');\n }\n return baseUri;\n }\n\n return this.uriPart;\n }\n}\n\n\n/**\n * Router object.\n * @public\n */\n\nconst error_middleware_message = 'method takes at least a middleware';\nexport default class Router {\n\n\n /**\n * Initialize the router.\n *\n * @private\n */\n\n constructor(uri) {\n this._baseUri = uri;\n this._routes = [];\n }\n\n\n /**\n * Do some checks and set _baseUri.\n *\n * @private\n */\n\n set baseUri(uri) {\n if (this._baseUri) {\n throw new TypeError('base uri is already set');\n }\n this._baseUri = uri;\n }\n\n\n /**\n * Return router's _baseUri.\n *\n * @private\n */\n\n get baseUri() {\n return this._baseUri;\n }\n\n\n /**\n * Add a route to the router.\n *\n * @private\n */\n\n _add(route) {\n this._routes.push(route);\n return this;\n }\n\n\n /**\n * Gather routes from routers filtered by _uri_ and HTTP _method_.\n *\n * @private\n */\n\n routes(uri, method) {\n return this._routes.filter((route) => {\n if (route.method && route.method !== method) {\n return false;\n }\n\n if (!route.uri || !uri) {\n return true;\n }\n\n //remove query string from uri to test\n //remove anchor from uri to test\n const match = /^(.*)\\?.*#.*|(.*)(?=\\?|#)|(.*[^\\?#])$/.exec(uri);\n const baseUriToCheck = match[1] || match[2] || match[3];\n\n if (route.uri instanceof RegExp) {\n return baseUriToCheck.match(route.uri);\n }\n\n return route.uri === baseUriToCheck;\n });\n }\n\n\n /**\n * Gather visited routes from routers.\n *\n * @private\n */\n\n visited() {\n return this._routes.filter(route => route.visited);\n }\n\n\n /**\n * Use the given middleware function or object on this router.\n *\n * // middleware function\n * router.use((req, res, next) => {console.log('Hello')});\n *\n * // middleware object\n * router.use(new Middleware());\n *\n * @param {Middleware|Function} middleware object or function\n * @return {Router} for chaining\n *\n * @public\n */\n\n use(middleware) {\n if (!(middleware instanceof Middleware) && (typeof middleware !== 'function') ) {\n throw new TypeError(error_middleware_message);\n }\n\n this._add(new Route(this, undefined, undefined, middleware));\n\n return this;\n }\n\n\n /**\n * Use the given middleware function or object on this router for\n * all HTTP methods.\n *\n * // middleware function\n * router.all((req, res, next) => {console.log('Hello')});\n *\n * // middleware object\n * router.all(new Middleware());\n *\n * @param {Middleware|Function} middleware object or function\n * @return {Router} for chaining\n *\n * @public\n */\n\n all(...args) {\n const {middleware} = toParameters(args);\n if (!middleware) {\n throw new TypeError(error_middleware_message);\n }\n\n for (const method of HTTP_METHODS) {\n this[method.toLowerCase()](...args);\n }\n return this;\n }\n}\n\nfor (const method of HTTP_METHODS) {\n\n\n /**\n * Use the given middleware function or object, with optional _uri_ on\n * HTTP methods: get, post, put, delete...\n * Default _uri_ is \"/\".\n *\n * // middleware function will be applied on path \"/\"\n * router.get((req, res, next) => {console.log('Hello')});\n *\n * // middleware object will be applied on path \"/\" and\n * router.get(new Middleware());\n *\n * // middleware function will be applied on path \"/user\"\n * router.post('/user', (req, res, next) => {console.log('Hello')});\n *\n * // middleware object will be applied on path \"/user\" and\n * router.post('/user', new Middleware());\n *\n * @param {String} uri\n * @param {Middleware|Function} middleware object or function\n * @return {Router} for chaining\n * @public\n */\n\n const methodName = method.toLowerCase();\n Router.prototype[methodName] = function(...args) {\n const {baseUri, middleware} = toParameters(args);\n if (!middleware) {\n throw new TypeError(error_middleware_message);\n }\n\n if (baseUri && this._baseUri && this._baseUri instanceof RegExp) {\n throw new TypeError('router cannot mix uri/regexp');\n }\n\n this._add(new Route(this, baseUri, method, middleware));\n\n return this;\n };\n}\n","/**\n * Module dependencies.\n */\n\nimport Application from './application';\nimport Router from './router';\nimport Middleware from './middleware';\n\n\n/**\n * Create a frontexpress application.\n *\n * @return {Function}\n * @api public\n */\n\nconst frontexpress = () => new Application();\n\n/**\n * Expose Router, Middleware constructors.\n */\nfrontexpress.Router = (baseUri) => new Router(baseUri);\nfrontexpress.Middleware = Middleware;\n\nexport default frontexpress;\n"],"names":["toParameters","args","baseUri","middleware","router","which","length","Router","Middleware","Requester","request","resolve","reject","method","uri","headers","data","success","responseText","fail","status","statusText","errorThrown","xmlhttp","XMLHttpRequest","onreadystatechange","readyState","open","Object","keys","header","setRequestHeader","send","Settings","settings","uriWithoutAnchor","anchor","match","exec","reduce","gUri","d","index","indexOf","rules","requester","fetch","TypeError","name","value","checkRules","this","Route","uriPart","visited","RegExp","trim","replace","error_middleware_message","_baseUri","_routes","route","push","filter","baseUriToCheck","_add","undefined","HTTP_METHODS","toLowerCase","methodName","prototype","Application","routers","isDOMLoaded","isDOMReady","get","set","callback","onbeforeunload","_callMiddlewareMethod","onpopstate","event","state","response","currentRoutes","_this","window","location","pathname","search","document","routes","meth","next","breakMiddlewareLoop","exited","history","httpMethodTransformer","req","res","pushState","title","reqProto","middlewareMethodName","httpMethodName","charAt","toUpperCase","slice","_fetch","frontexpress"],"mappings":"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"} \ No newline at end of file diff --git a/gzipsize.js b/gzipsize.js new file mode 100644 index 0000000..62aaaff --- /dev/null +++ b/gzipsize.js @@ -0,0 +1,5 @@ +import bytesize from 'bytesize'; + +bytesize.gzipSize(__dirname + '/frontexpress.min.js', true, (err, size) => { + console.log(`frontexpress size: ${size}(min+gzip)`); +}); diff --git a/lib/application.js b/lib/application.js index 5b79201..ee21223 100755 --- a/lib/application.js +++ b/lib/application.js @@ -151,27 +151,16 @@ export default class Application { */ use(...args) { - const errorMsg = 'use method takes at least a middleware or a router'; - let baseUri, middleware, router, which; - 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; + let {baseUri, router, middleware} = toParameters(args); + if (router) { router.baseUri = baseUri; - } else if ((which instanceof Middleware) || (typeof which === 'function')) { - middleware = which; + } else if (middleware) { router = new Router(baseUri); for (const method of HTTP_METHODS) { router[method.toLowerCase()](middleware); } } else { - throw new TypeError(errorMsg); + throw new TypeError('method takes at least a middleware or a router'); } this.routers.push(router); @@ -313,23 +302,13 @@ HTTP_METHODS.reduce((reqProto, method) => { const middlewareMethodName = method.toLowerCase(); reqProto[middlewareMethodName] = function(...args) { - let baseUri, middleware, which; - if (!args || args.length === 0) { - throw new TypeError(`${middlewareMethodName} method takes at least a middleware ${middlewareMethodName === 'get' ? 'or a string' : ''}`); - } else if (args.length === 1) { - [which] = args; - if (middlewareMethodName === 'get' && typeof which === 'string') { - return this.settings.get(which); - } - } else { - [baseUri, which,] = args; + let {baseUri, middleware, which} = toParameters(args); + if (middlewareMethodName === 'get' && typeof which === 'string') { + return this.settings.get(which); } - - if (!(which instanceof Middleware) && (typeof which !== 'function')) { - throw new TypeError(`${middlewareMethodName} method takes at least a middleware`); + if (!middleware) { + throw new TypeError(`method takes a middleware ${middlewareMethodName === 'get' ? 'or a string' : ''}`); } - - middleware = which; const router = new Router(); router[middlewareMethodName](baseUri, middleware); @@ -375,3 +354,22 @@ HTTP_METHODS.reduce((reqProto, method) => { return reqProto; }, 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}; +} diff --git a/lib/requester.js b/lib/requester.js index 4b18a30..4bfc892 100755 --- a/lib/requester.js +++ b/lib/requester.js @@ -29,8 +29,6 @@ export default class Requester { }; const fail = ({status, statusText, errorThrown}) => { - // Removed for reducing size of frontexpress - // const errors = this._analyzeErrors({status, statusText, errorThrown}); reject( request, { @@ -68,45 +66,4 @@ export default class Requester { 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:''}`; - // } } diff --git a/lib/router.js b/lib/router.js index 3c2eac9..5c3a202 100755 --- a/lib/router.js +++ b/lib/router.js @@ -4,6 +4,7 @@ */ import HTTP_METHODS from './methods'; +import {toParameters} from './application'; import Middleware from './middleware'; @@ -49,12 +50,12 @@ export class Route { return this.router.baseUri; } - if (this.router.baseUri && this.uriPart) { - return (this.router.baseUri.trim() + this.uriPart.trim()).replace(/\/{2,}/, '/'); - } - 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; @@ -67,6 +68,7 @@ export class Route { * @public */ +const error_middleware_message = 'method takes at least a middleware'; export default class Router { @@ -77,9 +79,7 @@ export default class Router { */ constructor(uri) { - if (uri) { - this._baseUri = uri; - } + this._baseUri = uri; this._routes = []; } @@ -91,22 +91,10 @@ export default class Router { */ set baseUri(uri) { - if (!uri) { - return; - } - - 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()}`); + if (this._baseUri) { + throw new TypeError('base uri is already set'); } + this._baseUri = uri; } @@ -141,36 +129,24 @@ export default class Router { routes(uri, method) { return this._routes.filter((route) => { - if (!route.uri && !route.method) { - return true; - } - if (route.method !== method) { + if (route.method && route.method !== method) { return false; } - if (!route.uri) { + if (!route.uri || !uri) { return true; } - let uriToCheck = uri; - //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 - const hashIndex = uriToCheck.indexOf('#'); - if (hashIndex >= 0) { - uriToCheck = uriToCheck.slice(0, hashIndex); - } + const match = /^(.*)\?.*#.*|(.*)(?=\?|#)|(.*[^\?#])$/.exec(uri); + const baseUriToCheck = match[1] || match[2] || match[3]; 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() { - return this._routes.filter((route) => { - return route.visited; - }); + return this._routes.filter(route => route.visited); } @@ -205,7 +179,7 @@ export default class Router { use(middleware) { 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)); @@ -231,19 +205,9 @@ export default class Router { */ all(...args) { - if (args.length === 0) { - throw new TypeError('use all method takes at least a middleware'); - } - 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'); + const {middleware} = toParameters(args); + if (!middleware) { + throw new TypeError(error_middleware_message); } for (const method of HTTP_METHODS) { @@ -281,26 +245,16 @@ for (const method of HTTP_METHODS) { const methodName = method.toLowerCase(); Router.prototype[methodName] = function(...args) { - if (args.length === 0) { - throw new TypeError(`use ${methodName} method takes at least a middleware`); - } - let uri, middleware; - - if (args.length === 1) { - [middleware,] = args; - } else { - [uri, middleware,] = args; + const {baseUri, middleware} = toParameters(args); + if (!middleware) { + throw new TypeError(error_middleware_message); } - if (!(middleware instanceof Middleware) && (typeof middleware !== 'function') ) { - throw new TypeError(`use ${methodName} method takes at least a middleware`); + if (baseUri && this._baseUri && this._baseUri instanceof RegExp) { + throw new TypeError('router cannot mix uri/regexp'); } - if (uri && this._baseUri && this._baseUri instanceof RegExp) { - throw new TypeError('router contains a regexp cannot mix with route uri/regexp'); - } - - this._add(new Route(this, uri, method, middleware)); + this._add(new Route(this, baseUri, method, middleware)); return this; }; diff --git a/package.json b/package.json index 0bb3dfd..ca4dde1 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "lint": "eslint .", "only-test": "mocha --compilers js:babel-core/register", "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" }, "author": "Camel Aissani (https://nuageprive.fr)", @@ -37,6 +38,7 @@ "babel-preset-es2015": "^6.18.0", "babel-preset-es2015-rollup": "^3.0.0", "babel-register": "^6.18.0", + "bytesize": "^0.2.0", "chai": "^3.5.0", "eslint": "^3.12.2", "eslint-loader": "^1.6.1", diff --git a/rollup.config.dev.js b/rollup.config.dev.js index 691c8ef..5f6c007 100644 --- a/rollup.config.dev.js +++ b/rollup.config.dev.js @@ -6,10 +6,7 @@ export default { moduleName:'frontexpress', plugins: [babel({ babelrc: false, - // exclude: 'node_modules/**', - presets: ['es2015-rollup'], - // externalHelpers: true, - // plugins: ['external-helpers'] + presets: ['es2015-rollup'] })], dest: 'frontexpress.js' }; diff --git a/rollup.config.prod.js b/rollup.config.prod.js index 3f1f887..3ddb3de 100644 --- a/rollup.config.prod.js +++ b/rollup.config.prod.js @@ -11,10 +11,7 @@ export default { plugins: [ babel({ babelrc: false, - // exclude: 'node_modules/**', - presets: ['es2015-rollup'], - // externalHelpers: true, - // plugins: ['external-helpers'] + presets: ['es2015-rollup'] }), uglify({ compress: { diff --git a/test/readme-test.js b/test/readme-test.js index eb5b813..a6f444d 100644 --- a/test/readme-test.js +++ b/test/readme-test.js @@ -111,7 +111,7 @@ describe('Test sample from README', () => { const router = frontexpress.Router(); - // middleware that is specific to this router + // middleware which is specific to this router router.use((req, res, next) => { spy_log(`Time: ${Date.now()}`); next(); @@ -148,4 +148,4 @@ describe('Test sample from README', () => { }); }); -}); \ No newline at end of file +});