UNPKG

file-routing-expressjs

Version:

A dependency-free, flexible, system-based file routing for Express.

195 lines 7.88 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; var fileBasedRouting_exports = {}; __export(fileBasedRouting_exports, { default: () => fileBasedRouting_default }); module.exports = __toCommonJS(fileBasedRouting_exports); var import_fs = __toESM(require("fs")); var import_path = __toESM(require("path")); var import_extractors = require("../helpers/extractors"); var import_builders = require("../helpers/builders"); var import_validators = require("../helpers/validators"); class FileBasedRouting { constructor({ app, target }) { this.base = target || import_path.default.resolve(__dirname, "src", "routes"); this._app = app; this.endpoints = []; this._currentDepth = 0; } createRoutes() { return __async(this, null, function* () { this.mapRoutes({ target: this.base, route: "/", parentConfig: void 0 }); }); } mapRoutes(_0) { return __async(this, arguments, function* ({ target, route, parentConfig }) { var _a; if (!import_fs.default.existsSync(target)) { return; } let parent = ((_a = parentConfig == null ? void 0 : parentConfig.route) == null ? void 0 : _a.trim()) || "/"; const targetStat = import_fs.default.statSync(target); const basename = import_path.default.basename(target.replace(this.base, "")); const { name, isParam } = (0, import_extractors.extractEndpointName)(import_path.default.parse(basename).name); route = (0, import_builders.buildRouteWithOneLeadingSlash)(route); if (targetStat.isDirectory()) { return this.handleDir({ route, parent, name, basename, target, isParam }); } if (targetStat.isFile()) { return this.handleFile({ route, name, basename, target, isParam }); } }); } handleDir({ route, parent, name, basename, target, isParam }) { parent = import_path.default.join(parent, basename); const routes = import_fs.default.readdirSync(target); const { config, middlewares, errorHandler } = (0, import_extractors.extractDirContext)(target); const endpoint = (0, import_builders.buildRoutePattern)(route, name, isParam, typeof (config == null ? void 0 : config.pattern) === "string" || config.pattern instanceof RegExp ? config.pattern : void 0); middlewares.forEach((middleware) => this._app.use(endpoint, middleware)); this.endpoints.push({ depth: this._currentDepth++, name, endpoint, method: "-", middlewares: middlewares.map((item) => item.name), errorHandler: (errorHandler == null ? void 0 : errorHandler.name) || "-" }); routes.forEach((item) => { if (item.startsWith("_")) return; const newTarget = import_path.default.join(target, item); if (!import_fs.default.existsSync(newTarget)) return; this.mapRoutes({ target: newTarget, route: endpoint, parentConfig: { route: parent } }); }); this._currentDepth--; if (errorHandler) this._app.use(endpoint, errorHandler); } handleFile(_0) { return __async(this, arguments, function* ({ route, name, basename, target, isParam }) { var _a, _b; if (!(0, import_validators.filenameIsJSorTS)(basename)) return; const module2 = yield import(target); if (!module2) return; const handlers = { get: module2._get, post: module2._post, delete: module2._delete, put: module2._put, patch: module2._patch, all: module2._all }; let { config, middlewares, errorHandler } = (0, import_extractors.extractFileContext)(target); const entries = Object.entries(handlers); for (const [method, handler] of entries) { if (!(0, import_validators.methodIsExpressMethod)(method) || !(0, import_validators.functionIsRequestHandler)(handler)) continue; const endpoint = (0, import_builders.buildRoutePattern)( route, name, isParam, config.pattern instanceof RegExp || typeof config.pattern === "string" ? config.pattern : ((_a = config.pattern) == null ? void 0 : _a[method]) || ((_b = config.pattern) == null ? void 0 : _b.all), true ); const routerEndpoint = { depth: this._currentDepth, name, endpoint, method, middlewares: [], errorHandler: "-" }; const routeMiddlewares = []; if (Array.isArray(middlewares)) { middlewares.forEach((middleware) => { routeMiddlewares.push(middleware); routerEndpoint.middlewares.push(middleware.name); }); } else if (typeof middlewares === "object") { const methodMiddlwares = middlewares[method] || middlewares.all; if (!Array.isArray(methodMiddlwares)) { if (methodMiddlwares) { routeMiddlewares.push(methodMiddlwares); routerEndpoint.middlewares.push(methodMiddlwares.name); } } else { methodMiddlwares == null ? void 0 : methodMiddlwares.forEach((middleware) => { routeMiddlewares.push(middleware); routerEndpoint.middlewares.push(middleware.name); }); } } else { routeMiddlewares.push(middlewares); routerEndpoint.middlewares.push(middlewares.name); } this._app[method](endpoint, ...routeMiddlewares, handler); if (errorHandler) { if (typeof errorHandler !== "function") { errorHandler = errorHandler[method] && errorHandler.all; } if ((0, import_validators.functionIsExceptionHandler)(errorHandler)) { this._app.use(endpoint, errorHandler); routerEndpoint.errorHandler = errorHandler.name; } } this.endpoints.push(routerEndpoint); } }); } } var fileBasedRouting_default = FileBasedRouting; //# sourceMappingURL=fileBasedRouting.js.map