Middleware Router
import type { Middleware } from "@/Middleware/Middleware";
import {
MiddlewareVariant,
type MiddlewareHandler,
type MiddlewareUseOn,
} from "@/Middleware/types";
import type { MiddlewareRouterInterface } from "@/Registry/types";
import type { MiddlewareRouterReturn } from "@/Router/types";
import { compile } from "@/utils/compile";
export class MiddlewareRouter implements MiddlewareRouterInterface {
private readonly maps = {
[MiddlewareVariant.inbound]: new Map<string, MiddlewareHandler[]>(),
[MiddlewareVariant.outbound]: new Map<string, MiddlewareHandler[]>(),
};
add(middleware: Middleware): void {
const map = this.maps[middleware.variant];
for (const routeId of this.resolveRouteIds(middleware.useOn)) {
let handlers = map.get(routeId);
if (!handlers) {
handlers = [];
map.set(routeId, handlers);
}
handlers.push(middleware.handler);
}
}
find(routeId: string): MiddlewareRouterReturn {
return {
inbound: compile(this.maps[MiddlewareVariant.inbound].get(routeId) ?? []),
outbound: compile(this.maps[MiddlewareVariant.outbound].get(routeId) ?? []),
};
}
private resolveRouteIds(useOn: MiddlewareUseOn): string[] {
if (useOn === "*") return ["*"];
const targets = Array.isArray(useOn) ? useOn : [useOn];
const routeIds = new Set<string>();
for (const target of targets) {
if (typeof target === "string") {
routeIds.add(target);
} else if ("id" in target) {
routeIds.add(target.id);
} else {
target.routeIds.forEach((id) => routeIds.add(id));
}
}
return Array.from(routeIds);
}
}