frontexpress/frontexpress.js

1265 lines
33 KiB
JavaScript
Raw Normal View History

var frontexpress = (function () {
'use strict';
/**
* HTTP method list
* @private
*/
var HTTP_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];
// not supported yet
// HEAD', 'CONNECT', 'OPTIONS', 'TRACE';
2017-01-14 15:08:22 +00:00
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
var createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"]) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
return function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
}();
var toConsumableArray = function (arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
} else {
return Array.from(arr);
}
};
/**
* Middleware object.
* @public
*/
var Middleware = function () {
/**
* Middleware initialization
*
* @param {String} middleware name
*/
function Middleware() {
var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
classCallCheck(this, Middleware);
this.name = name;
}
/**
* Invoked by the app before an ajax request is sent or
* during the DOM loading (document.readyState === 'loading').
* See Application#_callMiddlewareEntered documentation for details.
*
* Override this method to add your custom behaviour
*
* @param {Object} request
* @public
*/
createClass(Middleware, [{
key: 'entered',
value: function entered(request) {}
/**
* Invoked by the app before a new ajax request is sent or before the DOM is unloaded.
* See Application#_callMiddlewareExited documentation for details.
*
* Override this method to add your custom behaviour
*
* @param {Object} request
* @public
*/
}, {
key: 'exited',
value: function exited(request) {}
/**
* Invoked by the app after an ajax request has responded or on DOM ready
* (document.readyState === 'interactive').
* See Application#_callMiddlewareUpdated documentation for details.
*
* Override this method to add your custom behaviour
*
* @param {Object} request
* @param {Object} response
* @public
*/
}, {
key: 'updated',
value: function updated(request, response) {}
/**
* Invoked by the app when an ajax request has failed.
*
* Override this method to add your custom behaviour
*
* @param {Object} request
* @param {Object} response
* @public
*/
}, {
key: 'failed',
value: function failed(request, response) {}
/**
* Allow the hand over to the next middleware object or function.
*
* Override this method and return `false` to break execution of
* middleware chain.
*
* @return {Boolean} `true` by default
*
* @public
*/
}, {
key: 'next',
value: function next() {
return true;
}
}]);
return Middleware;
}();
/**
* Module dependencies.
* @private
*/
/**
* Route object.
* @private
*/
var Route = function () {
/**
* Initialize the route.
*
* @private
*/
function Route(router, uriPart, method, middleware) {
classCallCheck(this, Route);
this.router = router;
this.uriPart = uriPart;
this.method = method;
this.middleware = middleware;
this.visited = false;
}
/**
* Return route's uri.
*
* @private
*/
createClass(Route, [{
key: 'uri',
get: function get$$1() {
if (!this.uriPart && !this.method) {
return undefined;
}
if (this.uriPart instanceof RegExp) {
return this.uriPart;
}
if (this.router.baseUri instanceof RegExp) {
return this.router.baseUri;
}
if (this.router.baseUri) {
2017-01-14 14:02:50 +00:00
var baseUri = this.router.baseUri.trim();
if (this.uriPart) {
return (baseUri + this.uriPart.trim()).replace(/\/{2,}/, '/');
}
return baseUri;
}
return this.uriPart;
}
}]);
return Route;
}();
/**
* Router object.
* @public
*/
2017-01-14 14:02:50 +00:00
var error_middleware_message = 'method takes at least a middleware';
var Router = function () {
/**
* Initialize the router.
*
* @private
*/
function Router(uri) {
classCallCheck(this, Router);
2017-01-14 14:02:50 +00:00
this._baseUri = uri;
this._routes = [];
}
/**
* Do some checks and set _baseUri.
*
* @private
*/
createClass(Router, [{
key: '_add',
/**
* Add a route to the router.
*
* @private
*/
value: function _add(route) {
this._routes.push(route);
return this;
}
/**
* Gather routes from routers filtered by _uri_ and HTTP _method_.
*
* @private
*/
}, {
key: 'routes',
2017-06-22 19:17:18 +00:00
value: function routes(application, request) {
request.params = request.params || {};
var isRouteMatch = application.get('route matcher');
return this._routes.filter(function (route) {
2017-06-22 19:17:18 +00:00
return isRouteMatch(request, route);
});
}
/**
* Gather visited routes from routers.
*
* @private
*/
}, {
key: 'visited',
value: function visited() {
return this._routes.filter(function (route) {
return route.visited;
});
}
/**
* Use the given middleware function or object on this router.
*
* // middleware function
* router.use((req, res, next) => {console.log('Hello')});
*
* // middleware object
* router.use(new Middleware());
*
* @param {Middleware|Function} middleware object or function
* @return {Router} for chaining
*
* @public
*/
}, {
key: 'use',
value: function use(middleware) {
if (!(middleware instanceof Middleware) && typeof middleware !== 'function') {
2017-01-14 14:02:50 +00:00
throw new TypeError(error_middleware_message);
}
this._add(new Route(this, undefined, undefined, middleware));
return this;
}
/**
* Use the given middleware function or object on this router for
* all HTTP methods.
*
* // middleware function
* router.all((req, res, next) => {console.log('Hello')});
*
* // middleware object
* router.all(new Middleware());
*
* @param {Middleware|Function} middleware object or function
* @return {Router} for chaining
*
* @public
*/
}, {
key: 'all',
value: function all() {
2017-01-15 11:00:51 +00:00
var _this = this;
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
2017-01-14 14:02:50 +00:00
var _toParameters = toParameters(args),
middleware = _toParameters.middleware;
2017-01-14 14:02:50 +00:00
if (!middleware) {
throw new TypeError(error_middleware_message);
}
2017-01-15 11:00:51 +00:00
HTTP_METHODS.forEach(function (method) {
_this[method.toLowerCase()].apply(_this, args);
});
return this;
}
}, {
key: 'baseUri',
set: function set$$1(uri) {
2017-01-14 15:08:22 +00:00
if (!uri) {
return;
}
if (!this._baseUri) {
this._baseUri = uri;
return;
}
if (_typeof(this._baseUri) !== (typeof uri === 'undefined' ? 'undefined' : _typeof(uri))) {
throw new TypeError('router cannot mix regexp and uri');
}
}
/**
* Return router's _baseUri.
*
* @private
*/
,
get: function get$$1() {
return this._baseUri;
}
}]);
return Router;
}();
2017-01-15 11:00:51 +00:00
HTTP_METHODS.forEach(function (method) {
2017-01-15 11:00:51 +00:00
/**
* 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
*/
2017-01-15 11:00:51 +00:00
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];
}
2017-01-15 11:00:51 +00:00
var _toParameters2 = toParameters(args),
baseUri = _toParameters2.baseUri,
middleware = _toParameters2.middleware;
2017-01-15 11:00:51 +00:00
if (!middleware) {
throw new TypeError(error_middleware_message);
}
2017-01-15 11:00:51 +00:00
if (baseUri && this._baseUri && this._baseUri instanceof RegExp) {
throw new TypeError('router cannot mix uri/regexp');
}
2017-01-15 11:00:51 +00:00
this._add(new Route(this, baseUri, method, middleware));
2017-01-15 11:00:51 +00:00
return this;
};
2017-01-15 11:00:51 +00:00
});
2017-06-22 19:17:18 +00:00
function routeMatcher(request, route) {
// check if http method are equals
if (route.method && route.method !== request.method) {
return false;
}
// route and uri not defined always match
if (!route.uri || !request.uri) {
return true;
}
//remove query string and anchor from uri to test
var match = /^(.*)\?.*#.*|(.*)(?=\?|#)|(.*[^\?#])$/.exec(request.uri);
var baseUriToCheck = match[1] || match[2] || match[3];
// if route is a regexp path
if (route.uri instanceof RegExp) {
return baseUriToCheck.match(route.uri) !== null;
}
// if route is parameterized path
if (route.uri.indexOf(':') !== -1) {
var decodeParmeterValue = function decodeParmeterValue(v) {
return !isNaN(parseFloat(v)) && isFinite(v) ? Number.isInteger(v) ? Number.parseInt(v, 10) : Number.parseFloat(v) : v;
};
// figure out key names
var keys = [];
var keysRE = /:([^\/\?]+)\??/g;
var keysMatch = keysRE.exec(route.uri);
while (keysMatch != null) {
keys.push(keysMatch[1]);
keysMatch = keysRE.exec(route.uri);
}
// change parameterized path to regexp
var regExpUri = route.uri
// :parameter?
.replace(/\/:[^\/]+\?/g, '(?:\/([^\/]+))?')
// :parameter
.replace(/:[^\/]+/g, '([^\/]+)')
// escape all /
.replace('/', '\\/');
// checks if uri match
var routeMatch = baseUriToCheck.match(new RegExp('^' + regExpUri + '$'));
if (!routeMatch) {
return false;
}
// update params in request with keys
request.params = Object.assign(request.params, keys.reduce(function (acc, key, index) {
var value = routeMatch[index + 1];
if (value) {
value = value.indexOf(',') !== -1 ? value.split(',').map(function (v) {
return decodeParmeterValue(v);
}) : value = decodeParmeterValue(value);
}
acc[key] = value;
return acc;
}, {}));
return true;
}
// if route is a simple path
return route.uri === baseUriToCheck;
}
/**
* Module dependencies.
* @private
*/
var Requester = function () {
function Requester() {
classCallCheck(this, Requester);
}
createClass(Requester, [{
key: 'fetch',
/**
* Make an ajax request.
*
* @param {Object} request
* @param {Function} success callback
* @param {Function} failure callback
* @private
*/
value: function fetch(request, resolve, reject) {
var method = request.method,
uri = request.uri,
headers = request.headers,
data = request.data;
var success = function success(responseText) {
resolve(request, {
status: 200,
statusText: 'OK',
responseText: responseText
});
};
var fail = function fail(_ref) {
var status = _ref.status,
statusText = _ref.statusText,
errorThrown = _ref.errorThrown;
reject(request, {
status: status,
statusText: statusText,
errorThrown: errorThrown,
errors: 'HTTP ' + status + ' ' + (statusText ? statusText : '')
});
};
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4) {
//XMLHttpRequest.DONE
if (xmlhttp.status === 200) {
success(xmlhttp.responseText);
} else {
fail({ status: xmlhttp.status, statusText: xmlhttp.statusText });
}
}
};
try {
xmlhttp.open(method, uri, true);
if (headers) {
Object.keys(headers).forEach(function (header) {
xmlhttp.setRequestHeader(header, headers[header]);
});
}
if (data) {
xmlhttp.send(data);
} else {
xmlhttp.send();
}
} catch (errorThrown) {
fail({ errorThrown: errorThrown });
}
}
}]);
return Requester;
}();
var httpGetTransformer = {
uri: function uri(_ref2) {
var _uri = _ref2.uri,
headers = _ref2.headers,
data = _ref2.data;
if (!data) {
return _uri;
}
var uriWithoutAnchor = _uri,
anchor = '';
var match = /^(.*)(#.*)$/.exec(_uri);
if (match) {
var _$exec = /^(.*)(#.*)$/.exec(_uri);
var _$exec2 = slicedToArray(_$exec, 3);
uriWithoutAnchor = _$exec2[1];
anchor = _$exec2[2];
}
uriWithoutAnchor = Object.keys(data).reduce(function (gUri, d, index) {
gUri += '' + (index === 0 && gUri.indexOf('?') === -1 ? '?' : '&') + d + '=' + data[d];
return gUri;
}, uriWithoutAnchor);
return uriWithoutAnchor + anchor;
}
};
// export const httpPostTransformer = {
// 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;
// }
// };
/**
* Module dependencies.
* @private
*/
function errorIfNotFunction(toTest, message) {
if (typeof toTest !== 'function') {
throw new TypeError(message);
}
}
/**
* Settings object.
* @private
*/
var Settings = function () {
/**
* Initialize the settings.
*
* - setup default configuration
*
* @private
*/
function Settings() {
classCallCheck(this, Settings);
// default settings
this.settings = {
'http requester': new Requester(),
'http GET transformer': httpGetTransformer,
// 'http POST transformer': httpPostTransformer,
'route matcher': routeMatcher
};
this.rules = {
'http requester': function httpRequester(requester) {
errorIfNotFunction(requester.fetch, 'setting http requester has no fetch function');
},
'http GET transformer': function httpGETTransformer(transformer) {
if (!transformer || !transformer.uri && !transformer.headers && !transformer.data) {
throw new TypeError('setting http transformer one of functions: uri, headers, data is missing');
}
},
'route matcher': function routeMatcher$$1(_routeMatcher) {
errorIfNotFunction(_routeMatcher, 'setting route matcher is not a function');
}
};
}
/**
* Assign `setting` to `val`
*
* @param {String} setting
* @param {*} [val]
* @private
*/
createClass(Settings, [{
key: 'set',
value: function set$$1(name, value) {
var checkRules = this.rules[name];
if (checkRules) {
checkRules(value);
}
this.settings[name] = value;
}
/**
* Return `setting`'s value.
*
* @param {String} setting
* @private
*/
}, {
key: 'get',
value: function get$$1(name) {
return this.settings[name];
}
}]);
return Settings;
}();
/**
* Module dependencies.
* @private
*/
/**
* Application class.
*/
var Application = function () {
/**
* Initialize the application.
*
* - setup default configuration
*
* @private
*/
function Application() {
classCallCheck(this, Application);
this.routers = [];
this.settings = new Settings();
2017-06-22 19:17:18 +00:00
this.plugins = [];
}
/**
* Assign `setting` to `val`, or return `setting`'s value.
*
* app.set('foo', 'bar');
* app.set('foo');
* // => "bar"
*
* @param {String} setting
* @param {*} [val]
* @return {app} for chaining
* @public
*/
createClass(Application, [{
key: 'set',
value: function set$$1() {
2017-06-22 19:17:18 +00:00
var _settings;
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
// get behaviour
if (args.length === 1) {
return this.settings.get([args]);
}
// set behaviour
2017-06-22 19:17:18 +00:00
(_settings = this.settings).set.apply(_settings, args);
return this;
}
/**
* Listen for DOM initialization and history state changes.
*
* The callback function is called once the DOM has
* the `document.readyState` equals to 'interactive'.
*
* app.listen(()=> {
* console.log('App is listening requests');
* console.log('DOM is ready!');
* });
*
*
* @param {Function} callback
* @public
*/
}, {
key: 'listen',
value: function listen(callback) {
var _this = this;
2017-06-22 19:17:18 +00:00
var request = { method: 'GET', uri: window.location.pathname + window.location.search };
var response = { status: 200, statusText: 'OK' };
var currentRoutes = this._routes(request);
this._callMiddlewareMethod('entered', currentRoutes, request);
2017-01-15 11:00:51 +00:00
// manage history
window.onpopstate = function (event) {
if (event.state) {
var _event$state = event.state,
2017-01-15 11:00:51 +00:00
_request = _event$state.request,
_response = _event$state.response;
2017-06-22 19:17:18 +00:00
['exited', 'entered', 'updated'].forEach(function (middlewareMethod) {
return _this._callMiddlewareMethod(middlewareMethod, _this._routes(_request), _request, _response);
});
}
};
2017-01-15 11:00:51 +00:00
// manage page loading/refreshing
2017-06-22 19:17:18 +00:00
window.onbeforeunload = function () {
_this._callMiddlewareMethod('exited');
};
2017-01-15 11:00:51 +00:00
var whenPageIsInteractiveFn = function whenPageIsInteractiveFn() {
2017-06-22 19:17:18 +00:00
_this.plugins.forEach(function (pluginObject) {
return pluginObject.plugin(_this);
});
2017-01-15 11:00:51 +00:00
_this._callMiddlewareMethod('updated', currentRoutes, request, response);
if (callback) {
callback(request, response);
}
};
document.onreadystatechange = function () {
2017-01-15 11:00:51 +00:00
// DOM ready state
if (document.readyState === 'interactive') {
whenPageIsInteractiveFn();
}
};
2017-01-15 11:00:51 +00:00
if (['interactive', 'complete'].indexOf(document.readyState) !== -1) {
whenPageIsInteractiveFn();
}
}
/**
* Returns a new `Router` instance for the _uri_.
* See the Router api docs for details.
*
* app.route('/');
* // => new Router instance
*
* @param {String} uri
* @return {Router} for chaining
*
* @public
*/
}, {
key: 'route',
value: function route(uri) {
var router = new Router(uri);
this.routers.push(router);
return router;
}
/**
* Use the given middleware function or object, with optional _uri_.
* Default _uri_ is "/".
2017-06-22 19:17:18 +00:00
* Or use the given plugin
*
* // middleware function will be applied on path "/"
* app.use((req, res, next) => {console.log('Hello')});
*
* // middleware object will be applied on path "/"
* app.use(new Middleware());
*
2017-06-22 19:17:18 +00:00
* // use a plugin
* app.use({
* name: 'My plugin name',
* plugin(application) {
* // here plugin implementation
* }
* });
*
* @param {String} uri
2017-06-22 19:17:18 +00:00
* @param {Middleware|Function|plugin} middleware object, middleware function, plugin
* @return {app} for chaining
*
* @public
*/
}, {
key: 'use',
value: function use() {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
2017-01-14 14:02:50 +00:00
var _toParameters = toParameters(args),
baseUri = _toParameters.baseUri,
router = _toParameters.router,
2017-06-22 19:17:18 +00:00
middleware = _toParameters.middleware,
plugin = _toParameters.plugin;
2017-06-22 19:17:18 +00:00
if (plugin) {
this.plugins.push(plugin);
} else {
2017-06-22 19:17:18 +00:00
if (router) {
router.baseUri = baseUri;
} else if (middleware) {
router = new Router(baseUri);
HTTP_METHODS.forEach(function (method) {
router[method.toLowerCase()](middleware);
});
} else {
throw new TypeError('method takes at least a middleware or a router');
}
this.routers.push(router);
}
return this;
}
/**
* Gather routes from all routers filtered by _uri_ and HTTP _method_.
* See Router#routes() documentation for details.
*
* @private
*/
}, {
key: '_routes',
2017-06-22 19:17:18 +00:00
value: function _routes(request) {
var _this2 = this;
2017-06-22 19:17:18 +00:00
return this.routers.reduce(function (acc, router) {
acc.push.apply(acc, toConsumableArray(router.routes(_this2, request)));
return acc;
}, []);
}
/**
* Call `Middleware` method or middleware function on _currentRoutes_.
*
* @private
*/
}, {
key: '_callMiddlewareMethod',
value: function _callMiddlewareMethod(meth, currentRoutes, request, response) {
if (meth === 'exited') {
// currentRoutes, request, response params not needed
2017-01-15 11:00:51 +00:00
this.routers.forEach(function (router) {
router.visited().forEach(function (route) {
if (route.middleware.exited) {
route.middleware.exited(route.visited);
route.visited = null;
}
2017-01-15 11:00:51 +00:00
});
});
return;
}
2017-01-15 11:00:51 +00:00
currentRoutes.some(function (route) {
if (meth === 'updated') {
route.visited = request;
}
2017-01-15 11:00:51 +00:00
if (route.middleware[meth]) {
route.middleware[meth](request, response);
if (route.middleware.next && !route.middleware.next()) {
return true;
}
2017-01-15 11:00:51 +00:00
} 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;
}
}
2017-01-15 11:00:51 +00:00
return false;
});
}
/**
* Make an ajax request. Manage History#pushState if history object set.
*
* @private
*/
}, {
key: '_fetch',
2017-01-15 11:00:51 +00:00
value: function _fetch(req, resolve, reject) {
2017-06-22 19:17:18 +00:00
var _this3 = this;
2017-01-15 11:00:51 +00:00
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) {
2017-01-15 11:00:51 +00:00
var _uriFn = httpMethodTransformer.uri,
_headersFn = httpMethodTransformer.headers,
_dataFn = httpMethodTransformer.data;
req.uri = _uriFn ? _uriFn({ uri: uri, headers: headers, data: data }) : uri;
req.headers = _headersFn ? _headersFn({ uri: uri, headers: headers, data: data }) : headers;
req.data = _dataFn ? _dataFn({ uri: uri, headers: headers, data: data }) : data;
}
// calls middleware exited method
this._callMiddlewareMethod('exited');
// gathers all routes impacted by the uri
2017-06-22 19:17:18 +00:00
var currentRoutes = this._routes(req);
// calls middleware entered method
2017-01-15 11:00:51 +00:00
this._callMiddlewareMethod('entered', currentRoutes, req);
// invokes http request
2017-01-15 11:00:51 +00:00
this.settings.get('http requester').fetch(req, function (request, response) {
if (history) {
2017-01-15 11:00:51 +00:00
window.history.pushState({ request: request, response: response }, history.title, history.uri);
}
2017-06-22 19:17:18 +00:00
_this3._callMiddlewareMethod('updated', currentRoutes, request, response);
if (resolve) {
2017-01-15 11:00:51 +00:00
resolve(request, response);
}
2017-01-15 11:00:51 +00:00
}, function (request, response) {
2017-06-22 19:17:18 +00:00
_this3._callMiddlewareMethod('failed', currentRoutes, request, response);
if (reject) {
2017-01-15 11:00:51 +00:00
reject(request, response);
}
});
}
}]);
return Application;
}();
HTTP_METHODS.reduce(function (reqProto, method) {
/**
* 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 "/"
* app.get((req, res, next) => {console.log('Hello')});
*
* // middleware object will be applied on path "/" and
* app.get(new Middleware());
*
* // get a setting value
* app.set('foo', 'bar');
* app.get('foo');
* // => "bar"
*
* @param {String} uri or setting
* @param {Middleware|Function} middleware object or function
* @return {app} for chaining
* @public
*/
var middlewareMethodName = method.toLowerCase();
reqProto[middlewareMethodName] = function () {
for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
2017-01-14 14:02:50 +00:00
var _toParameters2 = toParameters(args),
baseUri = _toParameters2.baseUri,
middleware = _toParameters2.middleware,
which = _toParameters2.which;
2017-01-14 14:02:50 +00:00
if (middlewareMethodName === 'get' && typeof which === 'string') {
return this.settings.get(which);
}
2017-01-14 14:02:50 +00:00
if (!middleware) {
throw new TypeError('method takes a middleware ' + (middlewareMethodName === 'get' ? 'or a string' : ''));
}
var router = new Router();
router[middlewareMethodName](baseUri, middleware);
this.routers.push(router);
return this;
};
/**
* Ajax request (get, post, put, delete...).
*
* // HTTP GET method
* httpGet('/route1');
*
* // HTTP GET method
* httpGet({uri: '/route1', data: {'p1': 'val1'});
* // uri invoked => /route1?p1=val1
*
* // HTTP GET method with browser history management
* httpGet({uri: '/api/users', history: {state: {foo: "bar"}, title: 'users page', uri: '/view/users'});
*
* Samples above can be applied on other HTTP methods.
*
* @param {String|Object} uri or object containing uri, http headers, data, history
* @param {Function} success callback
* @param {Function} failure callback
* @public
*/
var httpMethodName = 'http' + method.charAt(0).toUpperCase() + method.slice(1).toLowerCase();
reqProto[httpMethodName] = function (request, resolve, reject) {
var uri = request.uri,
headers = request.headers,
data = request.data,
history = request.history;
if (!uri) {
uri = request;
}
return this._fetch({
uri: uri,
method: method,
headers: headers,
data: data,
history: history
}, resolve, reject);
};
return reqProto;
}, Application.prototype);
2017-01-14 14:02:50 +00:00
function toParameters(args) {
2017-06-22 19:17:18 +00:00
var _args, _args2, _args3, _args4;
2017-01-14 14:02:50 +00:00
var baseUri = void 0,
middleware = void 0,
router = void 0,
2017-06-22 19:17:18 +00:00
plugin = void 0,
2017-01-14 14:02:50 +00:00
which = void 0;
2017-06-22 19:17:18 +00:00
args.length === 1 ? (_args = args, _args2 = slicedToArray(_args, 1), which = _args2[0], _args) : (_args3 = args, _args4 = slicedToArray(_args3, 2), baseUri = _args4[0], which = _args4[1], _args3);
2017-01-14 14:02:50 +00:00
2017-06-22 19:17:18 +00:00
if (which instanceof Router) {
router = which;
} else if (which instanceof Middleware || typeof which === 'function') {
middleware = which;
} else if (which && which.plugin && typeof which.plugin === 'function') {
plugin = which;
2017-01-14 14:02:50 +00:00
}
2017-06-22 19:17:18 +00:00
return { baseUri: baseUri, middleware: middleware, router: router, plugin: plugin, which: which };
2017-01-14 14:02:50 +00:00
}
/**
* Module dependencies.
*/
/**
* Create a frontexpress application.
*
* @return {Function}
* @api public
*/
var frontexpress = function frontexpress() {
return new Application();
};
/**
* Expose Router, Middleware constructors.
*/
frontexpress.Router = function (baseUri) {
return new Router(baseUri);
};
frontexpress.Middleware = Middleware;
return frontexpress;
}());