-
Notifications
You must be signed in to change notification settings - Fork 86
/
Copy pathrequest.ts
98 lines (83 loc) · 2.59 KB
/
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
import type { NextURL } from 'next/dist/server/web/next-url'
import { NextResponse } from 'next/server'
import type { NextRequest as InternalNextRequest } from 'next/server'
import { MiddlewareResponse } from './response'
export type NextRequest = InternalNextRequest & {
get geo(): {
timezone?: string
}
}
export interface NextOptions {
/**
* Include conditional request headers in the request to the origin.
* If you do this, you must ensure you check the response for a 304 Not Modified response
* and handle it and the missing bode accordingly.
*/
sendConditionalRequest?: boolean
}
// TODO: add Context type
type Context = {
next: (options?: NextOptions) => Promise<Response>
}
/**
* Supercharge your Next middleware with Netlify Edge Functions
*/
export class MiddlewareRequest extends Request {
context: Context
originalRequest: Request
constructor(private nextRequest: NextRequest) {
super(nextRequest)
if (!('Deno' in globalThis)) {
throw new Error('MiddlewareRequest only works in a Netlify Edge Function environment')
}
const requestId = nextRequest.headers.get('x-nf-request-id')
if (!requestId) {
throw new Error('Missing x-nf-request-id header')
}
const requestContext = globalThis.NFRequestContextMap.get(requestId)
if (!requestContext) {
throw new Error(`Could not find request context for request id ${requestId}`)
}
this.context = requestContext.context
this.originalRequest = requestContext.request
}
// Add the headers to the original request, which will be passed to the origin
private applyHeaders() {
this.headers.forEach((value, name) => {
this.originalRequest.headers.set(name, value)
})
}
/**
* Passes the request to the origin, allowing you to access the response
*/
async next(options?: NextOptions): Promise<MiddlewareResponse> {
this.applyHeaders()
const response = await this.context.next(options)
return new MiddlewareResponse(response)
}
rewrite(destination: string | URL | NextURL, init?: ResponseInit): NextResponse {
if (typeof destination === 'string' && destination.startsWith('/')) {
destination = new URL(destination, this.url)
}
this.applyHeaders()
return NextResponse.rewrite(destination, init)
}
get headers() {
return this.nextRequest.headers
}
get cookies() {
return this.nextRequest.cookies
}
get geo() {
return this.nextRequest.geo
}
get ip() {
return this.nextRequest.ip
}
get nextUrl() {
return this.nextRequest.nextUrl
}
get url() {
return this.nextRequest.url.toString()
}
}