import type { HousekeepingDomainId } from "../migration/types"; import { satisfiesCapability } from "./capability-context"; import type { HousekeepingCapabilityContext, HousekeepingDomainManifest, } from "./contracts"; import type { HousekeepingRouteRuntime } from "./routing/runtime"; export interface HousekeepingNavigationDomain { id: HousekeepingDomainId; href: string; iconId: HousekeepingDomainManifest["iconId"]; label: string; description: string; items: readonly { id: string; href: string; label: string }[]; } export function buildHousekeepingNavigation( runtime: HousekeepingRouteRuntime, context: HousekeepingCapabilityContext, translate: (key: string) => string, ): readonly HousekeepingNavigationDomain[] { return runtime.registry.domains.flatMap((domain) => { if (!satisfiesCapability(context, domain.capability)) return []; const items = domain.routes .filter( (route) => runtime.handlers.has(route.id) && isConcreteNavigationHref(route.href) && satisfiesCapability(context, route.capability), ) .map((route) => ({ id: route.id, href: route.href, label: translate(route.labelKey), })); const landing = items[0]; if (!landing) return []; return [ { id: domain.id, href: landing.href, iconId: domain.iconId, label: translate(domain.labelKey), description: translate(domain.descriptionKey), items, }, ]; }); } function isConcreteNavigationHref(href: string): boolean { return !href.split("/").some((segment) => segment.startsWith(":")); }