@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.29.5-appdir.0",
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.3.0",
16
- "@netlify/ipx": "^1.3.2",
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.3.0",
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()