@netlify/plugin-nextjs 4.29.5-appdir.0 → 4.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/plugin-nextjs",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.30.0",
|
|
4
4
|
"description": "Run Next.js seamlessly on Netlify",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
],
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@netlify/esbuild": "0.14.39",
|
|
15
|
-
"@netlify/functions": "^1.
|
|
16
|
-
"@netlify/ipx": "^1.3.
|
|
15
|
+
"@netlify/functions": "^1.4.0",
|
|
16
|
+
"@netlify/ipx": "^1.3.3",
|
|
17
17
|
"@vercel/node-bridge": "^2.1.0",
|
|
18
18
|
"chalk": "^4.1.2",
|
|
19
19
|
"destr": "^1.1.1",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@delucis/if-env": "^1.1.2",
|
|
39
|
-
"@netlify/build": "^29.
|
|
39
|
+
"@netlify/build": "^29.4.1",
|
|
40
40
|
"@types/fs-extra": "^9.0.13",
|
|
41
41
|
"@types/jest": "^27.4.1",
|
|
42
42
|
"@types/merge-stream": "^1.1.2",
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { assertEquals } from 'https://deno.land/std@0.167.0/testing/asserts.ts'
|
|
2
|
+
import { beforeEach, describe, it } from 'https://deno.land/std@0.167.0/testing/bdd.ts'
|
|
3
|
+
import { updateModifiedHeaders, FetchEventResult } from './utils.ts'
|
|
4
|
+
|
|
5
|
+
describe('updateModifiedHeaders', () => {
|
|
6
|
+
it("does not modify the headers if 'x-middleware-override-headers' is not found", () => {
|
|
7
|
+
const mockHeaders = new Headers()
|
|
8
|
+
// There shouldn't be a case where x-middleware-override-headers is not set and a header has
|
|
9
|
+
// been modified with 'x-middleware-request' added to it, this is more to confirm the test case
|
|
10
|
+
mockHeaders.set('x-middleware-request-foo', 'bar')
|
|
11
|
+
|
|
12
|
+
const mockResponse = {
|
|
13
|
+
headers: mockHeaders,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const mockRequest = {
|
|
17
|
+
headers: new Headers(),
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
updateModifiedHeaders(mockRequest.headers, mockResponse.headers)
|
|
21
|
+
|
|
22
|
+
assertEquals(mockRequest.headers.get('x-middleware-request-foo'), null)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
describe("when the 'x-middleware-override-headers' headers is present", () => {
|
|
26
|
+
let mockHeaders
|
|
27
|
+
let mockRequest: { headers: Headers }
|
|
28
|
+
let mockResponse: { headers: Headers }
|
|
29
|
+
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
mockHeaders = new Headers()
|
|
32
|
+
mockHeaders.set('foo', 'bar')
|
|
33
|
+
mockHeaders.set('x-middleware-request-hello', 'world')
|
|
34
|
+
mockHeaders.set('x-middleware-request-test', '123')
|
|
35
|
+
mockHeaders.set('x-middleware-override-headers', 'hello,test')
|
|
36
|
+
|
|
37
|
+
mockRequest = {
|
|
38
|
+
headers: new Headers(),
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
mockResponse = {
|
|
42
|
+
headers: mockHeaders,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
updateModifiedHeaders(mockRequest.headers, mockResponse.headers)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it("does not modify or add headers that are missing 'x-middleware-request' in the name", () => {
|
|
49
|
+
assertEquals(mockRequest.headers.get('foo'), null)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it("removes 'x-middleware-request-' from headers", () => {
|
|
53
|
+
assertEquals(mockRequest.headers.get('x-middleware-request-hello'), null)
|
|
54
|
+
assertEquals(mockRequest.headers.get('x-middleware-request-test'), null)
|
|
55
|
+
|
|
56
|
+
assertEquals(mockRequest.headers.get('hello'), 'world')
|
|
57
|
+
assertEquals(mockRequest.headers.get('test'), '123')
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it("removes 'x-middleware-override-headers' after cleaning headers", () => {
|
|
61
|
+
assertEquals(mockRequest.headers.get('x-middleware-override-headers'), null)
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
})
|
|
@@ -31,8 +31,13 @@ export const addMiddlewareHeaders = async (
|
|
|
31
31
|
// We need to await the response to get the origin headers, then we can add the ones from middleware.
|
|
32
32
|
const res = await originResponse
|
|
33
33
|
const response = new Response(res.body, res)
|
|
34
|
+
const originCookies = response.headers.get('set-cookie')
|
|
34
35
|
middlewareResponse.headers.forEach((value, key) => {
|
|
35
36
|
response.headers.set(key, value)
|
|
37
|
+
// Append origin cookies after middleware cookies
|
|
38
|
+
if (key === 'set-cookie' && originCookies) {
|
|
39
|
+
response.headers.append(key, originCookies)
|
|
40
|
+
}
|
|
36
41
|
})
|
|
37
42
|
return response
|
|
38
43
|
}
|
|
@@ -59,6 +64,32 @@ function isMiddlewareResponse(response: Response | MiddlewareResponse): response
|
|
|
59
64
|
return 'dataTransforms' in response
|
|
60
65
|
}
|
|
61
66
|
|
|
67
|
+
// Next 13 supports request header mutations and has the side effect of prepending header values with 'x-middleware-request'
|
|
68
|
+
// as part of invoking NextResponse.next() in the middleware. We need to remove that before sending the response the user
|
|
69
|
+
// as the code that removes it in Next isn't run based on how we handle the middleware
|
|
70
|
+
//
|
|
71
|
+
// Related Next.js code:
|
|
72
|
+
// * https://github.com/vercel/next.js/blob/68d06fe015b28d8f81da52ca107a5f4bd72ab37c/packages/next/server/next-server.ts#L1918-L1928
|
|
73
|
+
// * https://github.com/vercel/next.js/blob/43c9d8940dc42337dd2f7d66aa90e6abf952278e/packages/next/server/web/spec-extension/response.ts#L10-L27
|
|
74
|
+
export function updateModifiedHeaders(requestHeaders: Headers, responseHeaders: Headers) {
|
|
75
|
+
const overriddenHeaders = responseHeaders.get('x-middleware-override-headers')
|
|
76
|
+
|
|
77
|
+
if (!overriddenHeaders) {
|
|
78
|
+
return
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const headersToUpdate = overriddenHeaders.split(',').map((header) => header.trim())
|
|
82
|
+
|
|
83
|
+
for (const header of headersToUpdate) {
|
|
84
|
+
const oldHeaderKey = 'x-middleware-request-' + header
|
|
85
|
+
const headerValue = responseHeaders.get(oldHeaderKey) || ''
|
|
86
|
+
|
|
87
|
+
requestHeaders.set(header, headerValue)
|
|
88
|
+
responseHeaders.delete(oldHeaderKey)
|
|
89
|
+
}
|
|
90
|
+
responseHeaders.delete('x-middleware-override-headers')
|
|
91
|
+
}
|
|
92
|
+
|
|
62
93
|
export const buildResponse = async ({
|
|
63
94
|
result,
|
|
64
95
|
request,
|
|
@@ -68,6 +99,8 @@ export const buildResponse = async ({
|
|
|
68
99
|
request: Request
|
|
69
100
|
context: Context
|
|
70
101
|
}) => {
|
|
102
|
+
updateModifiedHeaders(request.headers, result.response.headers)
|
|
103
|
+
|
|
71
104
|
// They've returned the MiddlewareRequest directly, so we'll call `next()` for them.
|
|
72
105
|
if (isMiddlewareRequest(result.response)) {
|
|
73
106
|
result.response = await result.response.next()
|