file-routing-expressjs
Version:
A dependency-free, flexible, system-based file routing for Express.
195 lines • 7.88 kB
JavaScript
;
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