UNPKG

dinoloop-es8

Version:

A lightweight REST API Library for building scalable Node.js server-side applications powered by Typescript

284 lines 27.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const dicontainer_1 = require("./dicontainer"); const dino_controller_1 = require("./dino.controller"); const dino_error_controller_1 = require("./dino.error.controller"); const router_1 = require("../router"); const controller_1 = require("../controller"); const lib_1 = require("../lib"); const utility_1 = require("../utility"); const constants_1 = require("../constants"); const providers_1 = require("../providers"); class DinoContainer { constructor(config) { this.app = config.app; this.baseUri = config.baseUri; this.enableTaskContext = config.enableTaskContext; this.useRouterCb = config.routerCallback; this.diContainer = dicontainer_1.DIContainer.create(config.diContainer, config.diResolveCb); this.routeTable = router_1.RouteTable.create(); } // made public for unit test and not available on interface contract resolve(middleware, dino) { let o = this.diContainer.resolve(middleware); if (utility_1.DataUtility.isUndefinedOrNull(dino)) { return o; } // walk-through the entire object chain and replace IUserIdentity instance References return this.enableTaskContext ? utility_1.ObjectUtility.replaceObjectReferences(o, dino.context, providers_1.IUserIdentity) : o; } routeNotFoundMiddleware(middleware) { if (utility_1.DinoUtility.isSyncRequestStartMiddleware(middleware)) { // created as singleton object let mw = new middleware(this.routeTable); this.app.use(this.baseUri, (req, res, next) => { mw.invoke(req, res, next); }); } } // create builtin middlewares as singleton objects // ex: DinoStartMiddleware, TaskContextMiddleware builtInRequestStartMiddleware(middleware) { if (utility_1.DinoUtility.isSyncRequestStartMiddleware(middleware)) { let mw = new middleware(); this.app.use(this.baseUri, (req, res, next) => { mw.invoke(req, res, next); }); } } // ex: ResponseEndMiddleware builtInRequestEndMiddleware(middleware) { if (utility_1.DinoUtility.isSyncRequestEndMiddleware(middleware)) { let mw = new middleware(); this.app.use(this.baseUri, (req, res, next) => { mw.invoke(req, res, next, res.locals.dino.result); }); } } // ex: ResponseEndMiddleware builtInErrorMiddleware(middleware) { if (utility_1.DinoUtility.isSyncErrorMiddleware(middleware)) { let mw = new middleware(); this.app.use(this.baseUri, (err, req, res, next) => { mw.invoke(err, req, res, next); }); } } appStartMiddleware(middleware) { if (utility_1.DinoUtility.isSyncAppStartMiddleware(middleware)) { let mw = this.resolve(middleware, null); mw.invoke(); } } requestStartMiddleware(middleware) { if (utility_1.DinoUtility.isSyncRequestStartMiddleware(middleware)) { this.app.use(this.baseUri, (req, res, next) => { let mw = this.resolve(middleware, res.locals.dino); mw.invoke(req, res, next); }); } else if (utility_1.DinoUtility.isAsyncRequestStartMiddleware(middleware)) { this.app.use(this.baseUri, async (req, res, next) => { try { let mw = this.resolve(middleware, res.locals.dino); await mw.invoke(req, res, next); } catch (err) { next(err); } }); } } requestEndMiddleware(middleware) { if (utility_1.DinoUtility.isSyncRequestEndMiddleware(middleware)) { this.app.use(this.baseUri, (req, res, next) => { let mw = this.resolve(middleware, res.locals.dino); mw.invoke(req, res, next, res.locals.dino.result); }); } else if (utility_1.DinoUtility.isAsyncRequestEndMiddleware(middleware)) { this.app.use(this.baseUri, async (req, res, next) => { try { let mw = this.resolve(middleware, res.locals.dino); await mw.invoke(req, res, next, res.locals.dino.result); } catch (err) { next(err); } }); } } // Any error occurred in dinoloop instance will be propagated to these middlewares registerErrorMiddleware(middleware) { if (utility_1.DinoUtility.isSyncErrorMiddleware(middleware)) { this.app.use(this.baseUri, (err, req, res, next) => { let mw = this.resolve(middleware, res.locals.dino); mw.invoke(err, req, res, next); }); } else if (utility_1.DinoUtility.isAsyncErrorMiddleware(middleware)) { this.app.use(this.baseUri, async (err, req, res, next) => { let mw = this.resolve(middleware, res.locals.dino); try { await mw.invoke(err, req, res, next); } catch (err) { next(err); } }); } } // Register the global application error controller for the dinoloop instance // This can be considered as last error handler for the error object registerErrorController(type) { if (utility_1.DinoUtility.isErrorController(type)) { this.app.use(this.baseUri, (err, req, res, next) => { let api = this.resolve(type, res.locals.dino); let ctx = dino_error_controller_1.DinoErrorController.create(api); ctx.patch(err, req, res, next); ctx.invoke(constants_1.Constants.errControllerDefaultMethod); }); } } // made public for unit test and not available on interface contract setUpDinoController(type, actionAttr, res) { let api = this.resolve(type, res.locals.dino); let action = controller_1.ControllerAction.create(actionAttr); let ctx = dino_controller_1.DinoController.create(api, action); return ctx; } // Populates controller middlewares, filters etc by walking up the controllers inheritance chain // made public for unit test and not available on interface contract populateControllerMiddlewares(obj) { let objProto = utility_1.ObjectUtility.getPrototypeOf(obj); let metadata = lib_1.Reflector.getMetadata(constants_1.Attribute.controller, obj); let exceptionFilters = []; let resultFilters = []; let middlewares = []; let prefixes = []; let beforeActionFilters = []; let afterActionFilters = []; let expressWares = []; while (!(utility_1.DataUtility.isUndefinedOrNull(metadata))) { let reverseFilters = metadata.filters.slice().reverse(); metadata.middlewares.reverse(); metadata.use.reverse(); prefixes.push(metadata.prefix .split('') .reverse() .join('')); for (const expressWare of metadata.use) expressWares.push(expressWare); for (const filter of metadata.filters) afterActionFilters.push(filter); for (const filter of reverseFilters) beforeActionFilters.push(filter); for (const middleware of metadata.middlewares) middlewares.push(middleware); for (const filter of metadata.exceptions) exceptionFilters.push(filter); for (const filter of metadata.result) resultFilters.push(filter); objProto = utility_1.ObjectUtility.getPrototypeOf(objProto); metadata = lib_1.Reflector.getOwnMetadata(constants_1.Attribute.controller, objProto); } expressWares.reverse(); middlewares.reverse(); beforeActionFilters.reverse(); let prefixRoute = prefixes .join('') .split('') .reverse() .join(''); return { middlewares: middlewares, use: expressWares, exceptions: exceptionFilters, result: resultFilters, prefix: prefixRoute, afterActionFilters: afterActionFilters, beforeActionFilters: beforeActionFilters }; } // made public for unit test and not available on interface contract // gets all the attributes that are attached to action method getActionMethodMetadata(httpAttribute, actionName, controller) { let route = lib_1.Reflector.getMetadata(httpAttribute, controller, actionName); let httpVerb = constants_1.RouteAttribute[httpAttribute]; let isAsync = lib_1.Reflector.hasMetadata(constants_1.Attribute.asyncAttr, controller, actionName); let sendsResponse = lib_1.Reflector.hasMetadata(constants_1.Attribute.sendsResponse, controller, actionName); let actionArgs = lib_1.Reflector.getMetadata(constants_1.Attribute.parse, controller, actionName); let obj = { route: route, httpVerb: httpVerb, isAsync: isAsync, sendsResponse: sendsResponse, actionArguments: utility_1.DataUtility.isUndefinedOrNull(actionArgs) ? [] : actionArgs }; return obj; } // Registers and binds the controller with express router registerController(type) { if (!utility_1.DinoUtility.isApiController(type)) return; let controller = utility_1.ObjectUtility.create(type.prototype); // validate if the controller has @Controller attribute if (lib_1.Reflector.hasMetadata(constants_1.Attribute.controller, controller)) { let metadata = this.populateControllerMiddlewares(controller); let dinoRoute = router_1.DinoRouter.create({ enableTaskContext: this.enableTaskContext, routerCb: this.useRouterCb, diContainer: this.diContainer }); const router = dinoRoute.expressRouter(); // Register expresswares before anything else gets registered on the router // expresswares are the native express middleware handlers. for (const expressWare of metadata.use) { router.use(expressWare); } dinoRoute.registerMiddlewares(metadata.middlewares); dinoRoute.registerBeginActionFilters(metadata.beforeActionFilters); const props = utility_1.DinoUtility.getControllerProperties(controller); // loop through all the controller action methods // this also includes the inherited base controllers action methods for (let actionName of props) { // loop through every HttpVerb key i.e. get, post ... utility_1.ObjectUtility.keys(constants_1.RouteAttribute).forEach(httpAttribute => { // Check if the controller action has HttpVerb (get, post ...) attribute if (lib_1.Reflector.hasMetadata(httpAttribute, controller, actionName)) { let action = this.getActionMethodMetadata(httpAttribute, actionName, controller); this.routeTable .add(`${this.baseUri}${metadata.prefix}${action.route}`, action.httpVerb); if (action.isAsync) { router[action.httpVerb](action.route, async (req, res, next) => { let ctx = this.setUpDinoController(type, action, res); ctx.patch(req, res, next); ctx.invokeAsync(actionName); }); } else { router[action.httpVerb](action.route, (req, res, next) => { let ctx = this.setUpDinoController(type, action, res); ctx.patch(req, res, next); ctx.invoke(actionName); }); } } }); } dinoRoute.registerAfterActionFilters(metadata.afterActionFilters); dinoRoute.registerResultFilters(metadata.result); // Register the router on the app instance this.app.use(this.baseUri + metadata.prefix, router); // Note: router specific Error middlewares must be registered, // only after registering the router with the express.app instance. dinoRoute.registerExceptionFilters(this.app, this.baseUri + metadata.prefix, metadata.exceptions); } } static create(config) { return new DinoContainer(config); } } exports.DinoContainer = DinoContainer; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGluby5jb250YWluZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbW9kdWxlcy9jb3JlL2Rpbm8uY29udGFpbmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQ0EsK0NBQTRDO0FBQzVDLHVEQUFtRDtBQUNuRCxtRUFBOEQ7QUFDOUQsc0NBQW1EO0FBQ25ELDhDQUl1QjtBQUN2QixnQ0FBbUM7QUFDbkMsd0NBSW9CO0FBaUJwQiw0Q0FJc0I7QUFDdEIsNENBQTZDO0FBVzdDO0lBUUksWUFBWSxNQUE0QjtRQUNwQyxJQUFJLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUM7UUFDdEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDO1FBQzlCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUM7UUFDbEQsSUFBSSxDQUFDLFdBQVcsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxXQUFXLEdBQUcseUJBQVcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDOUUsSUFBSSxDQUFDLFVBQVUsR0FBRyxtQkFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQzFDLENBQUM7SUFFRCxvRUFBb0U7SUFDcEUsT0FBTyxDQUFJLFVBQW9CLEVBQUUsSUFBcUI7UUFDbEQsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUksVUFBVSxDQUFDLENBQUM7UUFFaEQsSUFBSSxxQkFBVyxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ3JDLE9BQU8sQ0FBQyxDQUFDO1NBQ1o7UUFFRCxxRkFBcUY7UUFDckYsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUMzQix1QkFBYSxDQUFDLHVCQUF1QixDQUFDLENBQUMsRUFBRSxJQUFJ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