UNPKG

@tdsoft/express-routing-wrapper

Version:

Package gives you level of abstraction/wrapping of express router(s), endpoints and middlewares, additionally defining subrouters makes tree structure possible and easily discoverable by root router.

89 lines (74 loc) 3.11 kB
const express = require("express"); const logger = console; // temporary class ApiRouter { constructor(basePath) { this.basePath = basePath; this.expressRouter = express.Router({mergeParams: true}); this.subRouters = []; this.endpoints = {}; this.middlewares = []; } subRouter(apiRouter) { this._passAccessCallback(apiRouter); this.subRouters.push(apiRouter); this.expressRouter.use(apiRouter.basePath, apiRouter.expressRouter); } use(middleware) { this._passAccessCallback(middleware); if (typeof middleware === "function") { this.middlewares.push(middleware && middleware.name); this.expressRouter.use(middleware) } else { this.middlewares.push(middleware); this.expressRouter.use(middleware.expressFn.bind(middleware)) } } _passAccessCallback(routerMiddlewareEndpoint) { const middlewareOrEndpoint = routerMiddlewareEndpoint.def; if (this.accessCallback) if (!middlewareOrEndpoint && !routerMiddlewareEndpoint.accessCallback && routerMiddlewareEndpoint.applyAccessCallback) { routerMiddlewareEndpoint.applyAccessCallback(this.accessCallback); } else if (routerMiddlewareEndpoint.access && !routerMiddlewareEndpoint.access.cb) { routerMiddlewareEndpoint.access.cb = this.accessCallback; } } applyAccessCallback(callback) { this.accessCallback = callback; this.subRouters .filter(router => !router.accessCallback) .forEach(router => router.applyAccessCallback(this.accessCallback)); Object.keys(this.endpoints).forEach(eptKey => { if (!this.endpoints[eptKey].def.access.cb) this.endpoints[eptKey].def.access.cb = this.accessCallback; }); } _addEndpoint(method = "GET", path, apiEndpoint) { this._passAccessCallback(apiEndpoint); const methodLower = method.toLowerCase(); this.endpoints[`${path}/${method}`] = apiEndpoint; apiEndpoint.method = method; return this.expressRouter[methodLower](path, apiEndpoint.expressFn.bind(apiEndpoint)); } get(path, apiEndpoint, expressCb) { if (expressCb) apiEndpoint.cb = expressCb; return this._addEndpoint("GET", path, apiEndpoint) } post(path, apiEndpoint, expressCb) { if (expressCb) apiEndpoint.cb = expressCb; return this._addEndpoint("POST", path, apiEndpoint) } put(path, apiEndpoint, expressCb) { if (expressCb) apiEndpoint.cb = expressCb; return this._addEndpoint("PUT", path, apiEndpoint) } delete(path, apiEndpoint, expressCb) { if (expressCb) apiEndpoint.cb = expressCb; return this._addEndpoint("DELETE", path, apiEndpoint) } param(paramName, paramCb) { // TODO: Additional stuff for docummentaton? How to handle it properly? return this.expressRouter.param(paramName, paramCb); } } module.exports = ApiRouter;