@netlify/plugin-nextjs 4.29.4 → 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/lib/helpers/files.js
CHANGED
|
@@ -364,7 +364,7 @@ const unpatchNextFiles = async (root) => {
|
|
|
364
364
|
}
|
|
365
365
|
};
|
|
366
366
|
exports.unpatchNextFiles = unpatchNextFiles;
|
|
367
|
-
const movePublicFiles = async ({ appDir, outdir, publish, }) => {
|
|
367
|
+
const movePublicFiles = async ({ appDir, outdir, publish, basePath, }) => {
|
|
368
368
|
// `outdir` is a config property added when using Next.js with Nx. It's typically
|
|
369
369
|
// a relative path outside of the appDir, e.g. '../../dist/apps/<app-name>', and
|
|
370
370
|
// the parent directory of the .next directory.
|
|
@@ -373,7 +373,7 @@ const movePublicFiles = async ({ appDir, outdir, publish, }) => {
|
|
|
373
373
|
// directory from the original app directory.
|
|
374
374
|
const publicDir = outdir ? (0, pathe_1.join)(appDir, outdir, 'public') : (0, pathe_1.join)(appDir, 'public');
|
|
375
375
|
if ((0, fs_extra_1.existsSync)(publicDir)) {
|
|
376
|
-
await (0, fs_extra_1.copy)(publicDir, `${publish}/`);
|
|
376
|
+
await (0, fs_extra_1.copy)(publicDir, `${publish}${basePath}/`);
|
|
377
377
|
}
|
|
378
378
|
};
|
|
379
379
|
exports.movePublicFiles = movePublicFiles;
|
package/lib/index.js
CHANGED
|
@@ -94,7 +94,7 @@ const plugin = {
|
|
|
94
94
|
const apiRoutes = await (0, functions_1.getExtendedApiRouteConfigs)(publish, appDir);
|
|
95
95
|
await (0, functions_1.generateFunctions)(constants, appDir, apiRoutes);
|
|
96
96
|
await (0, functions_1.generatePagesResolver)(constants);
|
|
97
|
-
await (0, files_1.movePublicFiles)({ appDir, outdir, publish });
|
|
97
|
+
await (0, files_1.movePublicFiles)({ appDir, outdir, publish, basePath });
|
|
98
98
|
await (0, files_1.patchNextFiles)(appDir);
|
|
99
99
|
if (!(0, destr_1.default)(process.env.SERVE_STATIC_FILES_FROM_ORIGIN)) {
|
|
100
100
|
await (0, files_1.moveStaticPages)({ target, netlifyConfig, i18n, basePath });
|
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,12 +36,12 @@
|
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@delucis/if-env": "^1.1.2",
|
|
39
|
-
"@netlify/build": "^29.1
|
|
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",
|
|
43
43
|
"@types/node": "^17.0.25",
|
|
44
|
-
"next": "^13.0.
|
|
44
|
+
"next": "^13.0.7",
|
|
45
45
|
"npm-run-all": "^4.1.5",
|
|
46
46
|
"typescript": "^4.6.3"
|
|
47
47
|
},
|
|
@@ -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()
|