diff --git a/dist/index.js b/dist/index.js index af3e77a..1fd469f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -50,9 +50,8 @@ export default class Flummpress { yield this.processPipeline(this.middleware, req, res); const route = this.router.getRoute(req.url.pathname, req.method); if (route) { - const [pathPattern, methods] = route; - const handler = methods[(_a = req.method) === null || _a === void 0 ? void 0 : _a.toLowerCase()]; - req.params = ((_b = req.url.pathname.match(new RegExp(pathPattern))) === null || _b === void 0 ? void 0 : _b.groups) || {}; + const handler = route.methods[(_a = req.method) === null || _a === void 0 ? void 0 : _a.toLowerCase()]; + req.params = ((_b = req.url.pathname.match(new RegExp(route.path))) === null || _b === void 0 ? void 0 : _b.groups) || {}; req.post = yield this.readBody(req); yield this.processPipeline(handler, req, res); } diff --git a/dist/router.js b/dist/router.js index 60e4dcf..d34371a 100644 --- a/dist/router.js +++ b/dist/router.js @@ -12,7 +12,8 @@ import path from "node:path"; import Tpl from "./template.js"; export default class Router { constructor() { - this.routes = new Map(); + this.routes = []; + this.routes; this.mimes = new Map(); } importRoutesFromPath(p_1) { @@ -70,7 +71,6 @@ export default class Router { } use(obj) { if (obj instanceof Router) { - this.routes = new Map([...this.routes, ...obj.routes]); this.sortRoutes(); } if (obj instanceof Tpl) { @@ -102,27 +102,47 @@ export default class Router { return this; } registerRoute(path, method, handler) { - var _a; - const route = (_a = this.routes.get(path)) !== null && _a !== void 0 ? _a : { - [method]: handler - }; - this.routes.set(path, route); + const existingRoute = this.routes.find(route => typeof route.path === "string" + ? route.path === path + : route.path instanceof RegExp && path instanceof RegExp && route.path.toString() === path.toString()); + if (existingRoute) { + existingRoute.methods[method] = [ + ...(existingRoute.methods[method] || []), + ...handler + ]; + } + else { + this.routes.push({ + path, + methods: { [method]: handler } + }); + } console.log("route set:", method.toUpperCase(), path); this.sortRoutes(); return this; } getRoute(path, method) { - return [...this.routes.entries()] + return this.routes .find(r => { var _a, _b; - return typeof r[0] === "string" - ? r[0] === path - : ((_b = (_a = r[0]).exec) === null || _b === void 0 ? void 0 : _b.call(_a, path)) - && r[1][method.toLowerCase()]; + return typeof r.path === "string" + ? r.path === path + : ((_b = (_a = r.path).exec) === null || _b === void 0 ? void 0 : _b.call(_a, path)) + && r.methods[method.toLowerCase()]; }); } sortRoutes() { - this.routes = new Map([...this.routes.entries()].sort().reverse()); + this.routes.sort((a, b) => { + const aLength = typeof a.path === "string" ? a.path.length : a.path.source.length; + const bLength = typeof b.path === "string" ? b.path.length : b.path.source.length; + if (typeof a.path === "string" && typeof b.path === "string") + return bLength - aLength; + if (typeof a.path === "string") + return -1; + if (typeof b.path === "string") + return 1; + return bLength - aLength; + }); return this; } readMimes(file = "/etc/mime.types") { diff --git a/src/index.ts b/src/index.ts index 8880d5f..6343e45 100644 --- a/src/index.ts +++ b/src/index.ts @@ -89,10 +89,9 @@ export default class Flummpress { const route = this.router.getRoute(req.url.pathname, req.method!); if(route) { - const [pathPattern, methods] = route; - const handler = methods[req.method?.toLowerCase()!]; + const handler = route.methods[req.method?.toLowerCase()!]; - req.params = req.url.pathname.match(new RegExp(pathPattern))?.groups || {}; + req.params = req.url.pathname.match(new RegExp(route.path))?.groups || {}; req.post = await this.readBody(req); await this.processPipeline(handler, req, res); } diff --git a/src/router.ts b/src/router.ts index 08028fa..407238a 100644 --- a/src/router.ts +++ b/src/router.ts @@ -5,12 +5,11 @@ import Tpl from "./template.js"; import { Request, Response, Handler } from "./types.js"; export default class Router { - private routes: Map; + private routes: Array<{ path: string | RegExp; methods: { [method: string]: Handler[] } }> = []; private tpl?: Tpl; private mimes: Map; constructor() { - this.routes = new Map(); this.mimes = new Map(); } @@ -96,7 +95,7 @@ export default class Router { */ use(obj: Router | Tpl): void { if(obj instanceof Router) { - this.routes = new Map([...this.routes, ...obj.routes]); + this.routes = { ...this.routes, ...obj.routes }; this.sortRoutes(); } if(obj instanceof Tpl) { @@ -181,10 +180,24 @@ export default class Router { method: string, handler: Handler[] ): this { - const route: { [key: string]: Handler[] } = this.routes.get(path) ?? { - [ method ]: handler - }; - this.routes.set(path, route); + const route = this.routes.find(route => + typeof route.path === "string" + ? route.path === path + : route.path instanceof RegExp && path instanceof RegExp && route.path.toString() === path.toString() + ); + + if(route) { + route.methods[method] = [ + ...(route.methods[method] || []), + ...handler + ]; + } + else { + this.routes.push({ + path, + methods: { [method]: handler } + }); + } console.log("route set:", method.toUpperCase(), path); this.sortRoutes(); @@ -198,11 +211,11 @@ export default class Router { * @returns The matching route or undefined. */ getRoute(path: string, method: string): any { - return [...this.routes.entries()] - .find(r => typeof r[0] === "string" - ? r[0] === path - : r[0].exec?.(path) - && r[1][method.toLowerCase()] + return this.routes + .find(r => typeof r.path === "string" + ? r.path === path + : r.path.exec?.(path) + && r.methods[method.toLowerCase()] ); } @@ -211,7 +224,18 @@ export default class Router { * @returns The Router instance for chaining. */ private sortRoutes(): this { - this.routes = new Map([...this.routes.entries()].sort().reverse()); + this.routes.sort((a, b) => { + const aLength = typeof a.path === "string" ? a.path.length : a.path.source.length; + const bLength = typeof b.path === "string" ? b.path.length : b.path.source.length; + + if(typeof a.path === "string" && typeof b.path === "string") + return bLength - aLength; + if(typeof a.path === "string") + return -1; + if(typeof b.path === "string") + return 1; + return bLength - aLength; + }); return this; }