UNPKG

appolo

Version:
224 lines (159 loc) 7.94 kB
import {Route} from "../routes/route"; import { Hooks, Methods, MiddlewareHandlerErrorOrAny, MiddlewareHandlerOrAny, MiddlewareHandlerParams } from "appolo-agent"; import {define} from "appolo-engine"; import {Arrays, Reflector} from "appolo-utils"; import {IMiddlewareCtr} from "../interfaces/IMiddleware"; import {IRouteOptions} from "../interfaces/IRouteOptions"; import {IController} from "../controller/IController"; import {IRequest} from "../interfaces/IRequest"; import {IResponse} from "../interfaces/IResponse"; import {Util} from "../util/util"; export const RouterDefinitionsSymbol = "__RouterDefinitions__"; export const RouterDefinitionsCompiledSymbol = "__RouterDefinitionsCompiled__"; export const RouterDefinitionsClassSymbol = "__RouterDefinitionsClass__"; export const RouterModelSymbol = "__RouterModelDefinitions__"; export const RouterControllerSymbol = "__RouterControllerDefinitions__"; function defineRouteClass(params: { name: string, args: any[] }[], target: any): void { let route = Reflector.getFnMetadata<Route<IController>>(RouterDefinitionsClassSymbol, target, new Route<IController>(target)); route = route.clone(); (params || []).forEach(param => { route[param.name].apply(route, param.args) }); Reflector.setMetadata(RouterDefinitionsClassSymbol,route , target); } export function controller(name?: string): (target: any) => void { return function (name: string, target: any) { Reflect.defineMetadata(RouterControllerSymbol, name || "", target); define("")(target); }.bind(null, name) } function defineRouteProperty(params: { name: string, args: any[] }[]): (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => void { return function (params: { name: string, args: any[] }[], target: any, propertyKey: string, descriptor: PropertyDescriptor) { if (!propertyKey) { defineRouteClass(params, target) } let data = Reflector.getFnMetadata<{ [index: string]: Route<IController> }>(RouterDefinitionsSymbol, target.constructor, {}); let route = data[propertyKey]; if (!route) { data[propertyKey] = route = new Route<IController>(target.constructor); route.action(propertyKey); } else { route = data[propertyKey] = route.clone(); } (params || []).forEach(param => { route[param.name].apply(route, param.args) }) }.bind(null, params) } // // export function path(path: string): any { // return defineRouteProperty([{name: "path", args: [path]}, {name: "method", args: [Methods.GET]}]) // // } export function get(path?: string): (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => void { return defineRouteProperty([{name: "path", args: [path || ""]}, {name: "method", args: [Methods.GET]}]) } export function post(path?: string): (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => void { return defineRouteProperty([{name: "path", args: [path || ""]}, {name: "method", args: [Methods.POST]}]) } export function patch(path?: string): (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => void { return defineRouteProperty([{name: "path", args: [path || ""]}, {name: "method", args: [Methods.PATCH]}]) } export function put(path?: string): (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => void { return defineRouteProperty([{name: "path", args: [path || ""]}, {name: "method", args: [Methods.PUT]}]) } export function del(path?: string): (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => void { return defineRouteProperty([{name: "path", args: [path || ""]}, {name: "method", args: [Methods.DELETE]}]) } export function purge(path?: string): (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => void { return defineRouteProperty([{name: "path", args: [path || ""]}, {name: "method", args: [Methods.PURGE]}]) } export function method(method: 'get' | 'post' | 'delete' | 'patch' | 'head' | 'put' | Methods) { return defineRouteProperty([{name: "method", args: [method]}]) } export function hook(name: Hooks.OnError, ...hook: (string | MiddlewareHandlerErrorOrAny | IMiddlewareCtr)[]) export function hook(name: Hooks.OnResponse | Hooks.PreMiddleware | Hooks.PreHandler | Hooks.OnRequest, ...hook: (string | MiddlewareHandlerErrorOrAny | IMiddlewareCtr)[]) export function hook(name: Hooks.OnSend, ...hook: (string | MiddlewareHandlerOrAny | IMiddlewareCtr)[]) export function hook(name: Hooks, ...hook: (string | MiddlewareHandlerParams | IMiddlewareCtr)[]) { return defineRouteProperty([{name: "addHook", args: [name, ...hook]}]) } export function middleware(middleware: string | string[] | MiddlewareHandlerOrAny | MiddlewareHandlerOrAny[] | IMiddlewareCtr | IMiddlewareCtr[]): any { if (Array.isArray(middleware)) { middleware = Arrays.clone(middleware as string[]).reverse() } return defineRouteProperty([{name: "middleware", args: [middleware, "head"]}]) } export function error(middleware: string | string[] | MiddlewareHandlerErrorOrAny | MiddlewareHandlerErrorOrAny[] | IMiddlewareCtr | IMiddlewareCtr[]): any { if (Array.isArray(middleware)) { middleware = Arrays.clone(middleware as string[]).reverse() } return defineRouteProperty([{name: "error", args: [middleware, "head"]}]) } export function abstract(route: Partial<IRouteOptions>): (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => void { Util.reverseMiddleware(route); return defineRouteProperty([{name: "abstract", args: [route]}]) } export function roles(role: string | string[]): any { return defineRouteProperty([{name: "roles", args: [role]}]) } export function gzip() { return defineRouteProperty([{name: "gzip", args: []}]) } export function header(key: string, value: string) { return defineRouteProperty([{name: "headers", args: [key, value]}]) } export function statusCode(code: number) { return defineRouteProperty([{name: "statusCode", args: [code]}]) } export function customRouteDecorator(fn: ((req: IRequest, res: IResponse, route: IRouteOptions) => void)) { return defineRouteProperty([{name: "customRouteFn", args: [fn]}]) } export function customRouteParam(fn: ((req: IRequest, res: IResponse, route: IRouteOptions) => void)) { return function (target: Object, propertyKey: string, parameterIndex: number) { defineRouteProperty([{name: "customRouteParam", args: [parameterIndex, fn]}])(target, propertyKey) } } export let body = function (param?: string) { return customRouteParam(function (req: IRequest) { return param != undefined ? req.body[param] : req.body }) }; export let headers = function (param?: string) { return customRouteParam(function (req: IRequest) { return param != undefined ? req.headers[param] : req.headers }) }; export let query = function (param?: string) { return customRouteParam(function (req: IRequest) { return param != undefined ? req.query[param] : req.query }) }; export let model = function (param?: string) { return customRouteParam(function (req: IRequest) { if (!req.model) { req.model = Object.assign({}, req.body || {}, req.query || {}, req.params || {}); } return param != undefined ? req.model[param] : req.model }) }; export let params = function (param?: string) { return customRouteParam(function (req: IRequest) { return param != undefined ? req.params[param] : req.params }) }; export let req = function () { return customRouteParam(function (req: IRequest) { return req }) }; export let res = function () { return customRouteParam(function (req: IRequest, res: IResponse) { return res }) };