mirror of
https://gitlab.silvrtree.co.uk/martind2000/frontexpress.git
synced 2025-01-11 21:55:09 +00:00
161 lines
5.0 KiB
JavaScript
Executable File
161 lines
5.0 KiB
JavaScript
Executable File
import Router, {Route} from './router';
|
|
import Middleware from './middleware';
|
|
import Requester, {HTTP_METHODS} from './requester';
|
|
|
|
export default class Application {
|
|
constructor() {
|
|
this.routers = [];
|
|
this.requester = new Requester();
|
|
this.lastVisited = null;
|
|
|
|
this.settingsDef = {
|
|
'http-requester': (requester) => {this.requester = requester}
|
|
};
|
|
}
|
|
|
|
////////////////////////////////////////////////////////
|
|
// Setting
|
|
set(name, value) {
|
|
const settingFn = this.settingsDef[name];
|
|
if (!settingFn) {
|
|
throw new ReferenceError(`unsupported setting ${name}`);
|
|
}
|
|
settingFn(value);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////
|
|
// Routes
|
|
route(uri) {
|
|
const router = new Router(uri);
|
|
this.routers.push(router);
|
|
return router;
|
|
}
|
|
|
|
use(...args) {
|
|
if (args.length === 0) {
|
|
throw new TypeError(`use method takes at least a middleware or a router`);
|
|
}
|
|
|
|
let baseUri, middleware, router, which;
|
|
|
|
if (args.length === 1) {
|
|
[which,] = args;
|
|
} else {
|
|
[baseUri, which,] = args;
|
|
}
|
|
|
|
if (!(which instanceof Middleware) && (typeof which !== 'function') && !(which instanceof Router)) {
|
|
throw new TypeError(`use method takes at least a middleware or a router`);
|
|
}
|
|
|
|
if (which instanceof Router) {
|
|
router = which;
|
|
router.baseUri = baseUri;
|
|
} else {
|
|
middleware = which;
|
|
router = new Router(baseUri);
|
|
for (const method of Object.keys(HTTP_METHODS)) {
|
|
router[method.toLowerCase()](middleware);
|
|
}
|
|
}
|
|
this.routers.push(router);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////
|
|
// Ajax request
|
|
_fetch({method, uri, headers, data}, resolve, reject) {
|
|
if (this.lastVisited) {
|
|
for (const router of this.routers) {
|
|
const routes = router.getRoutes(this.lastVisited.uri, this.lastVisited.method);
|
|
for (const route of routes) {
|
|
if (route.middleware.exited) {
|
|
route.middleware.exited(this.lastVisited);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const currentRoutes = [];
|
|
for (const router of this.routers) {
|
|
const routes = router.getRoutes(uri, method);
|
|
currentRoutes.push(...routes);
|
|
}
|
|
|
|
for (const route of currentRoutes) {
|
|
if (route.middleware.entered) {
|
|
route.middleware.entered({method, uri, headers, data});
|
|
}
|
|
}
|
|
|
|
this.requester.fetch({uri, method}, (request, response) => {
|
|
this.lastVisited = {method, uri, headers, data};
|
|
|
|
for (const route of currentRoutes) {
|
|
if (route.middleware.updated) {
|
|
route.middleware.updated(request, response);
|
|
} else {
|
|
route.middleware(request, response);
|
|
}
|
|
}
|
|
if (resolve) {
|
|
resolve(request, response);
|
|
}
|
|
}, (request, response) => {
|
|
for (const route of currentRoutes) {
|
|
if (route.middleware.failed) {
|
|
route.middleware.failed(request, response);
|
|
}
|
|
}
|
|
if (reject) {
|
|
reject(request, response);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
Object.keys(HTTP_METHODS).reduce((reqProto, method) => {
|
|
// Middleware methods
|
|
const middlewareMethodeName = method.toLowerCase();
|
|
reqProto[middlewareMethodeName] = function(...args) {
|
|
if (args.length === 0) {
|
|
throw new TypeError(`${middlewareMethodeName} method takes at least a middleware`);
|
|
}
|
|
|
|
let baseUri, middleware, which;
|
|
|
|
if (args.length === 1) {
|
|
[which,] = args;
|
|
} else {
|
|
[baseUri, which,] = args;
|
|
}
|
|
|
|
if (!(which instanceof Middleware) && (typeof which !== 'function')) {
|
|
throw new TypeError(`${middlewareMethodeName} method takes at least a middleware`);
|
|
}
|
|
|
|
const router = new Router();
|
|
middleware = which;
|
|
router[middlewareMethodeName](baseUri, middleware);
|
|
|
|
this.routers.push(router);
|
|
}
|
|
|
|
// HTTP methods
|
|
const transformer = HTTP_METHODS[method];
|
|
const httpMethodName = 'http'+method.charAt(0).toUpperCase() + method.slice(1).toLowerCase();
|
|
reqProto[httpMethodName] = function(request, resolve, reject) {
|
|
let {uri, headers, data} = request;
|
|
if (!uri) {
|
|
uri = request;
|
|
}
|
|
return this._fetch({
|
|
uri,
|
|
method,
|
|
headers,
|
|
data,
|
|
}, resolve, reject);
|
|
}
|
|
|
|
return reqProto;
|
|
}, Application.prototype);
|