/** * 类型化路由常量 * * 关键设计: * - `as const` 让每个值都是字符串字面量类型,可用于 `PageProps<'/literal'>`。 * - 不导出 Client-only 模块(`use-auth-gate` 走独立路径导入),保证 Server bundle 不被污染。 * - 动态查询路由通过 `ROUTE_BUILDERS` 函数生成,避免手拼字符串。 */ import type { PayChannel } from "@/data/dto/payment"; /** 静态路由字面量 */ export const ROUTES = { root: "/", splash: "/splash", chat: "/chat", privateRoom: "/private-room", tip: "/tip", externalEntry: "/external-entry", auth: "/auth", sidebar: "/sidebar", subscription: "/subscription", coinsRules: "/coins-rules", } as const; export type StaticRoute = (typeof ROUTES)[keyof typeof ROUTES]; /** 动态查询路由构造器 */ export const ROUTE_BUILDERS = { subscription: ( type: "vip" | "topup", options: { payChannel?: PayChannel; returnTo?: "chat" } = {}, ): `/subscription?${string}` => { const params = new URLSearchParams({ type }); if (options.payChannel) params.set("payChannel", options.payChannel); if (options.returnTo) params.set("returnTo", options.returnTo); return `${ROUTES.subscription}?${params.toString()}` as const; }, authWithRedirect: (redirectTo: string): `/auth?redirect=${string}` => `${ROUTES.auth}?redirect=${encodeURIComponent(redirectTo)}` as const, } as const; /** 所有静态路由,供 `proxy.ts` matcher 与未来 sitemap 使用 */ export const ALL_STATIC_ROUTES: readonly StaticRoute[] = [ ROUTES.splash, ROUTES.chat, ROUTES.privateRoom, ROUTES.tip, ROUTES.externalEntry, ROUTES.auth, ROUTES.sidebar, ROUTES.coinsRules, ] as const; /** 联合路由类型 */ export type Route = StaticRoute;