dinoloop-es8
Version:
A lightweight REST API Library for building scalable Node.js server-side applications powered by Typescript
284 lines • 27.6 kB
JavaScript
"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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