-
Notifications
You must be signed in to change notification settings - Fork 1k
/
Copy pathroutes.ts
126 lines (116 loc) · 3.93 KB
/
routes.ts
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import path from 'path'
import chalk from 'chalk'
import { getPaths, getRouteHookForPage } from '@redwoodjs/project-config'
import { getRouteRegexAndParams } from '@redwoodjs/router/dist/util'
import { getProject } from '@redwoodjs/structure/dist/index.js'
import type { RWRoute } from '@redwoodjs/structure/dist/model/RWRoute'
export interface RouteInformation {
name?: string
path?: string
page?: string
}
/**
* Returns an array of routes which conflict on their defined names
*/
export function getDuplicateRoutes() {
const duplicateRoutes: RouteInformation[] = []
const allRoutes: RWRoute[] = getProject(getPaths().base).router.routes
const uniqueNames = new Set(
allRoutes
.filter((route) => route.name !== undefined)
.map((route) => route.name),
)
uniqueNames.forEach((name) => {
const routesWithName = allRoutes.filter((route) => {
return route.name === name
})
if (routesWithName.length > 1) {
duplicateRoutes.push(
...routesWithName.map((route) => {
return {
name: route.name,
page: route.page_identifier_str,
path: route.path,
}
}),
)
}
})
return duplicateRoutes
}
/**
* Detects any potential duplicate routes and returns a formatted warning message
* @see {@link getDuplicateRoutes} for how duplicate routes are detected
* @return {string} Warning message when duplicate routes found, empty string if not
*/
export function warningForDuplicateRoutes() {
const duplicatedRoutes = getDuplicateRoutes()
let message = ''
if (duplicatedRoutes.length > 0) {
message += chalk.keyword('orange')(
`Warning: ${duplicatedRoutes.length} duplicate routes have been detected, only the route(s) closest to the top of the file will be used.\n`,
)
duplicatedRoutes.forEach((route) => {
message += ` ${chalk.keyword('orange')('->')} Name: "${
route.name
}", Path: "${route.path}", Page: "${route.page}"\n`
})
}
return message.trimEnd()
}
export interface RWRouteManifestItem {
name: string
pathDefinition: string
matchRegexString: string | null
routeHooks: string | null
bundle: string | null
hasParams: boolean
relativeFilePath: string
redirect: { to: string; permanent: boolean } | null
isPrivate: boolean
unauthenticated: string | null
roles: string | string[] | null
pageIdentifier: string | null
// Probably want isNotFound here, so we can attach a separate 404 handler
}
export interface RouteSpec extends RWRouteManifestItem {
id: string
isNotFound: boolean
filePath: string | undefined
isPrivate: boolean
unauthenticated: string | null
relativeFilePath: string
}
export const getProjectRoutes = (): RouteSpec[] => {
const rwProject = getProject(getPaths().base)
const routes = rwProject.getRouter().routes
// @ts-expect-error "Bundle" is not found but is in the Spec type?
return routes.map((route: any) => {
const { matchRegexString, routeParams } = route.isNotFound
? { matchRegexString: null, routeParams: null }
: getRouteRegexAndParams(route.path)
return {
name: route.isNotFound ? 'NotFoundPage' : route.name,
pathDefinition: route.isNotFound ? 'notfound' : route.path,
hasParams: route.hasParameters,
id: route.id,
isNotFound: route.isNotFound,
filePath: route.page?.filePath,
relativeFilePath: route.page?.filePath
? path.relative(getPaths().web.src, route.page?.filePath)
: undefined,
routeHooks: getRouteHookForPage(route.page?.filePath),
renderMode: route.renderMode,
matchRegexString: matchRegexString,
paramNames: routeParams,
// TODO (STREAMING) deal with permanent/temp later
redirect: route.redirect
? { to: route.redirect, permanent: false }
: null,
isPrivate: route.isPrivate,
unauthenticated: route.unauthenticated,
roles: route.roles,
pageIdentifier: route.page_identifier_str,
}
})
}