@netlify/plugin-nextjs 5.4.0 → 5.5.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/dist/build/content/prerendered.js +5 -5
- package/dist/build/content/server.js +3 -3
- package/dist/build/content/static.js +5 -5
- package/dist/build/functions/server.js +3 -3
- package/dist/build/verification.js +35 -10
- package/dist/esm-chunks/{package-7DG4KM7X.js → package-C5ZXMRQF.js} +3 -3
- package/dist/index.js +7 -2
- package/dist/run/handlers/server.js +2 -1
- package/dist/run/handlers/tracing.js +1 -1
- package/dist/run/headers.js +10 -12
- package/package.json +1 -1
|
@@ -4,9 +4,6 @@
|
|
|
4
4
|
return createRequire(import.meta.url);
|
|
5
5
|
})();
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
require_out
|
|
9
|
-
} from "../../esm-chunks/chunk-FHR56UHE.js";
|
|
10
7
|
import {
|
|
11
8
|
wrapTracer
|
|
12
9
|
} from "../../esm-chunks/chunk-5QSXBV7L.js";
|
|
@@ -14,6 +11,9 @@ import {
|
|
|
14
11
|
init_esm,
|
|
15
12
|
trace
|
|
16
13
|
} from "../../esm-chunks/chunk-GNGHTHMQ.js";
|
|
14
|
+
import {
|
|
15
|
+
require_out
|
|
16
|
+
} from "../../esm-chunks/chunk-FHR56UHE.js";
|
|
17
17
|
import {
|
|
18
18
|
require_semver
|
|
19
19
|
} from "../../esm-chunks/chunk-EFGWM7RS.js";
|
|
@@ -137,7 +137,7 @@ function pLimit(concurrency) {
|
|
|
137
137
|
// src/build/content/prerendered.ts
|
|
138
138
|
var import_semver = __toESM(require_semver(), 1);
|
|
139
139
|
import { encodeBlobKey } from "../../shared/blobkey.js";
|
|
140
|
-
import {
|
|
140
|
+
import { verifyNetlifyForms } from "../verification.js";
|
|
141
141
|
var tracer = wrapTracer(trace.getTracer("Next runtime"));
|
|
142
142
|
var writeCacheEntry = async (route, value, lastModified, ctx) => {
|
|
143
143
|
const path = join(ctx.blobDir, await encodeBlobKey(route));
|
|
@@ -231,7 +231,7 @@ var copyPrerenderedContent = async (ctx) => {
|
|
|
231
231
|
throw new Error(`Unrecognized content: ${route}`);
|
|
232
232
|
}
|
|
233
233
|
if (value.kind === "PAGE" || value.kind === "APP_PAGE") {
|
|
234
|
-
|
|
234
|
+
verifyNetlifyForms(ctx, value.html);
|
|
235
235
|
}
|
|
236
236
|
await writeCacheEntry(key, value, lastModified, ctx);
|
|
237
237
|
})
|
|
@@ -4,9 +4,6 @@
|
|
|
4
4
|
return createRequire(import.meta.url);
|
|
5
5
|
})();
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
require_out
|
|
9
|
-
} from "../../esm-chunks/chunk-FHR56UHE.js";
|
|
10
7
|
import {
|
|
11
8
|
wrapTracer
|
|
12
9
|
} from "../../esm-chunks/chunk-5QSXBV7L.js";
|
|
@@ -14,6 +11,9 @@ import {
|
|
|
14
11
|
init_esm,
|
|
15
12
|
trace
|
|
16
13
|
} from "../../esm-chunks/chunk-GNGHTHMQ.js";
|
|
14
|
+
import {
|
|
15
|
+
require_out
|
|
16
|
+
} from "../../esm-chunks/chunk-FHR56UHE.js";
|
|
17
17
|
import {
|
|
18
18
|
require_semver
|
|
19
19
|
} from "../../esm-chunks/chunk-EFGWM7RS.js";
|
|
@@ -4,9 +4,6 @@
|
|
|
4
4
|
return createRequire(import.meta.url);
|
|
5
5
|
})();
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
require_out
|
|
9
|
-
} from "../../esm-chunks/chunk-FHR56UHE.js";
|
|
10
7
|
import {
|
|
11
8
|
wrapTracer
|
|
12
9
|
} from "../../esm-chunks/chunk-5QSXBV7L.js";
|
|
@@ -14,6 +11,9 @@ import {
|
|
|
14
11
|
init_esm,
|
|
15
12
|
trace
|
|
16
13
|
} from "../../esm-chunks/chunk-GNGHTHMQ.js";
|
|
14
|
+
import {
|
|
15
|
+
require_out
|
|
16
|
+
} from "../../esm-chunks/chunk-FHR56UHE.js";
|
|
17
17
|
import {
|
|
18
18
|
__toESM
|
|
19
19
|
} from "../../esm-chunks/chunk-OEQOKJGE.js";
|
|
@@ -25,7 +25,7 @@ import { cp, mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
|
25
25
|
import { basename, join } from "node:path";
|
|
26
26
|
var import_fast_glob = __toESM(require_out(), 1);
|
|
27
27
|
import { encodeBlobKey } from "../../shared/blobkey.js";
|
|
28
|
-
import {
|
|
28
|
+
import { verifyNetlifyForms } from "../verification.js";
|
|
29
29
|
var tracer = wrapTracer(trace.getTracer("Next runtime"));
|
|
30
30
|
var copyStaticContent = async (ctx) => {
|
|
31
31
|
return tracer.withActiveSpan("copyStaticContent", async () => {
|
|
@@ -40,7 +40,7 @@ var copyStaticContent = async (ctx) => {
|
|
|
40
40
|
await Promise.all(
|
|
41
41
|
paths.filter((path) => !paths.includes(`${path.slice(0, -5)}.json`)).map(async (path) => {
|
|
42
42
|
const html = await readFile(join(srcDir, path), "utf-8");
|
|
43
|
-
|
|
43
|
+
verifyNetlifyForms(ctx, html);
|
|
44
44
|
await writeFile(join(destDir, await encodeBlobKey(path)), html, "utf-8");
|
|
45
45
|
})
|
|
46
46
|
);
|
|
@@ -4,9 +4,6 @@
|
|
|
4
4
|
return createRequire(import.meta.url);
|
|
5
5
|
})();
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
require_out
|
|
9
|
-
} from "../../esm-chunks/chunk-FHR56UHE.js";
|
|
10
7
|
import {
|
|
11
8
|
wrapTracer
|
|
12
9
|
} from "../../esm-chunks/chunk-5QSXBV7L.js";
|
|
@@ -14,6 +11,9 @@ import {
|
|
|
14
11
|
init_esm,
|
|
15
12
|
trace
|
|
16
13
|
} from "../../esm-chunks/chunk-GNGHTHMQ.js";
|
|
14
|
+
import {
|
|
15
|
+
require_out
|
|
16
|
+
} from "../../esm-chunks/chunk-FHR56UHE.js";
|
|
17
17
|
import {
|
|
18
18
|
__toESM
|
|
19
19
|
} from "../../esm-chunks/chunk-OEQOKJGE.js";
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
return createRequire(import.meta.url);
|
|
5
5
|
})();
|
|
6
6
|
|
|
7
|
+
import {
|
|
8
|
+
require_out
|
|
9
|
+
} from "../esm-chunks/chunk-FHR56UHE.js";
|
|
7
10
|
import {
|
|
8
11
|
require_semver
|
|
9
12
|
} from "../esm-chunks/chunk-EFGWM7RS.js";
|
|
@@ -12,12 +15,14 @@ import {
|
|
|
12
15
|
} from "../esm-chunks/chunk-OEQOKJGE.js";
|
|
13
16
|
|
|
14
17
|
// src/build/verification.ts
|
|
18
|
+
var import_fast_glob = __toESM(require_out(), 1);
|
|
15
19
|
var import_semver = __toESM(require_semver(), 1);
|
|
16
20
|
import { existsSync } from "node:fs";
|
|
21
|
+
import { readFile } from "node:fs/promises";
|
|
17
22
|
import { join } from "node:path";
|
|
18
23
|
import { ApiRouteType, getAPIRoutesConfigs } from "./advanced-api-routes.js";
|
|
19
24
|
var SUPPORTED_NEXT_VERSIONS = ">=13.5.0";
|
|
20
|
-
var
|
|
25
|
+
var verifications = /* @__PURE__ */ new Set();
|
|
21
26
|
function verifyPublishDir(ctx) {
|
|
22
27
|
if (!existsSync(ctx.publishDir)) {
|
|
23
28
|
ctx.failBuild(
|
|
@@ -49,7 +54,7 @@ function verifyPublishDir(ctx) {
|
|
|
49
54
|
}
|
|
50
55
|
if (ctx.nextVersion && !(0, import_semver.satisfies)(ctx.nextVersion, SUPPORTED_NEXT_VERSIONS, { includePrerelease: true })) {
|
|
51
56
|
ctx.failBuild(
|
|
52
|
-
`@netlify/plugin-
|
|
57
|
+
`@netlify/plugin-nextjs@5 requires Next.js version ${SUPPORTED_NEXT_VERSIONS}, but found ${ctx.nextVersion}. Please upgrade your project's Next.js version.`
|
|
53
58
|
);
|
|
54
59
|
}
|
|
55
60
|
}
|
|
@@ -64,30 +69,50 @@ function verifyPublishDir(ctx) {
|
|
|
64
69
|
}
|
|
65
70
|
}
|
|
66
71
|
}
|
|
67
|
-
async function
|
|
72
|
+
async function verifyAdvancedAPIRoutes(ctx) {
|
|
68
73
|
const apiRoutesConfigs = await getAPIRoutesConfigs(ctx);
|
|
69
74
|
const unsupportedAPIRoutes = apiRoutesConfigs.filter((apiRouteConfig) => {
|
|
70
75
|
return apiRouteConfig.config.type === ApiRouteType.BACKGROUND || apiRouteConfig.config.type === ApiRouteType.SCHEDULED;
|
|
71
76
|
});
|
|
72
77
|
if (unsupportedAPIRoutes.length !== 0) {
|
|
73
78
|
ctx.failBuild(
|
|
74
|
-
`@netlify/plugin-
|
|
79
|
+
`@netlify/plugin-nextjs@5 does not support advanced API routes. The following API routes should be migrated to Netlify background or scheduled functions:
|
|
75
80
|
${unsupportedAPIRoutes.map((apiRouteConfig) => ` - ${apiRouteConfig.apiRoute} (type: "${apiRouteConfig.config.type}")`).join("\n")}
|
|
76
81
|
|
|
77
82
|
Refer to https://ntl.fyi/next-scheduled-bg-function-migration as migration example.`
|
|
78
83
|
);
|
|
79
84
|
}
|
|
80
85
|
}
|
|
81
|
-
|
|
82
|
-
|
|
86
|
+
var formDetectionRegex = /<form[^>]*?\s(netlify|data-netlify)[=>\s]/;
|
|
87
|
+
async function verifyNetlifyFormsWorkaround(ctx) {
|
|
88
|
+
const srcDir = ctx.resolveFromSiteDir("public");
|
|
89
|
+
const paths = await (0, import_fast_glob.glob)("**/*.html", {
|
|
90
|
+
cwd: srcDir,
|
|
91
|
+
dot: true
|
|
92
|
+
});
|
|
93
|
+
try {
|
|
94
|
+
for (const path of paths) {
|
|
95
|
+
const html = await readFile(join(srcDir, path), "utf-8");
|
|
96
|
+
if (formDetectionRegex.test(html)) {
|
|
97
|
+
verifications.add("netlifyFormsWorkaround");
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
} catch (error) {
|
|
102
|
+
ctx.failBuild("Failed verifying public files", error);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function verifyNetlifyForms(ctx, html) {
|
|
106
|
+
if (!verifications.has("netlifyForms") && !verifications.has("netlifyFormsWorkaround") && formDetectionRegex.test(html)) {
|
|
83
107
|
console.warn(
|
|
84
|
-
"@netlify/plugin-
|
|
108
|
+
"@netlify/plugin-nextjs@5 requires migration steps to support Netlify Forms. Refer to https://ntl.fyi/next-runtime-forms-migration for migration example."
|
|
85
109
|
);
|
|
86
|
-
|
|
110
|
+
verifications.add("netlifyForms");
|
|
87
111
|
}
|
|
88
112
|
}
|
|
89
113
|
export {
|
|
90
|
-
|
|
91
|
-
|
|
114
|
+
verifyAdvancedAPIRoutes,
|
|
115
|
+
verifyNetlifyForms,
|
|
116
|
+
verifyNetlifyFormsWorkaround,
|
|
92
117
|
verifyPublishDir
|
|
93
118
|
};
|
|
@@ -8,7 +8,7 @@ import "./chunk-OEQOKJGE.js";
|
|
|
8
8
|
|
|
9
9
|
// package.json
|
|
10
10
|
var name = "@netlify/plugin-nextjs";
|
|
11
|
-
var version = "5.
|
|
11
|
+
var version = "5.5.0";
|
|
12
12
|
var description = "Run Next.js seamlessly on Netlify";
|
|
13
13
|
var main = "./dist/index.js";
|
|
14
14
|
var type = "module";
|
|
@@ -58,13 +58,13 @@ var homepage = "https://github.com/netlify/next-runtime#readme";
|
|
|
58
58
|
var devDependencies = {
|
|
59
59
|
"@fastly/http-compute-js": "1.1.4",
|
|
60
60
|
"@netlify/blobs": "^7.3.0",
|
|
61
|
-
"@netlify/build": "^29.50.
|
|
61
|
+
"@netlify/build": "^29.50.2",
|
|
62
62
|
"@netlify/edge-bundler": "^12.1.1",
|
|
63
63
|
"@netlify/edge-functions": "^2.8.1",
|
|
64
64
|
"@netlify/eslint-config-node": "^7.0.1",
|
|
65
65
|
"@netlify/functions": "^2.8.0",
|
|
66
66
|
"@netlify/serverless-functions-api": "^1.18.5",
|
|
67
|
-
"@netlify/zip-it-and-ship-it": "^9.37.
|
|
67
|
+
"@netlify/zip-it-and-ship-it": "^9.37.3",
|
|
68
68
|
"@opentelemetry/api": "^1.8.0",
|
|
69
69
|
"@opentelemetry/exporter-trace-otlp-http": "^0.51.0",
|
|
70
70
|
"@opentelemetry/resources": "^1.24.0",
|
package/dist/index.js
CHANGED
|
@@ -29,7 +29,11 @@ import { createEdgeHandlers } from "./build/functions/edge.js";
|
|
|
29
29
|
import { createServerHandler } from "./build/functions/server.js";
|
|
30
30
|
import { setImageConfig } from "./build/image-cdn.js";
|
|
31
31
|
import { PluginContext } from "./build/plugin-context.js";
|
|
32
|
-
import {
|
|
32
|
+
import {
|
|
33
|
+
verifyAdvancedAPIRoutes,
|
|
34
|
+
verifyNetlifyFormsWorkaround,
|
|
35
|
+
verifyPublishDir
|
|
36
|
+
} from "./build/verification.js";
|
|
33
37
|
var tracer = wrapTracer(trace.getTracer("Next.js runtime"));
|
|
34
38
|
var onPreDev = async (options) => {
|
|
35
39
|
await tracer.withActiveSpan("onPreDev", async () => {
|
|
@@ -56,7 +60,8 @@ var onBuild = async (options) => {
|
|
|
56
60
|
if (ctx.buildConfig.output === "export") {
|
|
57
61
|
return copyStaticExport(ctx);
|
|
58
62
|
}
|
|
59
|
-
await
|
|
63
|
+
await verifyAdvancedAPIRoutes(ctx);
|
|
64
|
+
await verifyNetlifyFormsWorkaround(ctx);
|
|
60
65
|
await Promise.all([
|
|
61
66
|
copyStaticAssets(ctx),
|
|
62
67
|
copyStaticContent(ctx),
|
|
@@ -3161,7 +3161,8 @@ var server_default = async (request, context) => {
|
|
|
3161
3161
|
span.setAttribute("responseCacheKey", requestContext.responseCacheKey);
|
|
3162
3162
|
}
|
|
3163
3163
|
await adjustDateHeader({ headers: response.headers, request, span, tracer, requestContext });
|
|
3164
|
-
|
|
3164
|
+
const useDurableCache = context.flags.get("serverless_functions_nextjs_durable_cache_disable") !== true;
|
|
3165
|
+
setCacheControlHeaders(response.headers, request, requestContext, useDurableCache);
|
|
3165
3166
|
setCacheTagsHeaders(response.headers, requestContext);
|
|
3166
3167
|
setVaryHeaders(response.headers, request, nextConfig);
|
|
3167
3168
|
setCacheStatusHeader(response.headers);
|
|
@@ -67385,7 +67385,7 @@ var import_semantic_conventions = __toESM(require_src(), 1);
|
|
|
67385
67385
|
import { getLogger } from "./request-context.cjs";
|
|
67386
67386
|
var {
|
|
67387
67387
|
default: { version, name }
|
|
67388
|
-
} = await import("../../esm-chunks/package-
|
|
67388
|
+
} = await import("../../esm-chunks/package-C5ZXMRQF.js");
|
|
67389
67389
|
var sdk = new import_sdk_node.NodeSDK({
|
|
67390
67390
|
resource: new import_resources.Resource({
|
|
67391
67391
|
[import_semantic_conventions.SEMRESATTRS_SERVICE_NAME]: name,
|
package/dist/run/headers.js
CHANGED
|
@@ -51,11 +51,6 @@ var omitHeaderValues = (header, values) => {
|
|
|
51
51
|
);
|
|
52
52
|
return filteredValues.join(", ");
|
|
53
53
|
};
|
|
54
|
-
var mapHeaderValues = (header, callback) => {
|
|
55
|
-
const headerValues = getHeaderValueArray(header);
|
|
56
|
-
const mappedValues = headerValues.map(callback);
|
|
57
|
-
return mappedValues.join(", ");
|
|
58
|
-
};
|
|
59
54
|
var setVaryHeaders = (headers, request, { basePath, i18n }) => {
|
|
60
55
|
const netlifyVaryValues = {
|
|
61
56
|
header: ["x-nextjs-data", "x-next-debug-logging"],
|
|
@@ -147,11 +142,12 @@ var adjustDateHeader = async ({
|
|
|
147
142
|
headers.set("x-nextjs-date", headers.get("date") ?? lastModifiedDate.toUTCString());
|
|
148
143
|
headers.set("date", lastModifiedDate.toUTCString());
|
|
149
144
|
};
|
|
150
|
-
var setCacheControlHeaders = (headers, request, requestContext) => {
|
|
145
|
+
var setCacheControlHeaders = (headers, request, requestContext, useDurableCache) => {
|
|
146
|
+
const durableCacheDirective = useDurableCache ? ", durable" : "";
|
|
151
147
|
if (typeof requestContext.routeHandlerRevalidate !== "undefined" && ["GET", "HEAD"].includes(request.method) && !headers.has("cdn-cache-control") && !headers.has("netlify-cdn-cache-control")) {
|
|
152
148
|
const cdnCacheControl = (
|
|
153
149
|
// if we are serving already stale response, instruct edge to not attempt to cache that response
|
|
154
|
-
headers.get("x-nextjs-cache") === "STALE" ? "public, max-age=0, must-revalidate" : `s-maxage=${requestContext.routeHandlerRevalidate === false ? 31536e3 : requestContext.routeHandlerRevalidate}, stale-while-revalidate=31536000`
|
|
150
|
+
headers.get("x-nextjs-cache") === "STALE" ? "public, max-age=0, must-revalidate" : `s-maxage=${requestContext.routeHandlerRevalidate === false ? 31536e3 : requestContext.routeHandlerRevalidate}, stale-while-revalidate=31536000${durableCacheDirective}`
|
|
155
151
|
);
|
|
156
152
|
headers.set("netlify-cdn-cache-control", cdnCacheControl);
|
|
157
153
|
return;
|
|
@@ -164,10 +160,12 @@ var setCacheControlHeaders = (headers, request, requestContext) => {
|
|
|
164
160
|
]);
|
|
165
161
|
const cdnCacheControl = (
|
|
166
162
|
// if we are serving already stale response, instruct edge to not attempt to cache that response
|
|
167
|
-
headers.get("x-nextjs-cache") === "STALE" ? "public, max-age=0, must-revalidate" :
|
|
168
|
-
cacheControl
|
|
169
|
-
|
|
170
|
-
|
|
163
|
+
headers.get("x-nextjs-cache") === "STALE" ? "public, max-age=0, must-revalidate" : [
|
|
164
|
+
...getHeaderValueArray(cacheControl).map(
|
|
165
|
+
(value) => value === "stale-while-revalidate" ? "stale-while-revalidate=31536000" : value
|
|
166
|
+
),
|
|
167
|
+
...useDurableCache ? ["durable"] : []
|
|
168
|
+
].join(", ")
|
|
171
169
|
);
|
|
172
170
|
headers.set("cache-control", browserCacheControl || "public, max-age=0, must-revalidate");
|
|
173
171
|
headers.set("netlify-cdn-cache-control", cdnCacheControl);
|
|
@@ -175,7 +173,7 @@ var setCacheControlHeaders = (headers, request, requestContext) => {
|
|
|
175
173
|
}
|
|
176
174
|
if (cacheControl === null && !headers.has("cdn-cache-control") && !headers.has("netlify-cdn-cache-control") && requestContext.usedFsRead) {
|
|
177
175
|
headers.set("cache-control", "public, max-age=0, must-revalidate");
|
|
178
|
-
headers.set("netlify-cdn-cache-control", `max-age=31536000`);
|
|
176
|
+
headers.set("netlify-cdn-cache-control", `max-age=31536000${durableCacheDirective}`);
|
|
179
177
|
}
|
|
180
178
|
};
|
|
181
179
|
var setCacheTagsHeaders = (headers, requestContext) => {
|