import { Matched, Matcher, isMatched, } from './matchers' import { MatchResult, MatchResultAny, } from './matchers/MatchResult' interface HandlerParams { match: Matched data: D } // eslint-disable-next-line @typescript-eslint/no-explicit-any export type MatchedHandler, D = any> = Handler, D> export type Handler< MR extends MatchResultAny, D, // eslint-disable-next-line @typescript-eslint/no-explicit-any > = (params: HandlerParams) => any export interface Route { matcher: Matcher handler: Handler } export class Router { private routes: Route[] = [] constructor(private defaultHandler?: Handler, D>) { this.addRoute = this.addRoute.bind(this) this.exec = this.exec.bind(this) } addRoute(route: Route): void { this.routes.push(route as unknown as Route) } // eslint-disable-next-line @typescript-eslint/no-explicit-any exec(params: D): ReturnType> { for (const route of this.routes) { const match = route.matcher.match(params) if (isMatched(match)) { return route.handler({ match, data: params, }) } } return this.defaultHandler?.({ match: { matched: true, result: undefined }, data: params, }) } }