/
response.ts
112 lines (95 loc) · 2.75 KB
/
response.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
import type { I18NConfig } from '../../config-shared'
import type { CookieSerializeOptions } from 'next/dist/compiled/cookie'
import { NextURL } from '../next-url'
import { toNodeHeaders } from '../utils'
import cookie from 'next/dist/compiled/cookie'
const INTERNALS = Symbol('internal response')
const REDIRECTS = new Set([301, 302, 303, 307, 308])
export class NextResponse extends Response {
[INTERNALS]: {
cookieParser(): { [key: string]: string }
url?: NextURL
}
constructor(body?: BodyInit | null, init: ResponseInit = {}) {
super(body, init)
const cookieParser = () => {
const value = this.headers.get('cookie')
return value ? cookie.parse(value) : {}
}
this[INTERNALS] = {
cookieParser,
url: init.url
? new NextURL(init.url, {
basePath: init.nextConfig?.basePath,
i18n: init.nextConfig?.i18n,
trailingSlash: init.nextConfig?.trailingSlash,
headers: toNodeHeaders(this.headers),
})
: undefined,
}
}
public get cookies() {
return this[INTERNALS].cookieParser()
}
public cookie(
name: string,
value: { [key: string]: any } | string,
opts: CookieSerializeOptions = {}
) {
const val =
typeof value === 'object' ? 'j:' + JSON.stringify(value) : String(value)
if (opts.maxAge) {
opts.expires = new Date(Date.now() + opts.maxAge)
opts.maxAge /= 1000
}
if (opts.path == null) {
opts.path = '/'
}
this.headers.append('Set-Cookie', cookie.serialize(name, String(val), opts))
return this
}
public clearCookie(name: string, opts: CookieSerializeOptions = {}) {
return this.cookie(name, '', { expires: new Date(1), path: '/', ...opts })
}
static json(body: any) {
return new NextResponse(JSON.stringify(body), {
headers: { 'content-type': 'application/json' },
})
}
static redirect(url: string | NextURL, status = 302) {
if (!REDIRECTS.has(status)) {
throw new RangeError(
'Failed to execute "redirect" on "response": Invalid status code'
)
}
return new NextResponse(null, {
headers: { Location: typeof url === 'string' ? url : url.toString() },
status,
})
}
static rewrite(destination: string | NextURL) {
return new NextResponse(null, {
headers: {
'x-middleware-rewrite':
typeof destination === 'string'
? destination
: destination.toString(),
},
})
}
static next() {
return new NextResponse(null, {
headers: {
'x-middleware-next': '1',
},
})
}
}
interface ResponseInit extends globalThis.ResponseInit {
nextConfig?: {
basePath?: string
i18n?: I18NConfig
trailingSlash?: boolean
}
url?: string
}