From b22725acd0b4d2b381dd3f39bb9e473fb1f57a0c Mon Sep 17 00:00:00 2001 From: Camel Aissani Date: Sun, 15 Jan 2017 12:00:51 +0100 Subject: [PATCH] refactored code for reducing lib size --- README.md | 2 +- frontexpress.js | 452 ++++++++++++++-------------------------- frontexpress.min.js | 2 +- frontexpress.min.js.map | 2 +- lib/application.js | 110 +++++----- lib/requester.js | 6 +- lib/router.js | 8 +- lib/settings.js | 12 ++ package.json | 2 +- 9 files changed, 238 insertions(+), 358 deletions(-) diff --git a/README.md b/README.md index 239a847..723bbd1 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.17kb-brightgreen.svg) + ![Size Shield](https://img.shields.io/badge/size-2.86kb-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 3ed41fb..c0a8949 100644 --- a/frontexpress.js +++ b/frontexpress.js @@ -190,6 +190,7 @@ var Requester = function () { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function () { if (xmlhttp.readyState === 4) { + //XMLHttpRequest.DONE if (xmlhttp.status === 200) { success(xmlhttp.responseText); } else { @@ -200,30 +201,9 @@ var Requester = function () { try { xmlhttp.open(method, uri, true); if (headers) { - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; - - try { - for (var _iterator = Object.keys(headers)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var header = _step.value; - - xmlhttp.setRequestHeader(header, headers[header]); - } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } - } + Object.keys(headers).forEach(function (header) { + xmlhttp.setRequestHeader(header, headers[header]); + }); } if (data) { xmlhttp.send(data); @@ -293,6 +273,18 @@ var Settings = function () { return uriWithoutAnchor + anchor; } } + // 'http POST transformer': { + // headers({uri, headers, data}) { + // if (!data) { + // return headers; + // } + // const updatedHeaders = headers || {}; + // if (!updatedHeaders['Content-Type']) { + // updatedHeaders['Content-Type'] = 'application/x-www-form-urlencoded'; + // } + // return updatedHeaders; + // } + // } }; this.rules = { @@ -629,6 +621,8 @@ var Router = function () { }, { key: 'all', value: function all() { + var _this = this; + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } @@ -640,31 +634,9 @@ var Router = function () { throw new TypeError(error_middleware_message); } - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; - - try { - for (var _iterator = HTTP_METHODS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var method = _step.value; - - this[method.toLowerCase()].apply(this, args); - } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } - } - + HTTP_METHODS.forEach(function (method) { + _this[method.toLowerCase()].apply(_this, args); + }); return this; } }, { @@ -698,79 +670,54 @@ var Router = function () { return Router; }(); -var _iteratorNormalCompletion2 = true; -var _didIteratorError2 = false; -var _iteratorError2 = undefined; +HTTP_METHODS.forEach(function (method) { -try { - var _loop = function _loop() { - var method = _step2.value; + /** + * Use the given middleware function or object, with optional _uri_ on + * HTTP methods: get, post, put, delete... + * Default _uri_ is "/". + * + * // middleware function will be applied on path "/" + * router.get((req, res, next) => {console.log('Hello')}); + * + * // middleware object will be applied on path "/" and + * router.get(new Middleware()); + * + * // middleware function will be applied on path "/user" + * router.post('/user', (req, res, next) => {console.log('Hello')}); + * + * // middleware object will be applied on path "/user" and + * router.post('/user', new Middleware()); + * + * @param {String} uri + * @param {Middleware|Function} middleware object or function + * @return {Router} for chaining + * @public + */ + var methodName = method.toLowerCase(); + Router.prototype[methodName] = function () { + for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } - /** - * Use the given middleware function or object, with optional _uri_ on - * HTTP methods: get, post, put, delete... - * Default _uri_ is "/". - * - * // middleware function will be applied on path "/" - * router.get((req, res, next) => {console.log('Hello')}); - * - * // middleware object will be applied on path "/" and - * router.get(new Middleware()); - * - * // middleware function will be applied on path "/user" - * router.post('/user', (req, res, next) => {console.log('Hello')}); - * - * // middleware object will be applied on path "/user" and - * router.post('/user', new Middleware()); - * - * @param {String} uri - * @param {Middleware|Function} middleware object or function - * @return {Router} for chaining - * @public - */ + var _toParameters2 = toParameters(args), + baseUri = _toParameters2.baseUri, + middleware = _toParameters2.middleware; - var methodName = method.toLowerCase(); - Router.prototype[methodName] = function () { - for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args[_key2] = arguments[_key2]; - } + if (!middleware) { + throw new TypeError(error_middleware_message); + } - var _toParameters2 = toParameters(args), - baseUri = _toParameters2.baseUri, - middleware = _toParameters2.middleware; + if (baseUri && this._baseUri && this._baseUri instanceof RegExp) { + throw new TypeError('router cannot mix uri/regexp'); + } - if (!middleware) { - throw new TypeError(error_middleware_message); - } + this._add(new Route(this, baseUri, method, middleware)); - if (baseUri && this._baseUri && this._baseUri instanceof RegExp) { - throw new TypeError('router cannot mix uri/regexp'); - } - - this._add(new Route(this, baseUri, method, middleware)); - - return this; - }; + return this; }; - - for (var _iterator2 = HTTP_METHODS[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { - _loop(); - } -} catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; -} finally { - try { - if (!_iteratorNormalCompletion2 && _iterator2.return) { - _iterator2.return(); - } - } finally { - if (_didIteratorError2) { - throw _iteratorError2; - } - } -} +}); /** * Module dependencies. @@ -795,8 +742,8 @@ var Application = function () { classCallCheck(this, Application); this.routers = []; - this.isDOMLoaded = false; - this.isDOMReady = false; + // this.isDOMLoaded = false; + // this.isDOMReady = false; this.settings = new Settings(); } @@ -855,43 +802,51 @@ var Application = function () { value: function listen(callback) { var _this = this; + // manage history + window.onpopstate = function (event) { + if (event.state) { + var _event$state = event.state, + _request = _event$state.request, + _response = _event$state.response; + + var _currentRoutes = _this._routes(_request.uri, _request.method); + + _this._callMiddlewareMethod('entered', _currentRoutes, _request); + _this._callMiddlewareMethod('updated', _currentRoutes, _request, _response); + } + }; + + // manage page loading/refreshing + var request = { method: 'GET', uri: window.location.pathname + window.location.search }; + var response = { status: 200, statusText: 'OK' }; + var currentRoutes = this._routes(); + + var whenPageIsInteractiveFn = function whenPageIsInteractiveFn() { + _this._callMiddlewareMethod('updated', currentRoutes, request, response); + if (callback) { + callback(request, response); + } + }; + window.onbeforeunload = function () { _this._callMiddlewareMethod('exited'); }; - window.onpopstate = function (event) { - if (event.state) { - var _event$state = event.state, - request = _event$state.request, - response = _event$state.response; - - var currentRoutes = _this._routes(request.uri, request.method); - - _this._callMiddlewareMethod('entered', currentRoutes, request); - _this._callMiddlewareMethod('updated', currentRoutes, request, response); - } - }; - document.onreadystatechange = function () { - var request = { method: 'GET', uri: window.location.pathname + window.location.search }; - var response = { status: 200, statusText: 'OK' }; - var currentRoutes = _this._routes(); - // DOM state - if (document.readyState === 'loading' && !_this.isDOMLoaded) { - _this.isDOMLoaded = true; - _this._callMiddlewareMethod('entered', currentRoutes, request); - } else if (document.readyState === 'interactive' && !_this.isDOMReady) { - if (!_this.isDOMLoaded) { - _this.isDOMLoaded = true; + // DOM ready state + switch (document.readyState) { + case 'loading': _this._callMiddlewareMethod('entered', currentRoutes, request); - } - _this.isDOMReady = true; - _this._callMiddlewareMethod('updated', currentRoutes, request, response); - if (callback) { - callback(request, response); - } + break; + case 'interactive': + whenPageIsInteractiveFn(); + break; } }; + + if (['interactive', 'complete'].indexOf(document.readyState) !== -1) { + whenPageIsInteractiveFn(); + } } /** @@ -948,30 +903,9 @@ var Application = function () { router.baseUri = baseUri; } else if (middleware) { router = new Router(baseUri); - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; - - try { - for (var _iterator = HTTP_METHODS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var method = _step.value; - - router[method.toLowerCase()](middleware); - } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } - } + HTTP_METHODS.forEach(function (method) { + router[method.toLowerCase()](middleware); + }); } else { throw new TypeError('method takes at least a middleware or a router'); } @@ -994,30 +928,9 @@ var Application = function () { var method = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'GET'; var currentRoutes = []; - var _iteratorNormalCompletion2 = true; - var _didIteratorError2 = false; - var _iteratorError2 = undefined; - - try { - for (var _iterator2 = this.routers[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { - var router = _step2.value; - - currentRoutes.push.apply(currentRoutes, toConsumableArray(router.routes(uri, method))); - } - } catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; - } finally { - try { - if (!_iteratorNormalCompletion2 && _iterator2.return) { - _iterator2.return(); - } - } finally { - if (_didIteratorError2) { - throw _iteratorError2; - } - } - } + this.routers.forEach(function (router) { + currentRoutes.push.apply(currentRoutes, toConsumableArray(router.routes(uri, method))); + }); return currentRoutes; } @@ -1033,102 +946,41 @@ var Application = function () { value: function _callMiddlewareMethod(meth, currentRoutes, request, response) { if (meth === 'exited') { // currentRoutes, request, response params not needed - var _iteratorNormalCompletion3 = true; - var _didIteratorError3 = false; - var _iteratorError3 = undefined; - - try { - for (var _iterator3 = this.routers[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { - var router = _step3.value; - var _iteratorNormalCompletion4 = true; - var _didIteratorError4 = false; - var _iteratorError4 = undefined; - - try { - for (var _iterator4 = router.visited()[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - var route = _step4.value; - - if (route.middleware.exited) { - route.middleware.exited(route.visited); - route.visited = null; - } - } - } catch (err) { - _didIteratorError4 = true; - _iteratorError4 = err; - } finally { - try { - if (!_iteratorNormalCompletion4 && _iterator4.return) { - _iterator4.return(); - } - } finally { - if (_didIteratorError4) { - throw _iteratorError4; - } - } + this.routers.forEach(function (router) { + router.visited().forEach(function (route) { + if (route.middleware.exited) { + route.middleware.exited(route.visited); + route.visited = null; } - } - } catch (err) { - _didIteratorError3 = true; - _iteratorError3 = err; - } finally { - try { - if (!_iteratorNormalCompletion3 && _iterator3.return) { - _iterator3.return(); - } - } finally { - if (_didIteratorError3) { - throw _iteratorError3; - } - } - } - + }); + }); return; } - var _iteratorNormalCompletion5 = true; - var _didIteratorError5 = false; - var _iteratorError5 = undefined; + currentRoutes.some(function (route) { + if (meth === 'updated') { + route.visited = request; + } - try { - for (var _iterator5 = currentRoutes[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { - var _route = _step5.value; - - if (meth === 'updated') { - _route.visited = request; + if (route.middleware[meth]) { + route.middleware[meth](request, response); + if (route.middleware.next && !route.middleware.next()) { + return true; } - - if (_route.middleware[meth]) { - _route.middleware[meth](request, response); - if (_route.middleware.next && !_route.middleware.next()) { - break; - } - } else if (meth !== 'entered') { - // calls middleware method - var breakMiddlewareLoop = true; - var next = function next() { - breakMiddlewareLoop = false; - }; - _route.middleware(request, response, next); - if (breakMiddlewareLoop) { - break; - } + } else if (meth !== 'entered') { + // calls middleware method + var breakMiddlewareLoop = true; + var next = function next() { + breakMiddlewareLoop = false; + }; + route.middleware(request, response, next); + if (breakMiddlewareLoop) { + return true; } } - } catch (err) { - _didIteratorError5 = true; - _iteratorError5 = err; - } finally { - try { - if (!_iteratorNormalCompletion5 && _iterator5.return) { - _iterator5.return(); - } - } finally { - if (_didIteratorError5) { - throw _iteratorError5; - } - } - } + + return false; + }); } /** @@ -1139,21 +991,25 @@ var Application = function () { }, { key: '_fetch', - value: function _fetch(request, resolve, reject) { + value: function _fetch(req, resolve, reject) { var _this2 = this; - var method = request.method, - uri = request.uri, - headers = request.headers, - data = request.data, - history = request.history; + var method = req.method, + uri = req.uri, + headers = req.headers, + data = req.data, + history = req.history; var httpMethodTransformer = this.get('http ' + method + ' transformer'); if (httpMethodTransformer) { - uri = httpMethodTransformer.uri ? httpMethodTransformer.uri({ uri: uri, headers: headers, data: data }) : uri; - headers = httpMethodTransformer.headers ? httpMethodTransformer.headers({ uri: uri, headers: headers, data: data }) : headers; - data = httpMethodTransformer.data ? httpMethodTransformer.data({ uri: uri, headers: headers, data: data }) : data; + var _uriFn = httpMethodTransformer.uri, + _headersFn = httpMethodTransformer.headers, + _dataFn = httpMethodTransformer.data; + + uri = _uriFn ? _uriFn({ uri: uri, headers: headers, data: data }) : uri; + headers = _headersFn ? _headersFn({ uri: uri, headers: headers, data: data }) : headers; + data = _dataFn ? _dataFn({ uri: uri, headers: headers, data: data }) : data; } // calls middleware exited method @@ -1163,21 +1019,21 @@ var Application = function () { var currentRoutes = this._routes(uri, method); // calls middleware entered method - this._callMiddlewareMethod('entered', currentRoutes, request); + this._callMiddlewareMethod('entered', currentRoutes, req); // invokes http request - this.settings.get('http requester').fetch(request, function (req, res) { + this.settings.get('http requester').fetch(req, function (request, response) { if (history) { - window.history.pushState({ request: req, response: res }, history.title, history.uri); + window.history.pushState({ request: request, response: response }, history.title, history.uri); } - _this2._callMiddlewareMethod('updated', currentRoutes, req, res); + _this2._callMiddlewareMethod('updated', currentRoutes, request, response); if (resolve) { - resolve(req, res); + resolve(request, response); } - }, function (req, res) { - _this2._callMiddlewareMethod('failed', currentRoutes, req, res); + }, function (request, response) { + _this2._callMiddlewareMethod('failed', currentRoutes, request, response); if (reject) { - reject(req, res); + reject(request, response); } }); } diff --git a/frontexpress.min.js b/frontexpress.min.js index baba80b..8985d98 100644 --- a/frontexpress.min.js +++ b/frontexpress.min.js @@ -1,2 +1,2 @@ -var frontexpress=function(){"use strict";function t(t){var e=void 0,r=void 0,i=void 0,n=void 0;if(t&&t.length>0){if(1===t.length){var o=a(t,1);n=o[0]}else{var u=a(t,2);e=u[0],n=u[1]}n instanceof l?i=n:(n instanceof d||"function"==typeof n)&&(r=n)}return{baseUri:e,middleware:r,router:i,which:n}}var e=["GET","POST","PUT","DELETE"],r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},n=function(){function t(t,e){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:"";i(this,t),this.name=e}return n(t,[{key:"next",value:function(){return!0}}]),t}(),h=function(){function t(e,r,n,a){i(this,t),this.router=e,this.uriPart=r,this.method=n,this.middleware=a,this.visited=!1}return n(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}(),f="method takes at least a middleware",l=function(){function a(t){i(this,a),this._baseUri=t,this._routes=[]}return n(a,[{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 d)&&"function"!=typeof t)throw new TypeError(f);return this._add(new h(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,a=void 0;try{for(var u,s=this.routers[Symbol.iterator]();!(i=(u=s.next()).done);i=!0){var d=u.value;r.push.apply(r,o(d.routes(t,e)))}}catch(t){n=!0,a=t}finally{try{!i&&s.return&&s.return()}finally{if(n)throw a}}return r}},{key:"_callMiddlewareMethod",value:function(t,e,r,i){if("exited"!==t){var n=!0,a=!1,o=void 0;try{for(var u,s=e[Symbol.iterator]();!(n=(u=s.next()).done);n=!0){var d=u.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,f=function(){h=!1};if(d.middleware(r,i,f),h)break}}}catch(t){a=!0,o=t}finally{try{!n&&s.return&&s.return()}finally{if(a)throw o}}}else{var l=!0,c=!1,y=void 0;try{for(var v,w=this.routers[Symbol.iterator]();!(l=(v=w.next()).done);l=!0){var p=v.value,m=!0,b=!1,g=void 0;try{for(var x,M=p.visited()[Symbol.iterator]();!(m=(x=M.next()).done);m=!0){var _=x.value;_.middleware.exited&&(_.middleware.exited(_.visited),_.visited=null)}}catch(t){b=!0,g=t}finally{try{!m&&M.return&&M.return()}finally{if(b)throw g}}}}catch(t){c=!0,y=t}finally{try{!l&&w.return&&w.return()}finally{if(c)throw y}}}}},{key:"_fetch",value:function(t,e,r){var i=this,n=t.method,a=t.uri,o=t.headers,u=t.data,s=t.history,d=this.get("http "+n+" transformer");d&&(a=d.uri?d.uri({uri:a,headers:o,data:u}):a,o=d.headers?d.headers({uri:a,headers:o,data:u}):o,u=d.data?d.data({uri:a,headers:o,data:u}):u),this._callMiddlewareMethod("exited");var h=this._routes(a,n);this._callMiddlewareMethod("entered",h,t),this.settings.get("http requester").fetch(t,function(t,r){s&&window.history.pushState({request:t,response:r},s.title,s.uri),i._callMiddlewareMethod("updated",h,t,r),e&&e(t,r)},function(t,e){i._callMiddlewareMethod("failed",h,t,e),r&&r(t,e)})}}]),r}();e.reduce(function(e,r){var i=r.toLowerCase();e[i]=function(){for(var e=arguments.length,r=Array(e),n=0;n0){if(1===t.length){var a=o(t,1);n=a[0]}else{var u=o(t,2);e=u[0],n=u[1]}n instanceof c?i=n:(n instanceof h||"function"==typeof n)&&(r=n)}return{baseUri:e,middleware:r,router:i,which:n}}var e=["GET","POST","PUT","DELETE"],r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},n=function(){function t(t,e){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:"";i(this,t),this.name=e}return n(t,[{key:"next",value:function(){return!0}}]),t}(),d=function(){function t(e,r,n,o){i(this,t),this.router=e,this.uriPart=r,this.method=n,this.middleware=o,this.visited=!1}return n(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}(),f="method takes at least a middleware",c=function(){function o(t){i(this,o),this._baseUri=t,this._routes=[]}return n(o,[{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 h)&&"function"!=typeof t)throw new TypeError(f);return this._add(new d(this,void 0,void 0,t)),this}},{key:"all",value:function(){for(var r=this,i=arguments.length,n=Array(i),o=0;o0&&void 0!==arguments[0]?arguments[0]:window.location.pathname+window.location.search,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"GET",r=[];return this.routers.forEach(function(i){r.push.apply(r,a(i.routes(t,e)))}),r}},{key:"_callMiddlewareMethod",value:function(t,e,r,i){return"exited"===t?void this.routers.forEach(function(t){t.visited().forEach(function(t){t.middleware.exited&&(t.middleware.exited(t.visited),t.visited=null)})}):void e.some(function(e){if("updated"===t&&(e.visited=r),e.middleware[t]){if(e.middleware[t](r,i),e.middleware.next&&!e.middleware.next())return!0}else if("entered"!==t){var n=!0,o=function(){n=!1};if(e.middleware(r,i,o),n)return!0}return!1})}},{key:"_fetch",value:function(t,e,r){var i=this,n=t.method,o=t.uri,a=t.headers,u=t.data,s=t.history,h=this.get("http "+n+" transformer");if(h){var d=h.uri,f=h.headers,c=h.data;o=d?d({uri:o,headers:a,data:u}):o,a=f?f({uri:o,headers:a,data:u}):a,u=c?c({uri:o,headers:a,data:u}):u}this._callMiddlewareMethod("exited");var l=this._routes(o,n);this._callMiddlewareMethod("entered",l,t),this.settings.get("http requester").fetch(t,function(t,r){s&&window.history.pushState({request:t,response:r},s.title,s.uri),i._callMiddlewareMethod("updated",l,t,r),e&&e(t,r)},function(t,e){i._callMiddlewareMethod("failed",l,t,e),r&&r(t,e)})}}]),r}();e.reduce(function(e,r){var i=r.toLowerCase();e[i]=function(){for(var e=arguments.length,r=Array(e),n=0;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 (!uri) {\n return;\n }\n\n if (!this._baseUri) {\n this._baseUri = uri;\n return;\n }\n\n if (typeof this._baseUri !== typeof uri) {\n throw new TypeError('router cannot mix regexp and uri');\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.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","babelHelpers.typeof","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 +{"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\n // manage history\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 // manage page loading/refreshing\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\n const whenPageIsInteractiveFn = () => {\n this._callMiddlewareMethod('updated', currentRoutes, request, response);\n if (callback) {\n callback(request, response);\n }\n };\n\n window.onbeforeunload = () => {\n this._callMiddlewareMethod('exited');\n };\n\n document.onreadystatechange = () => {\n // DOM ready state\n switch (document.readyState) {\n case 'loading':\n this._callMiddlewareMethod('entered', currentRoutes, request);\n break;\n case 'interactive':\n whenPageIsInteractiveFn();\n break;\n }\n };\n\n if (['interactive', 'complete'].indexOf(document.readyState) !== -1) {\n whenPageIsInteractiveFn();\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 HTTP_METHODS.forEach((method) => {\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 this.routers.forEach((router) => {\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 this.routers.forEach((router) => {\n router.visited().forEach((route) => {\n if (route.middleware.exited) {\n route.middleware.exited(route.visited);\n route.visited = null;\n }\n });\n });\n return;\n }\n\n currentRoutes.some((route) => {\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 return true;\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 return true;\n }\n }\n\n return false;\n });\n }\n\n\n /**\n * Make an ajax request. Manage History#pushState if history object set.\n *\n * @private\n */\n\n _fetch(req, resolve, reject) {\n let {method, uri, headers, data, history} = req;\n\n const httpMethodTransformer = this.get(`http ${method} transformer`);\n if (httpMethodTransformer) {\n const {uri: _uriFn, headers: _headersFn, data: _dataFn } = httpMethodTransformer;\n uri = _uriFn ? _uriFn({uri, headers, data}) : uri;\n headers = _headersFn ? _headersFn({uri, headers, data}) : headers;\n data = _dataFn ? _dataFn({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, req);\n\n // invokes http request\n this.settings.get('http requester').fetch(req,\n (request, response) => {\n if (history) {\n window.history.pushState({request, response}, history.title, history.uri);\n }\n this._callMiddlewareMethod('updated', currentRoutes, request, response);\n if (resolve) {\n resolve(request, response);\n }\n },\n (request, response) => {\n this._callMiddlewareMethod('failed', currentRoutes, request, response);\n if (reject) {\n reject(request, response);\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) { //XMLHttpRequest.DONE\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 Object.keys(headers).forEach((header) => {\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 // 'http POST transformer': {\n // headers({uri, headers, data}) {\n // if (!data) {\n // return headers;\n // }\n // const updatedHeaders = headers || {};\n // if (!updatedHeaders['Content-Type']) {\n // updatedHeaders['Content-Type'] = 'application/x-www-form-urlencoded';\n // }\n // return updatedHeaders;\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 (!uri) {\n return;\n }\n\n if (!this._baseUri) {\n this._baseUri = uri;\n return;\n }\n\n if (typeof this._baseUri !== typeof uri) {\n throw new TypeError('router cannot mix regexp and uri');\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.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 HTTP_METHODS.forEach((method) => {\n this[method.toLowerCase()](...args);\n });\n return this;\n }\n}\n\nHTTP_METHODS.forEach((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 * 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","keys","forEach","header","setRequestHeader","send","Settings","settings","uriWithoutAnchor","anchor","match","exec","Object","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","toLowerCase","babelHelpers.typeof","methodName","prototype","Application","routers","get","set","callback","onpopstate","event","state","response","currentRoutes","_this","_callMiddlewareMethod","window","location","pathname","search","whenPageIsInteractiveFn","onbeforeunload","document","routes","meth","exited","some","next","breakMiddlewareLoop","req","history","httpMethodTransformer","_uriFn","_headersFn","_dataFn","pushState","title","reqProto","middlewareMethodName","httpMethodName","charAt","toUpperCase","slice","_fetch","frontexpress"],"mappings":"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"} \ No newline at end of file diff --git a/lib/application.js b/lib/application.js index ee21223..316e118 100755 --- a/lib/application.js +++ b/lib/application.js @@ -26,8 +26,8 @@ export default class Application { constructor() { this.routers = []; - this.isDOMLoaded = false; - this.isDOMReady = false; + // this.isDOMLoaded = false; + // this.isDOMReady = false; this.settings = new Settings(); } @@ -76,10 +76,8 @@ export default class Application { */ listen(callback) { - window.onbeforeunload = () => { - this._callMiddlewareMethod('exited'); - }; + // manage history window.onpopstate = (event) => { if (event.state) { const {request, response} = event.state; @@ -90,26 +88,37 @@ export default class Application { } }; - document.onreadystatechange = () => { - const request = {method: 'GET', uri: window.location.pathname + window.location.search}; - const response = {status: 200, statusText: 'OK'}; - const currentRoutes = this._routes(); - // DOM state - if (document.readyState === 'loading' && !this.isDOMLoaded) { - this.isDOMLoaded = true; - this._callMiddlewareMethod('entered', currentRoutes, request); - } else if (document.readyState === 'interactive' && !this.isDOMReady) { - if (!this.isDOMLoaded) { - this.isDOMLoaded = true; - this._callMiddlewareMethod('entered', currentRoutes, request); - } - this.isDOMReady = true; - this._callMiddlewareMethod('updated', currentRoutes, request, response); - if (callback) { - callback(request, response); - } + // manage page loading/refreshing + const request = {method: 'GET', uri: window.location.pathname + window.location.search}; + const response = {status: 200, statusText: 'OK'}; + const currentRoutes = this._routes(); + + const whenPageIsInteractiveFn = () => { + this._callMiddlewareMethod('updated', currentRoutes, request, response); + if (callback) { + callback(request, response); } }; + + window.onbeforeunload = () => { + this._callMiddlewareMethod('exited'); + }; + + document.onreadystatechange = () => { + // DOM ready state + switch (document.readyState) { + case 'loading': + this._callMiddlewareMethod('entered', currentRoutes, request); + break; + case 'interactive': + whenPageIsInteractiveFn(); + break; + } + }; + + if (['interactive', 'complete'].indexOf(document.readyState) !== -1) { + whenPageIsInteractiveFn(); + } } @@ -156,9 +165,9 @@ export default class Application { router.baseUri = baseUri; } else if (middleware) { router = new Router(baseUri); - for (const method of HTTP_METHODS) { + HTTP_METHODS.forEach((method) => { router[method.toLowerCase()](middleware); - } + }); } else { throw new TypeError('method takes at least a middleware or a router'); } @@ -177,9 +186,9 @@ export default class Application { _routes(uri=window.location.pathname + window.location.search, method='GET') { const currentRoutes = []; - for (const router of this.routers) { + this.routers.forEach((router) => { currentRoutes.push(...router.routes(uri, method)); - } + }); return currentRoutes; } @@ -194,18 +203,18 @@ export default class Application { _callMiddlewareMethod(meth, currentRoutes, request, response) { if (meth === 'exited') { // currentRoutes, request, response params not needed - for (const router of this.routers) { - for (const route of router.visited()) { + this.routers.forEach((router) => { + router.visited().forEach((route) => { if (route.middleware.exited) { route.middleware.exited(route.visited); route.visited = null; } - } - } + }); + }); return; } - for (const route of currentRoutes) { + currentRoutes.some((route) => { if (meth === 'updated') { route.visited = request; } @@ -213,7 +222,7 @@ export default class Application { if (route.middleware[meth]) { route.middleware[meth](request, response); if (route.middleware.next && !route.middleware.next()) { - break; + return true; } } else if (meth !== 'entered') { // calls middleware method @@ -223,10 +232,12 @@ export default class Application { }; route.middleware(request, response, next); if (breakMiddlewareLoop) { - break; + return true; } } - } + + return false; + }); } @@ -236,14 +247,15 @@ export default class Application { * @private */ - _fetch(request, resolve, reject) { - let {method, uri, headers, data, history} = request; + _fetch(req, resolve, reject) { + let {method, uri, headers, data, history} = req; const httpMethodTransformer = this.get(`http ${method} transformer`); if (httpMethodTransformer) { - uri = httpMethodTransformer.uri ? httpMethodTransformer.uri({uri, headers, data}) : uri; - headers = httpMethodTransformer.headers ? httpMethodTransformer.headers({uri, headers, data}) : headers; - data = httpMethodTransformer.data ? httpMethodTransformer.data({uri, headers, data}) : data; + const {uri: _uriFn, headers: _headersFn, data: _dataFn } = httpMethodTransformer; + uri = _uriFn ? _uriFn({uri, headers, data}) : uri; + headers = _headersFn ? _headersFn({uri, headers, data}) : headers; + data = _dataFn ? _dataFn({uri, headers, data}) : data; } // calls middleware exited method @@ -253,23 +265,23 @@ export default class Application { const currentRoutes = this._routes(uri, method); // calls middleware entered method - this._callMiddlewareMethod('entered', currentRoutes, request); + this._callMiddlewareMethod('entered', currentRoutes, req); // invokes http request - this.settings.get('http requester').fetch(request, - (req, res) => { + this.settings.get('http requester').fetch(req, + (request, response) => { if (history) { - window.history.pushState({request: req, response: res}, history.title, history.uri); + window.history.pushState({request, response}, history.title, history.uri); } - this._callMiddlewareMethod('updated', currentRoutes, req, res); + this._callMiddlewareMethod('updated', currentRoutes, request, response); if (resolve) { - resolve(req, res); + resolve(request, response); } }, - (req, res) => { - this._callMiddlewareMethod('failed', currentRoutes, req, res); + (request, response) => { + this._callMiddlewareMethod('failed', currentRoutes, request, response); if (reject) { - reject(req, res); + reject(request, response); } }); } diff --git a/lib/requester.js b/lib/requester.js index 4bfc892..7af7e93 100755 --- a/lib/requester.js +++ b/lib/requester.js @@ -42,7 +42,7 @@ export default class Requester { const xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = () => { - if (xmlhttp.readyState === 4) { + if (xmlhttp.readyState === 4) { //XMLHttpRequest.DONE if (xmlhttp.status === 200) { success(xmlhttp.responseText); } else { @@ -53,9 +53,9 @@ export default class Requester { try { xmlhttp.open(method, uri, true); if (headers) { - for (const header of Object.keys(headers)) { + Object.keys(headers).forEach((header) => { xmlhttp.setRequestHeader(header, headers[header]); - } + }); } if (data) { xmlhttp.send(data); diff --git a/lib/router.js b/lib/router.js index 9a3f752..8116be5 100755 --- a/lib/router.js +++ b/lib/router.js @@ -218,14 +218,14 @@ export default class Router { throw new TypeError(error_middleware_message); } - for (const method of HTTP_METHODS) { + HTTP_METHODS.forEach((method) => { this[method.toLowerCase()](...args); - } + }); return this; } } -for (const method of HTTP_METHODS) { +HTTP_METHODS.forEach((method) => { /** @@ -266,4 +266,4 @@ for (const method of HTTP_METHODS) { return this; }; -} +}); diff --git a/lib/settings.js b/lib/settings.js index 3ae814c..5e1f9d7 100644 --- a/lib/settings.js +++ b/lib/settings.js @@ -44,6 +44,18 @@ export default class Settings { return uriWithoutAnchor + anchor; } } + // 'http POST transformer': { + // headers({uri, headers, data}) { + // if (!data) { + // return headers; + // } + // const updatedHeaders = headers || {}; + // if (!updatedHeaders['Content-Type']) { + // updatedHeaders['Content-Type'] = 'application/x-www-form-urlencoded'; + // } + // return updatedHeaders; + // } + // } }; this.rules = { diff --git a/package.json b/package.json index ca4dde1..9a7f49d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "frontexpress", - "version": "1.0.0", + "version": "1.0.1", "description": "Frontexpress manages routes in browser like ExpressJS on Node", "main": "dist/frontexpress.js", "scripts": {