UNPKG

@d3vtool/ex-frame

Version:

This library enhances Express.js by providing a more organized structure for web API projects, along with improved control and error handling capabilities.

147 lines (146 loc) 8.35 kB
"use strict"; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _ExFrame_instances, _ExFrame_expressApp, _ExFrame_errorMap, _ExFrame_injectorMap, _ExFrame_getPossibleMatchingRoutes, _ExFrame_globalErrorHandler; Object.defineProperty(exports, "__esModule", { value: true }); exports.ExFrame = void 0; const express_1 = require("express"); const ex_middleware_1 = require("./ex-middleware"); const ex_helpers_1 = require("./ex-helpers"); class ExFrame { constructor(expressApp) { _ExFrame_instances.add(this); _ExFrame_expressApp.set(this, void 0); _ExFrame_errorMap.set(this, {}); _ExFrame_injectorMap.set(this, { transient: {}, scoped: {}, singleton: {} }); __classPrivateFieldSet(this, _ExFrame_expressApp, expressApp, "f"); } addTransient(service) { const serviceName = service.name.toLowerCase(); if (__classPrivateFieldGet(this, _ExFrame_injectorMap, "f").scoped[serviceName] || __classPrivateFieldGet(this, _ExFrame_injectorMap, "f").singleton[serviceName]) { throw new Error(`'${serviceName} is already registered service.'`); } __classPrivateFieldGet(this, _ExFrame_injectorMap, "f").transient[serviceName] = service; } addScoped(service) { const serviceName = service.name.toLowerCase(); if (__classPrivateFieldGet(this, _ExFrame_injectorMap, "f").transient[serviceName] || __classPrivateFieldGet(this, _ExFrame_injectorMap, "f").singleton[serviceName]) { throw new Error(`'${serviceName} is already registered service.'`); } __classPrivateFieldGet(this, _ExFrame_injectorMap, "f").scoped[serviceName] = service; } addSingleton(service) { const serviceName = service.name.toLowerCase(); if (__classPrivateFieldGet(this, _ExFrame_injectorMap, "f").scoped[serviceName] || __classPrivateFieldGet(this, _ExFrame_injectorMap, "f").transient[serviceName]) { throw new Error(`'${serviceName} is already registered service.'`); } __classPrivateFieldGet(this, _ExFrame_injectorMap, "f").singleton[serviceName] = new service(); } controller(controller) { const parentRoute = controller?.parentRoute ?? "/"; const parentErrorHandler = controller?.errorHandler; const parentMiddlewares = controller.handlers ?? []; const parentHttpMethod = controller?.parentHttpMethod?.toLowerCase(); if (parentErrorHandler && parentRoute !== "/") { __classPrivateFieldGet(this, _ExFrame_errorMap, "f")[parentRoute] = parentErrorHandler; } const parentRouter = (0, express_1.Router)(); for (const staticMethod of (0, ex_helpers_1.getStaticMethods)(controller)) { const controllerMethod = controller[staticMethod]; const route = controllerMethod?.route; const httpMethod = controllerMethod?.httpMethod?.toLowerCase(); const controllerMiddleware = controllerMethod?.handlers ?? []; const errorHandler = controllerMethod?.errorHandler; const transientServiceName = controllerMethod?.transientServiceName; const scopedServiceName = controllerMethod?.scopedServiceName; const singletonServiceName = controllerMethod?.singletonServiceName; if (!controllerMethod || !route || !httpMethod) continue; if (errorHandler) { const fullRoute = `${parentRoute}${route === "/" ? "" : route}`.trim(); __classPrivateFieldGet(this, _ExFrame_errorMap, "f")[fullRoute] = errorHandler; } parentRouter[httpMethod](route, controllerMiddleware, (0, ex_middleware_1.asyncHandler)(async (req, res, next) => { let service; switch (true) { case Boolean(__classPrivateFieldGet(this, _ExFrame_injectorMap, "f").transient[transientServiceName]): service = new (__classPrivateFieldGet(this, _ExFrame_injectorMap, "f").transient[transientServiceName])(); break; case Boolean(__classPrivateFieldGet(this, _ExFrame_injectorMap, "f").scoped[scopedServiceName]): if (!req["__scope__"][scopedServiceName]) { service = new (__classPrivateFieldGet(this, _ExFrame_injectorMap, "f").scoped[scopedServiceName])(); req["__scope__"][scopedServiceName] = service; } break; case Boolean(__classPrivateFieldGet(this, _ExFrame_injectorMap, "f").singleton[singletonServiceName]): service = __classPrivateFieldGet(this, _ExFrame_injectorMap, "f").singleton[singletonServiceName]; break; default: throw new Error("Unknown service call."); } if (service) { await controllerMethod(service, req, res, next); } else { await controllerMethod(req, res, next); } })); } if (parentHttpMethod) { __classPrivateFieldGet(this, _ExFrame_expressApp, "f")[parentHttpMethod](parentRoute, parentMiddlewares, parentRouter); return; } __classPrivateFieldGet(this, _ExFrame_expressApp, "f").use(parentRoute, parentMiddlewares, parentRouter); } listen(...args) { __classPrivateFieldGet(this, _ExFrame_expressApp, "f").use(__classPrivateFieldGet(this, _ExFrame_instances, "m", _ExFrame_globalErrorHandler).bind(this)); return __classPrivateFieldGet(this, _ExFrame_expressApp, "f").listen(...args); } } exports.ExFrame = ExFrame; _ExFrame_expressApp = new WeakMap(), _ExFrame_errorMap = new WeakMap(), _ExFrame_injectorMap = new WeakMap(), _ExFrame_instances = new WeakSet(), _ExFrame_getPossibleMatchingRoutes = function _ExFrame_getPossibleMatchingRoutes(route, map) { const routeSeg = route.split("/"); const viableERoutes = []; for (const errorRoute in map) { const eRouteSeg = errorRoute.split("/"); if (errorRoute.includes("/:") && eRouteSeg.length === routeSeg.length) { viableERoutes.unshift(errorRoute); } else if (route.includes(errorRoute)) { viableERoutes.push(errorRoute); } } return viableERoutes; }, _ExFrame_globalErrorHandler = function _ExFrame_globalErrorHandler(error, req, res, next) { const originalUrl = req.originalUrl; let errorHandler = __classPrivateFieldGet(this, _ExFrame_errorMap, "f")[`${originalUrl}/`]; if (errorHandler) { return errorHandler(error, req, res, next); } const viableERoutes = __classPrivateFieldGet(this, _ExFrame_instances, "m", _ExFrame_getPossibleMatchingRoutes).call(this, originalUrl, __classPrivateFieldGet(this, _ExFrame_errorMap, "f")); for (let vRoute of viableERoutes) { errorHandler = __classPrivateFieldGet(this, _ExFrame_errorMap, "f")[vRoute]; if (errorHandler) { return errorHandler(error, req, res, next); } } next(error); };