file-routing-expressjs
Version:
A dependency-free, flexible, system-based file routing for Express.
1 lines • 10.5 kB
Source Map (JSON)
{"version":3,"sources":["../../node_modules/tsup/assets/esm_shims.js","../../src/models/fileBasedRouting.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport { fileURLToPath } from 'url'\nimport path from 'path'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import { DirsHandlerConfig, FileBasedRoutingOptions, FilesHandlerConfig, MapRoutesParams, RouterEndpoint, RouterEndpoints, RouterRequestHandlersMap } from \"../types\";\nimport { Express, RequestHandler } from \"express\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { extractDirContext, extractEndpointName, extractFileContext } from \"../helpers/extractors\";\nimport { buildRoutePattern, buildRouteWithOneLeadingSlash } from \"../helpers/builders\";\nimport { filenameIsJSorTS, functionIsExceptionHandler, functionIsRequestHandler, methodIsExpressMethod } from \"../helpers/validators\";\n\nclass FileBasedRouting {\n public readonly base: string;\n public readonly endpoints: RouterEndpoints;\n private _app: Express; \n private _currentDepth: number;\n \n constructor({app, target}: FileBasedRoutingOptions){\n this.base = target || path.resolve(__dirname, \"src\", \"routes\");\n this._app = app;\n this.endpoints = [];\n this._currentDepth = 0;\n }\n\n public async createRoutes() {\n this.mapRoutes({\n target: this.base,\n route: \"/\",\n parentConfig: undefined\n });\n }\n\n private async mapRoutes({target, route, parentConfig}: MapRoutesParams) {\n if(!fs.existsSync(target)){\n return;\n }\n \n let parent = parentConfig?.route?.trim() || \"/\";\n\n const targetStat = fs.statSync(target);\n const basename = path.basename(target.replace(this.base, \"\"));\n const { name, isParam } = extractEndpointName(path.parse(basename).name);\n\n route = buildRouteWithOneLeadingSlash(route);\n\n if(targetStat.isDirectory()){\n return this.handleDir({route, parent, name, basename, target, isParam});\n }\n \n if(targetStat.isFile()){\n return this.handleFile({route, name, basename, target, isParam});\n }\n }\n\n private handleDir({route, parent, name, basename, target, isParam}: DirsHandlerConfig) {\n parent = path.join(parent, basename);\n \n const routes = fs.readdirSync(target);\n const { config, middlewares, errorHandler } = extractDirContext(target);\n const endpoint = buildRoutePattern(route, name, isParam, typeof config?.pattern === \"string\" || config.pattern instanceof RegExp ? config.pattern : undefined);\n\n middlewares.forEach(middleware => this._app.use(endpoint, middleware));\n\n this.endpoints.push({\n depth: this._currentDepth++,\n name,\n endpoint,\n method: \"-\", \n middlewares: middlewares.map(item => item.name),\n errorHandler: errorHandler?.name || \"-\"\n });\n\n routes\n .forEach(item => {\n if(item.startsWith(\"_\")) return;\n\n const newTarget = path.join(target, item);\n\n if(!fs.existsSync(newTarget)) return;\n \n this.mapRoutes({\n target: newTarget, \n route: endpoint, \n parentConfig: {\n route: parent,\n }\n });\n });\n \n this._currentDepth--;\n\n if(errorHandler) this._app.use(endpoint, errorHandler);\n }\n\n private async handleFile({route, name, basename, target, isParam}: FilesHandlerConfig) {\n if(!filenameIsJSorTS(basename)) return;\n \n const module = await import(target);\n \n if(!module) return;\n\n const handlers : RouterRequestHandlersMap = {\n get: module._get,\n post: module._post,\n delete: module._delete,\n put: module._put,\n patch: module._patch,\n all: module._all\n }\n\n let { config, middlewares, errorHandler } = extractFileContext(target);\n\n const entries = Object.entries(handlers);\n\n for(const [ method, handler ] of entries) {\n if(!methodIsExpressMethod(method) || !functionIsRequestHandler(handler)) continue;\n\n const endpoint = buildRoutePattern(\n route,\n name,\n isParam,\n (config.pattern instanceof RegExp || typeof config.pattern === \"string\" ? config.pattern : (config.pattern?.[method]) || config.pattern?.all),\n true\n );\n\n const routerEndpoint: RouterEndpoint = {\n depth: this._currentDepth,\n name,\n endpoint,\n method,\n middlewares: [],\n errorHandler: \"-\"\n };\n\n const routeMiddlewares: RequestHandler[] = [];\n \n if(Array.isArray(middlewares)) {\n middlewares.forEach(middleware => {\n routeMiddlewares.push(middleware);\n routerEndpoint.middlewares.push(middleware.name);\n });\n } else if(typeof middlewares === \"object\") {\n const methodMiddlwares = middlewares[method] || middlewares.all;\n \n if(!Array.isArray(methodMiddlwares)) {\n if(methodMiddlwares) {\n routeMiddlewares.push(methodMiddlwares)\n routerEndpoint.middlewares.push(methodMiddlwares.name);\n }\n } else {\n methodMiddlwares?.forEach(middleware => {\n routeMiddlewares.push(middleware)\n routerEndpoint.middlewares.push(middleware.name);\n });\n }\n } else {\n routeMiddlewares.push(middlewares);\n routerEndpoint.middlewares.push(middlewares.name);\n }\n\n this._app[method](endpoint, ...routeMiddlewares, handler);\n\n if(errorHandler) {\n if(typeof errorHandler !== \"function\" ) {\n errorHandler = errorHandler[method] && errorHandler.all;\n }\n\n if(functionIsExceptionHandler(errorHandler)) {\n this._app.use(endpoint, errorHandler);\n routerEndpoint.errorHandler = errorHandler.name;\n }\n }\n\n this.endpoints.push(routerEndpoint);\n }\n }\n}\n\nexport default FileBasedRouting;"],"mappings":"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","names":["path"]}