-
Notifications
You must be signed in to change notification settings - Fork 86
/
Copy pathnext-request.ts
116 lines (101 loc) · 2.94 KB
/
next-request.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
import type { Context } from '@netlify/edge-functions'
import { addBasePath, normalizeDataUrl, normalizeLocalePath, removeBasePath } from './util.ts'
interface I18NConfig {
defaultLocale: string
localeDetection?: false
locales: string[]
}
export interface RequestData {
geo?: {
city?: string
country?: string
region?: string
latitude?: string
longitude?: string
timezone?: string
}
headers: Record<string, string>
ip?: string
method: string
nextConfig?: {
basePath?: string
i18n?: I18NConfig | null
trailingSlash?: boolean
skipMiddlewareUrlNormalize?: boolean
}
page?: {
name?: string
params?: { [key: string]: string }
}
url: string
body?: ReadableStream<Uint8Array>
detectedLocale?: string
}
const normalizeRequestURL = (
originalURL: string,
nextConfig?: RequestData['nextConfig'],
): { url: string; detectedLocale?: string } => {
const url = new URL(originalURL)
url.pathname = removeBasePath(url.pathname, nextConfig?.basePath)
const didRemoveBasePath = url.toString() !== originalURL
let detectedLocale: string | undefined
if (nextConfig?.i18n) {
const { pathname, detectedLocale: detected } = normalizeLocalePath(
url.pathname,
nextConfig?.i18n?.locales,
)
if (!nextConfig?.skipMiddlewareUrlNormalize) {
url.pathname = pathname || '/'
}
detectedLocale = detected
}
if (!nextConfig?.skipMiddlewareUrlNormalize) {
// We want to run middleware for data requests and expose the URL of the
// corresponding pages, so we have to normalize the URLs before running
// the handler.
url.pathname = normalizeDataUrl(url.pathname)
// Normalizing the trailing slash based on the `trailingSlash` configuration
// property from the Next.js config.
if (nextConfig?.trailingSlash && url.pathname !== '/' && !url.pathname.endsWith('/')) {
url.pathname = `${url.pathname}/`
}
}
if (didRemoveBasePath) {
url.pathname = addBasePath(url.pathname, nextConfig?.basePath)
}
// keep the locale in the url for request.nextUrl object
if (detectedLocale) {
url.pathname = `/${detectedLocale}${url.pathname}`
}
return {
url: url.toString(),
detectedLocale,
}
}
export const buildNextRequest = (
request: Request,
context: Context,
nextConfig?: RequestData['nextConfig'],
): RequestData => {
const { url, method, body, headers } = request
const { country, subdivision, city, latitude, longitude, timezone } = context.geo
const geo: RequestData['geo'] = {
city,
country: country?.code,
region: subdivision?.code,
latitude: latitude?.toString(),
longitude: longitude?.toString(),
timezone,
}
const { detectedLocale, url: normalizedUrl } = normalizeRequestURL(url, nextConfig)
return {
headers: Object.fromEntries(headers.entries()),
geo,
url: normalizedUrl,
method,
ip: context.ip,
body: body ?? undefined,
nextConfig,
detectedLocale,
}
}