-
-
Notifications
You must be signed in to change notification settings - Fork 54
Expand file tree
/
Copy pathrouting.ts
More file actions
107 lines (96 loc) · 2.8 KB
/
routing.ts
File metadata and controls
107 lines (96 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import type { EntryContext } from "react-router"
import type { RouteWildcards } from "../context/rdtReducer.js"
import { convertReactRouterPathToUrl, findParentErrorBoundary } from "./sanitize.js"
type EntryRoute = EntryContext["manifest"]["routes"][0]
type Route = Pick<NonNullable<EntryRoute>, "id" | "index" | "path" | "parentId">
declare global {
interface Window {
__reactRouterManifest?: EntryContext["manifest"]
}
}
export function getRouteType(route: Route) {
if (route.id === "root") {
return "ROOT"
}
if (route.index) {
return "ROUTE"
}
if (!route.path) {
// Pathless layout route
return "LAYOUT"
}
if (!window.__reactRouterManifest) {
return "ROUTE"
}
// Find an index route with parentId set to this route
const childIndexRoute = Object.values(window.__reactRouterManifest.routes).find(
(r) => r?.parentId === route.id && r.index
)
return childIndexRoute ? "LAYOUT" : "ROUTE"
}
export function isLayoutRoute(route: Route | undefined) {
if (!route) {
return false
}
return getRouteType(route) === "LAYOUT"
}
export function isLeafRoute(route: Route) {
return getRouteType(route) === "ROUTE"
}
const ROUTE_FILLS = {
GREEN: "fill-green-500 text-white",
BLUE: "fill-blue-500 text-white",
PURPLE: "fill-purple-500 text-white",
} as const
const UNDISCOVERED_ROUTE_FILLS = {
GREEN: "fill-green-500/20 text-white",
BLUE: "fill-blue-500/20 text-white",
PURPLE: "fill-purple-500/20 text-white",
}
export function getRouteColor(route: Route) {
const isDiscovered = !!window.__reactRouterManifest?.routes[route.id]
const FILL = isDiscovered ? ROUTE_FILLS : UNDISCOVERED_ROUTE_FILLS
switch (getRouteType(route)) {
case "ROOT":
return FILL.PURPLE
case "ROUTE":
return FILL.GREEN
case "LAYOUT":
return FILL.BLUE
}
}
export type ExtendedRoute = EntryRoute & {
url: string
file?: string
errorBoundary: { hasErrorBoundary: boolean; errorBoundaryId: string | null }
}
export const constructRoutePath = (route: ExtendedRoute, routeWildcards: RouteWildcards) => {
const hasWildcard = route.url.includes(":")
const wildcards = routeWildcards[route.id]
const path = route.url
.split("/")
.map((p) => {
if (p.startsWith(":")) {
return wildcards?.[p] ? wildcards?.[p] : p
}
return p
})
.join("/")
const pathToOpen = document.location.origin + (path === "/" ? path : `/${path}`)
return { pathToOpen, path, hasWildcard }
}
export const createExtendedRoutes = () => {
if (!window.__reactRouterManifest) {
return []
}
return Object.values(window.__reactRouterManifest.routes)
.map((route) => {
return {
...route,
// biome-ignore lint/style/noNonNullAssertion: <explanation>
url: convertReactRouterPathToUrl(window.__reactRouterManifest!.routes, route),
errorBoundary: findParentErrorBoundary(route),
}
})
.filter((route) => isLeafRoute(route as any))
}