UNPKG

protontype

Version:

A simple REST framework make in TypeScript

289 lines 11.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); require("reflect-metadata"); const express_1 = __importDefault(require("express")); const fs_1 = __importDefault(require("fs")); const https_1 = __importDefault(require("https")); const DBConnector_1 = require("../database/DBConnector"); const DefaultDBConnector_1 = require("../database/DefaultDBConnector"); const DefaultMiddleware_1 = require("../middlewares/DefaultMiddleware"); const Method_1 = require("../router/Method"); const Logger_1 = require("./Logger"); const ProtonConfigLoader_1 = require("./ProtonConfigLoader"); /** * @author Humberto Machado * Protontype main class. Configure and start Routers, Middlewares and bootstrap application */ class ProtonApplication { /** * Create Protontype aplication */ constructor(config) { this.middlewares = []; this.routers = []; this.config = this.loadConfig(config); this.logger = Logger_1.Logger.createLogger(this.config.logger); this.express = express_1.default(); } /** * Start up Protontype application. * @return express instance */ start() { return new Promise((resolve, reject) => { this.connectDB().then(connection => { DBConnector_1.ProtonDB.dbConnection = connection; this.configMiddlewares(); this.configureRoutes(); this.startServers(); resolve(this); }).catch(error => reject(error)); }); } connectDB() { if (this.dbConnector) { return this.dbConnector.createConnection(this.config.database); } else { return new DefaultDBConnector_1.DefaultDBConnector().createConnection(this.config.database); } } startServers() { let servers = this.config.servers; if (servers && servers.length > 0) { servers.forEach(server => { this.startServer(server.port, server.useHttps); }); } else { this.logger.error('No server found'); } } startServer(port, useHttps) { if (this.config.https && useHttps) { const credentials = { key: fs_1.default.readFileSync(this.config.https.key), cert: fs_1.default.readFileSync(this.config.https.cert) }; https_1.default.createServer(credentials, this.express) .listen(port, () => this.logger.info(`Application listen port ${port} (HTTPS)`)); } else { this.express.listen(port, () => this.logger.info(`Application listen port ${port} (HTTP)`)); } } loadConfig(config) { if (config) { return config; } else { config = ProtonConfigLoader_1.ProtonConfigLoader.loadConfig(); if (!config) { config = ProtonConfigLoader_1.DEFAULT_CONFIG; } return config; } } /** * Configure global Middlewares. Application scope */ configMiddlewares() { new DefaultMiddleware_1.DefaultMiddleware().init(this).configMiddlewares(); this.middlewares.forEach(middleware => { middleware.init(this); middleware.configMiddlewares(); this.express.use((req, res, next) => { middleware.middlewareFuntion.call(middleware, this.createMiddlewareFunctionParams(req, res, next, this)); if (middleware.autoNext) { next(); } }); }); } /** * Initialize all configured routes annotated with @Route */ configureRoutes() { this.routers.forEach(router => { router.init(this); let configs = router.getRouteConfigs(); if (configs != null) { let routerMiddewares = this.configRouterMiddlewares(router); configs.forEach(config => { if (config.method != null && config.endpoint != null) { this.createRoutesByMethod(config, router, routerMiddewares); } else { config.routeFunction.call(router); } }); } }); } createRoutesByMethod(routeConfig, router, routerMiddlewares) { switch (routeConfig.method) { case Method_1.Method.GET: this.express.get(router.getBaseUrl() + routeConfig.endpoint, routerMiddlewares, this.configRouteMiddlewares(routeConfig), (req, res) => { routeConfig.routeFunction.call(router, this.createRouterFunctionParams(req, res, this)); }); break; case Method_1.Method.POST: this.express.post(router.getBaseUrl() + routeConfig.endpoint, routerMiddlewares, this.configRouteMiddlewares(routeConfig), (req, res) => { routeConfig.routeFunction.call(router, this.createRouterFunctionParams(req, res, this)); }); break; case Method_1.Method.PUT: this.express.put(router.getBaseUrl() + routeConfig.endpoint, routerMiddlewares, this.configRouteMiddlewares(routeConfig), (req, res) => { routeConfig.routeFunction.call(router, this.createRouterFunctionParams(req, res, this)); }); break; case Method_1.Method.DELETE: this.express.delete(router.getBaseUrl() + routeConfig.endpoint, routerMiddlewares, this.configRouteMiddlewares(routeConfig), (req, res) => { routeConfig.routeFunction.call(router, this.createRouterFunctionParams(req, res, this)); }); break; case Method_1.Method.PATCH: this.express.patch(router.getBaseUrl() + routeConfig.endpoint, routerMiddlewares, this.configRouteMiddlewares(routeConfig), (req, res) => { routeConfig.routeFunction.call(router, this.createRouterFunctionParams(req, res, this)); }); break; case Method_1.Method.OPTIONS: this.express.options(router.getBaseUrl() + routeConfig.endpoint, routerMiddlewares, this.configRouteMiddlewares(routeConfig), (req, res) => { routeConfig.routeFunction.call(router, this.createRouterFunctionParams(req, res, this)); }); break; case Method_1.Method.HEAD: this.express.head(router.getBaseUrl() + routeConfig.endpoint, routerMiddlewares, this.configRouteMiddlewares(routeConfig), (req, res) => { routeConfig.routeFunction.call(router, this.createRouterFunctionParams(req, res, this)); }); break; } } createRouterFunctionParams(req, res, app) { return { req: req, res: res, app: app }; } createMiddlewareFunctionParams(req, res, next, app) { return { req: req, res: res, next: next, app: app }; } withDBConnector(dbConnector) { this.dbConnector = dbConnector; return this; } withDBConnectorAs(dbConnector) { this.withDBConnector(new dbConnector()); return this; } withConfig(config) { this.config = config; return this; } /** * Configures the Route Scope Middlewares */ configRouteMiddlewares(config) { return this.getExpressMiddlewaresList(config.middlewares); } /** * Configures the Router Scope Middlewares */ configRouterMiddlewares(router) { return this.getExpressMiddlewaresList(router.getRouterMiddlewares()); } getExpressMiddlewaresList(BaseMiddlewares) { let middlewares = []; if (BaseMiddlewares) { BaseMiddlewares.forEach(middleware => { if (middleware && middleware.middlewareFuntion) { middleware.init(this); middleware.configMiddlewares(); middlewares.push((req, res, next) => { middleware.middlewareFuntion.call(middleware, this.createMiddlewareFunctionParams(req, res, next, this)); if (middleware.autoNext) { next(); } }); } else { middlewares.push((req, res, next) => { next(); }); } }); } else { middlewares.push((req, res, next) => { next(); }); } return middlewares; } /** * Add Router to application * @param router Router implementation */ addRouter(router) { this.routers.push(router); return this; } addRouterAs(router) { this.addRouter(new router()); return this; } /** * Add Global Middleware. A middleware added here, will act for all routers of the application * @param middleware Middleware implementation */ addMiddleware(middleware) { this.middlewares.push(middleware); return this; } addMiddlewareAs(middleware) { this.addMiddleware(new middleware()); return this; } /** * Return a express instance * @see {@link http://expressjs.com/en/4x/api.html} */ getExpress() { return this.express; } /** * Return a list of Confugured routers */ getRouters() { return this.routers; } /** * Return {@link GlobalConfig} object. Content of proton.json file */ getConfig() { return this.config; } /** * @return list of all endpoints loaded in ProtonApplication */ getRoutesList() { let routeList = []; this.express._router.stack.forEach(r => { if (r.route && r.route.path) { routeList.push({ method: r.route.stack[0].method.toUpperCase(), path: r.route.path }); } }); this.routers.forEach(router => { router.getRouter().stack.forEach(r => { if (r.route && r.route.path) { routeList.push({ method: r.route.stack[0].method.toUpperCase(), path: router.getBaseUrl() + r.route.path }); } }); }); return routeList; } } exports.ProtonApplication = ProtonApplication; //# sourceMappingURL=ProtonApplication.js.map