Files
EpicNext-Cms/src/features/housekeeping/foundation/routing/runtime.ts
T

48 lines
1.3 KiB
TypeScript

import type { HousekeepingRegistry } from "../registry";
import { matchHousekeepingRoute } from "./match-route";
import type {
HousekeepingRouteHandler,
HousekeepingRouteMatch,
} from "./route-handler";
export interface HousekeepingRouteRuntime {
registry: HousekeepingRegistry;
handlers: ReadonlyMap<string, HousekeepingRouteHandler>;
match(pathname: string): HousekeepingRouteMatch | null;
}
export function createHousekeepingRouteRuntime(
registry: HousekeepingRegistry,
handlers: readonly HousekeepingRouteHandler[],
): HousekeepingRouteRuntime {
const declaredRouteIds = new Set(
registry.domains.flatMap((domain) =>
domain.routes.map((route) => route.id),
),
);
const handlerMap = new Map<string, HousekeepingRouteHandler>();
for (const handler of handlers) {
if (handlerMap.has(handler.routeId)) {
throw new Error(`duplicate route handler: ${handler.routeId}`);
}
if (!declaredRouteIds.has(handler.routeId)) {
throw new Error(`handler without route: ${handler.routeId}`);
}
handlerMap.set(handler.routeId, handler);
}
for (const routeId of declaredRouteIds) {
if (!handlerMap.has(routeId)) {
throw new Error(`missing route handler: ${routeId}`);
}
}
return Object.freeze({
registry,
handlers: handlerMap,
match: (pathname: string) => matchHousekeepingRoute(registry, pathname),
});
}