aztec
Version:
Node Js Framework for creating API Services
230 lines (197 loc) • 5.76 kB
text/typescript
import { isString, isArray, reverse, uniqBy, map, extend } from 'lodash';
import { Base } from '../base.class';
import { $Router, $Route } from '../models.lib';
import { slashAdd, slashValid } from "../lib";
export class Router extends Base {
private routers: $Router[] = [];
private path: string;
private basePath: string;
constructor(private svc) {
super();
}
rest(path: string, handler: any, param: string = 'id'): void {
let routes;
if (isString(handler)) {
routes = [
{
method: 'GET',
path: `/`,
action: `${handler}@index`,
basePath: this.basePath
},
{
method: 'GET',
path: `/:${param}`,
action: `${handler}@show`,
basePath: this.basePath
},
{
method: 'POST',
path: `/`,
action: `${handler}@create`,
basePath: this.basePath
},
{
method: 'PUT',
path: `/:${param}`,
action: `${handler}@update`,
basePath: this.basePath
},
{
method: 'DELETE',
path: `/:${param}`,
action: `${handler}@destroy`,
basePath: this.basePath
},
{
method: 'DELETE',
path: `/`,
action: `${handler}@destroyAll`,
basePath: this.basePath
}
]
} else if (isArray(handler)) {
routes = [
{
method: 'GET',
path: `/`,
middlewares: [handler[0]],
basePath: this.basePath
},
{
method: 'GET',
path: `/:${param}`,
middlewares: [handler[1]],
basePath: this.basePath
},
{
method: 'POST',
path: `/`,
middlewares: [handler[2]],
basePath: this.basePath
},
{
method: 'PUT',
path: `/:${param}`,
middlewares: [handler[3]],
basePath: this.basePath
},
{
method: 'DELETE',
path: `/:${param}`,
middlewares: [handler[4]],
basePath: this.basePath
},
{
method: 'DELETE',
path: `/`,
middlewares: [handler[5]],
basePath: this.basePath
}
]
}
if (routes) {
this.routers.push({
rootPath: `api/${this.svc.get('api-prefix')}1${path}`,
routes: routes
});
if (this.svc.get('v2')) {
this.routers.push({
rootPath: `api/${this.svc.get('api-prefix')}2${path}`,
routes: routes
});
}
}
}
useRoute(route: $Route): void {
let prepareRoute, prepareRoute2;
if (!route.render) {
prepareRoute = {
rootPath: `api/${this.svc.get('api-prefix')}1${route.path}`,
routes: null
};
if (this.svc.get('v2')) {
prepareRoute2 = {
rootPath: `api/${this.svc.get('api-prefix')}2${route.path}`,
routes: null
};
}
} else {
prepareRoute = {
rootPath: route.path,
routes: null
};
}
route = extend(route, { basePath: this.basePath });
route.path = '/';
prepareRoute.routes = [route];
this.routers.push(prepareRoute);
if (prepareRoute2) {
prepareRoute2.routes = [route];
this.routers.push(prepareRoute2);
}
}
useRoutes(rootPath: string, routes: $Route[]): void {
rootPath = slashAdd(rootPath);
routes = reverse(routes);
routes = uniqBy(routes, 'path');
routes = routes.map(route => extend(route, { basePath: this.basePath }));
this.routers.push({
rootPath: `api/${this.svc.get('api-prefix')}1${rootPath}`,
routes: routes,
});
if (this.svc.get('v2')) {
this.routers.push({
rootPath: `api/${this.svc.get('api-prefix')}2${rootPath}`,
routes: routes,
});
}
}
mergeRoutes(): void {
let routers: any = {};
this.routers.forEach(router => {
const regex = new RegExp(`(${this.svc.get('api-perfix')}1|${this.svc.get('api-perfix')}2)`, 'g');
if (router.rootPath.match(regex) && router.rootPath.match(regex).length > 1) {
return router = undefined;
}
if (!routers[router.rootPath]) {
routers[router.rootPath] = router;
} else if (routers[router.rootPath]) {
router.routes = reverse([ ...routers[router.rootPath].routes, ...router.routes ]);
routers[router.rootPath] = router;
}
});
routers = map(routers, (val, key) => routers[key]);
this.routers = uniqBy(reverse(routers), 'rootPath');
}
mergeAppRoutes(root: string = ''): void {
root = slashAdd(root);
root = slashValid(root);
this.routers = this.routers.map(router => {
router.routes.forEach(route => {
if (root.length > 1 && !route.render) {
let partialPath = router.rootPath.split(`api/${this.svc.get('api-prefix')}1`);
router.rootPath = `/api/${this.svc.get('api-prefix')}1${root}${partialPath[0] || partialPath[1]}`;
} else {
router.rootPath = `${root}${router.rootPath}`;
}
});
return router;
});
if (this.svc.get('v2')) {
let localRouters = [];
this.routers.forEach(router => {
router.routes.forEach(route => {
if (root.length > 1 && !route.render) {
let partialPath = router.rootPath.split(`api/${this.svc.get('api-prefix')}1`);
localRouters.push({
rootPath: `/api/${this.svc.get('api-prefix')}2${partialPath[1]}`,
routes: router.routes
});
}
});
});
this.routers = [...this.routers, ...localRouters];
}
}
}