1 | import { Response } from './app';
|
2 | import { capitalize, isArray } from './lib';
|
3 | import middlewares from './middlewares';
|
4 | import app from './app';
|
5 |
|
6 | class Router {
|
7 |
|
8 | routers = [];
|
9 | rootPaths = [];
|
10 | controllersPath;
|
11 | actionName;
|
12 | controllerName;
|
13 | guardian;
|
14 |
|
15 | setControllersPath(path) {
|
16 | this.controllersPath = path;
|
17 | }
|
18 |
|
19 | setGuardian(guardian) {
|
20 | this.guardian = guardian;
|
21 | }
|
22 |
|
23 | routes(rootPath, routes) {
|
24 | if (isArray(routes)) {
|
25 | this.rootPaths.push(rootPath);
|
26 | this.routers.push(routes);
|
27 | } else {
|
28 | throw new Error('routes in "Router" must be array.');
|
29 | }
|
30 | }
|
31 |
|
32 | route(req, res) {
|
33 | const {url, method} = req;
|
34 |
|
35 | this.routers.map((router, routerIndex) => {
|
36 | router.map(route => {
|
37 | route.method = route.method.toUpperCase();
|
38 |
|
39 | const response = new Response(res);
|
40 | let rootPath = this.rootPaths[routerIndex];
|
41 |
|
42 | const run = () => {
|
43 | if (route.middleWares && !route.action) {
|
44 | return middlewares(req, res, route.middleWares);
|
45 | } else if (route.middleWares && route.action) {
|
46 | throw new Error('params: action and middleWares cannot work together');
|
47 | }
|
48 |
|
49 | const urlCondition = ((url === '/' ? '' : url) + '/');
|
50 | if (rootPath === '/' && route.path === '/') rootPath = '';
|
51 |
|
52 | if ((urlCondition === `${rootPath}${route.path}` || url === `${rootPath}${route.path}`) && method === route.method) {
|
53 | let [name, action] = route.action.split('@');
|
54 | this.actionName = action;
|
55 | this.controllerName = capitalize(name);
|
56 | let Controller;
|
57 |
|
58 | try {
|
59 | Controller = new (require(`${this.controllersPath}/${name}`)[this.controllerName]);
|
60 | } catch(e) {
|
61 | throw new Error(`${this.controllerName} controller contains error or cannot find "${this.controllersPath}/${name}" in ${app.get('base')}`);
|
62 | }
|
63 |
|
64 | this.action(req, res, Controller[action].bind(Controller), response);
|
65 | }
|
66 | };
|
67 |
|
68 | if (route.guard) {
|
69 | if (this.guardian) {
|
70 | return this.guardian({ req: req, res: res, next: run, response: response });
|
71 | } else {
|
72 | throw new Error('"guardian" is undefined. Please, set guardian in app.');
|
73 | }
|
74 | }
|
75 |
|
76 | run();
|
77 | })
|
78 | });
|
79 | }
|
80 |
|
81 | action(req, res, method, response) {
|
82 | method({ req: req, res: res, response: response });
|
83 | }
|
84 |
|
85 | }
|
86 |
|
87 | export default new Router();
|