-
Notifications
You must be signed in to change notification settings - Fork 87
/
util.ts
125 lines (109 loc) · 3.59 KB
/
util.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
/**
* Normalize a data URL into a route path.
* @see https://github.com/vercel/next.js/blob/25e0988e7c9033cb1503cbe0c62ba5de2e97849c/packages/next/src/shared/lib/router/utils/get-next-pathname-info.ts#L69-L76
*/
export function normalizeDataUrl(urlPath: string) {
if (urlPath.startsWith('/_next/data/') && urlPath.includes('.json')) {
const paths = urlPath
.replace(/^\/_next\/data\//, '')
.replace(/\.json/, '')
.split('/')
urlPath = paths[1] !== 'index' ? `/${paths.slice(1).join('/')}` : '/'
}
return urlPath
}
export const removeBasePath = (path: string, basePath?: string) => {
if (basePath && path.startsWith(basePath)) {
return path.replace(basePath, '')
}
return path
}
export const addBasePath = (path: string, basePath?: string) => {
if (basePath && !path.startsWith(basePath)) {
return `${basePath}${path}`
}
return path
}
// add locale prefix if not present, allowing for locale fallbacks
export const addLocale = (path: string, locale?: string) => {
if (
locale &&
path.toLowerCase() !== `/${locale.toLowerCase()}` &&
!path.toLowerCase().startsWith(`/${locale.toLowerCase()}/`) &&
!path.startsWith(`/api/`) &&
!path.startsWith(`/_next/`)
) {
return `/${locale}${path}`
}
return path
}
// https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/i18n/normalize-locale-path.ts
export interface PathLocale {
detectedLocale?: string
pathname: string
}
/**
* For a pathname that may include a locale from a list of locales, it
* removes the locale from the pathname returning it alongside with the
* detected locale.
*
* @param pathname A pathname that may include a locale.
* @param locales A list of locales.
* @returns The detected locale and pathname without locale
*/
export function normalizeLocalePath(pathname: string, locales?: string[]): PathLocale {
let detectedLocale: string | undefined
// first item will be empty string from splitting at first char
const pathnameParts = pathname.split('/')
;(locales || []).some((locale) => {
if (pathnameParts[1] && pathnameParts[1].toLowerCase() === locale.toLowerCase()) {
detectedLocale = locale
pathnameParts.splice(1, 1)
pathname = pathnameParts.join('/')
return true
}
return false
})
return {
pathname,
detectedLocale,
}
}
/**
* This is how Next handles rewritten URLs.
*/
export function relativizeURL(url: string | string, base: string | URL) {
const baseURL = typeof base === 'string' ? new URL(base) : base
const relative = new URL(url, base)
const origin = `${baseURL.protocol}//${baseURL.host}`
return `${relative.protocol}//${relative.host}` === origin
? relative.toString().replace(origin, '')
: relative.toString()
}
export const normalizeIndex = (path: string) => (path === '/' ? '/index' : path)
export const normalizeTrailingSlash = (path: string, trailingSlash?: boolean) =>
trailingSlash ? addTrailingSlash(path) : stripTrailingSlash(path)
export const stripTrailingSlash = (path: string) =>
path !== '/' && path.endsWith('/') ? path.slice(0, -1) : path
export const addTrailingSlash = (path: string) => (path.endsWith('/') ? path : `${path}/`)
/**
* Modify a data url to point to a new page route.
*/
export function rewriteDataPath({
dataUrl,
newRoute,
basePath,
}: {
dataUrl: string
newRoute: string
basePath?: string
}) {
const normalizedDataUrl = normalizeDataUrl(removeBasePath(dataUrl, basePath))
return addBasePath(
dataUrl.replace(
normalizeIndex(normalizedDataUrl),
stripTrailingSlash(normalizeIndex(newRoute)),
),
basePath,
)
}