import type { Router } from "../router/createRouter.ts"; import { createRouter } from "../router/createRouter.ts"; import { createLocalizedRoute, createLocalizedSegmentRoute, createRoute, createSegmentRoute, } from "../routes/create.ts"; import type { EndRoute } from "../routes/interfaces.ts"; import type { LocaleType, LocalizedPathsRecord, RouteMap, Routes, } from "../types.ts"; import type { SegmentRouterBuilder } from "./createSegmentRouterBuilderCreator.ts"; import { createSegmentRouterBuilderCreator } from "./createSegmentRouterBuilderCreator.ts"; export interface RouterBuilder { add: (path: string, ref: RouteRef, key?: string) => this; addLocalized: ( localizedPaths: LocalizedPathsRecord, ref: RouteRef, key?: string, ) => this; addLocalizedSegment: ( localizedPaths: LocalizedPathsRecord, buildSegment: (builder: SegmentRouterBuilder) => void, ) => this; addSegment: ( path: string, buildSegment: (builder: SegmentRouterBuilder) => void, ) => this; createRouter: () => Router; getRoutes: () => Routes; } export function createRouterBuilder( locales?: Locales[], ): RouterBuilder { const defaultLocale = locales?.[0]; const routes: Routes = []; const routeMap: RouteMap = new Map< string, EndRoute >(); const addToRouteMap = ( key: string, route: EndRoute, ): void => { if (routeMap.has(key)) throw new Error(`"${key}" is already used`); routeMap.set(key, route); }; const createSegmentRouterBuilder = createSegmentRouterBuilderCreator( defaultLocale, addToRouteMap, ); const builder: RouterBuilder = { add: (path: string, ref: RouteRef, key?: string) => { const route = createRoute(path, path, ref); routes.push(route); if (!key) key = path; addToRouteMap(key, route); return builder; }, addLocalized: ( localizedPaths: LocalizedPathsRecord, ref: RouteRef, key?: string, ) => { if (!defaultLocale) throw new Error("Invalid locales"); const route = createLocalizedRoute(localizedPaths, localizedPaths, ref); routes.push(route); const finalKey: string = key || localizedPaths[defaultLocale]; addToRouteMap(finalKey, route); return builder; }, addSegment: ( path: string, buildSegment: (builder: SegmentRouterBuilder) => void, ) => { const route = createSegmentRoute(path, path); buildSegment(createSegmentRouterBuilder(route)); route.freeze(); routes.push(route); return builder; }, addLocalizedSegment: ( localizedPaths: LocalizedPathsRecord, buildSegment: (builder: SegmentRouterBuilder) => void, ) => { if (!defaultLocale) throw new Error("Invalid locales"); const route = createLocalizedSegmentRoute( localizedPaths, localizedPaths, ); buildSegment(createSegmentRouterBuilder(route)); route.freeze(); routes.push(route); return builder; }, getRoutes: () => routes, createRouter: () => createRouter(routes, routeMap), }; return builder; }