aztec
Version:
Node Js Framework for creating API Services
169 lines (131 loc) • 5.18 kB
text/typescript
import http = require('http');
import fs = require('fs');
import { $Router, $Route, $Middleware } from '../models.lib';
import { middleware } from '../middleware.func';
import { slashValid, dropIfNotDefault } from '../lib';
import { Base } from '../base.class';
import { replace, endsWith, camelCase } from 'lodash';
import { Router } from "./router.class";
import { ControllersManager } from "../controllers-manager.class";
import { Handler } from "../handler.class";
export class RouterController extends Base {
constructor(private app) {
super();
}
parseParams(url: string, path: string, req): string {
if (path.indexOf('/:') > -1) {
let pattern = /:([a-z]|-[a-z])+/g;
let params = path.match(pattern);
params.forEach(param => {
path.split(param).forEach(item => {
if (url.search(item) > -1 && item.length) {
let slicedItem = url.slice(item.length);
let match = slicedItem.match('/');
if (match) {
let result = slicedItem.slice(0, match.index);
req.params[camelCase(param.slice(1))] = result;
path = replace(path, param, result);
} else if (endsWith(url, slicedItem)) {
let result = slicedItem.slice(0);
req.params[camelCase(param.slice(1))] = result;
path = replace(path, param, result);
}
}
});
});
}
return path;
}
parseRequest(svc, req, res) {
let {url, method} = req;
let statusCode: number = 404;
const Router: Router = this.app.get('router');
const ControllersManager: ControllersManager = this.app.get('controllersManager');
let Guardian: $Middleware;
let app;
if (url.indexOf('.html') > -1) {
statusCode = 200;
if (svc.get('public-path')) {
return res.render(`${svc.get('public-path')}${url}`).end();
} else {
return Handler.error('Cannot get "public-path". Please, set "public-path" in your service.');
}
}
if (url.indexOf('.css') > -1) {
statusCode = 200;
if (svc.get('public-path')) {
return res.render(`${svc.get('public-path')}${url}`, 'css').end();
} else {
return Handler.error('Cannot get "public-path". Please, set "public-path" in your service.');
}
}
if (url.indexOf('.js') > -1) {
statusCode = 200;
if (svc.get('public-path')) {
return res.render(`${svc.get('public-path')}${url}`, 'js').end();
} else {
return Handler.error('Cannot get "public-path". Please, set "public-path" in your service.');
}
}
if (url.indexOf('.xml') > -1) {
statusCode = 200;
if (svc.get('public-path')) {
return res.render(`${svc.get('public-path')}${url}`, 'xml').end();
} else {
return Handler.error('Cannot get "public-path". Please, set "public-path" in your service.');
}
}
Router.get('routers').forEach((router: $Router) => {
url = slashValid(url);
router.rootPath = slashValid(router.rootPath);
router.routes.forEach((route: $Route) => {
if (route.action && route.middlewares) {
return Handler.error('Property "action" can\'t work with "middlewares". Please, choose one property.');
}
app = dropIfNotDefault(route.basePath);
Guardian = app.get('guardian');
let path = slashValid(`${router.rootPath}${route.path}`);
path = this.parseParams(url, path, req);
if (route.action) {
let [componentName, action] = route.action.split(ControllersManager.get('prefix'));
let controllerName = `${componentName}Controller`;
const run = (): void => {
const RequiredController = app.get('controllers')[controllerName];
try {
RequiredController[action].bind(RequiredController);
} catch(e) {
Handler.error(`There is no action "${action}" in controller "${controllerName}"`);
}
RequiredController.model = app.get('models')[componentName];
RequiredController[action](req, res);
};
if (url === path && method === route.method) {
statusCode = 200;
if (Guardian && route.guard) {
return Guardian(req, res, run);
}
run();
}
} else if (route.middlewares) {
if (url === path && method === route.method) {
statusCode = 200;
const run = (): void => {
middleware(req, res, route.middlewares);
};
if (Guardian && route.guard) {
return Guardian(req, res, run);
}
run();
}
} else {
Handler.error('Setup one of the: "action", "middlewares", "render" property in a route.');
}
});
});
if (statusCode !== 200 && app.get('error-handler')) {
app.get('error-handler')(req, res, statusCode);
} else if (statusCode !== 200) {
res.status(statusCode).send({ message: http.STATUS_CODES[statusCode], code: statusCode });
}
}
}