UNPKG

tachijs

Version:

Highly testable dead simple web server written in Typescript

120 lines 4.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const express_1 = tslib_1.__importDefault(require("express")); const decorators_1 = require("./decorators"); const BaseController_1 = require("./BaseController"); const results_1 = require("./results"); const Injector_1 = require("./Injector"); function tachijs(options) { const { app = express_1.default(), controllers = [], container = {}, before, after } = options; return new TachiJSApp(app, controllers, container, before, after).build(); } exports.tachijs = tachijs; class TachiJSApp { constructor(app, controllers, container, before, after) { this.app = app; this.controllers = controllers; this.container = container; this.before = before; this.after = after; this.injector = new Injector_1.Injector(container); } build() { const { app, before, after, controllers } = this; if (before != null) before(app); controllers.map(ControllerConstructor => { const controllerMeta = decorators_1.getControllerMeta(ControllerConstructor); if (controllerMeta == null) throw new Error(`Please apply @controller decorator to "${ControllerConstructor.name}".`); const router = express_1.default.Router(controllerMeta.routerOptions); this.bindControllerRoutes(router, ControllerConstructor, controllerMeta); app.use(controllerMeta.path, router); }); if (after != null) after(app); return app; } bindControllerRoutes(router, ControllerConstructor, controllerMeta) { const methodList = decorators_1.getHttpMethodMetaList(ControllerConstructor); methodList.map(methodMeta => { const handler = this.makeRequestHandler(ControllerConstructor, methodMeta); this.bindHandler(router, controllerMeta, methodMeta, handler); }); } makeRequestHandler(ControllerConstructor, methodMeta) { return async (req, res, next) => { try { const controller = this.injector.instantiate(ControllerConstructor); if (controller instanceof BaseController_1.BaseController) { controller.context = { req, res, inject: (key) => { return this.injector.inject(key); } }; } const method = controller[methodMeta.propertyKey]; const paramMetaList = decorators_1.getHandlerParamMetaList(controller.constructor, methodMeta.propertyKey); const args = []; await Promise.all(paramMetaList.map(async (paramMeta) => { args[paramMeta.index] = await paramMeta.selector(req, res, next, paramMeta); })); const result = await method.bind(controller)(...args); if (result instanceof results_1.BaseResult) { await result.execute(req, res, next); return; } if (!res.finished) { res.send(result); } return; } catch (error) { next(error); return; } }; } bindHandler(router, controllerMeta, methodMeta, handler) { const before = [ ...(controllerMeta.middleware.before || []), ...(methodMeta.middleware.before || []) ]; const after = [ ...(methodMeta.middleware.after || []), ...(controllerMeta.middleware.after || []) ]; switch (methodMeta.method) { case 'get': router.get(methodMeta.path, ...before, handler, ...after); break; case 'post': router.post(methodMeta.path, ...before, handler, ...after); break; case 'put': router.put(methodMeta.path, ...before, handler, ...after); break; case 'patch': router.patch(methodMeta.path, ...before, handler, ...after); break; case 'delete': router.delete(methodMeta.path, ...before, handler, ...after); break; case 'options': router.options(methodMeta.path, ...before, handler, ...after); break; case 'head': router.head(methodMeta.path, ...before, handler, ...after); break; case 'all': router.all(methodMeta.path, ...before, handler, ...after); break; default: throw new Error(`"${methodMeta.method}" is not a valid method.`); } } } //# sourceMappingURL=tachijs.js.map