@netlify/plugin-nextjs 5.5.1 → 5.6.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/server.js +1 -1
- package/dist/build/functions/edge.js +1 -4
- package/dist/build/functions/server.js +8 -9
- package/dist/build/plugin-context.js +3 -0
- package/dist/build/verification.js +2 -3
- package/dist/esm-chunks/{package-SHOGGUO3.js → package-OHGYB5OD.js} +3 -3
- package/dist/run/handlers/tracing.js +1 -1
- package/edge-runtime/lib/next-request.ts +28 -0
- package/edge-runtime/lib/util.ts +14 -0
- package/edge-runtime/middleware.ts +7 -3
- package/package.json +1 -1
|
@@ -169,7 +169,7 @@ var copyNextDependencies = async (ctx) => {
|
|
|
169
169
|
await tracer.withActiveSpan("copyNextDependencies", async () => {
|
|
170
170
|
const entries = await readdir(ctx.standaloneDir);
|
|
171
171
|
const promises = entries.map(async (entry) => {
|
|
172
|
-
if (entry ===
|
|
172
|
+
if (entry === ctx.nextDistDir) {
|
|
173
173
|
return;
|
|
174
174
|
}
|
|
175
175
|
const src = join(ctx.standaloneDir, entry);
|
|
@@ -431,10 +431,7 @@ var writeHandlerFile = async (ctx, { matchers, name }) => {
|
|
|
431
431
|
const handlerDirectory = join(ctx.edgeFunctionsDir, handlerName);
|
|
432
432
|
const handlerRuntimeDirectory = join(handlerDirectory, "edge-runtime");
|
|
433
433
|
await copyRuntime(ctx, handlerDirectory);
|
|
434
|
-
await writeFile(
|
|
435
|
-
join(handlerRuntimeDirectory, "matchers.json"),
|
|
436
|
-
JSON.stringify(augmentMatchers(matchers, ctx))
|
|
437
|
-
);
|
|
434
|
+
await writeFile(join(handlerRuntimeDirectory, "matchers.json"), JSON.stringify(matchers));
|
|
438
435
|
const minimalNextConfig = {
|
|
439
436
|
basePath: nextConfig.basePath,
|
|
440
437
|
i18n: nextConfig.i18n,
|
|
@@ -61,10 +61,16 @@ var copyHandlerDependencies = async (ctx) => {
|
|
|
61
61
|
)
|
|
62
62
|
);
|
|
63
63
|
}
|
|
64
|
+
promises.push(
|
|
65
|
+
writeFile(
|
|
66
|
+
join(ctx.serverHandlerRuntimeModulesDir, "package.json"),
|
|
67
|
+
JSON.stringify({ type: "module" })
|
|
68
|
+
)
|
|
69
|
+
);
|
|
64
70
|
const fileList = await (0, import_fast_glob.glob)("dist/**/*", { cwd: ctx.pluginDir });
|
|
65
71
|
for (const filePath of fileList) {
|
|
66
72
|
promises.push(
|
|
67
|
-
cp(join(ctx.pluginDir, filePath), join(ctx.
|
|
73
|
+
cp(join(ctx.pluginDir, filePath), join(ctx.serverHandlerRuntimeModulesDir, filePath), {
|
|
68
74
|
recursive: true,
|
|
69
75
|
force: true
|
|
70
76
|
})
|
|
@@ -90,12 +96,6 @@ var writeHandlerManifest = async (ctx) => {
|
|
|
90
96
|
"utf-8"
|
|
91
97
|
);
|
|
92
98
|
};
|
|
93
|
-
var writePackageMetadata = async (ctx) => {
|
|
94
|
-
await writeFile(
|
|
95
|
-
join(ctx.serverHandlerRootDir, "package.json"),
|
|
96
|
-
JSON.stringify({ type: "module" })
|
|
97
|
-
);
|
|
98
|
-
};
|
|
99
99
|
var applyTemplateVariables = (template, variables) => {
|
|
100
100
|
return Object.entries(variables).reduce((acc, [key, value]) => {
|
|
101
101
|
return acc.replaceAll(key, value);
|
|
@@ -126,12 +126,11 @@ var clearStaleServerHandlers = async (ctx) => {
|
|
|
126
126
|
};
|
|
127
127
|
var createServerHandler = async (ctx) => {
|
|
128
128
|
await tracer.withActiveSpan("createServerHandler", async () => {
|
|
129
|
-
await mkdir(join(ctx.
|
|
129
|
+
await mkdir(join(ctx.serverHandlerRuntimeModulesDir), { recursive: true });
|
|
130
130
|
await copyNextServerCode(ctx);
|
|
131
131
|
await copyNextDependencies(ctx);
|
|
132
132
|
await copyHandlerDependencies(ctx);
|
|
133
133
|
await writeHandlerManifest(ctx);
|
|
134
|
-
await writePackageMetadata(ctx);
|
|
135
134
|
await writeHandlerFile(ctx);
|
|
136
135
|
await verifyHandlerDirStructure(ctx);
|
|
137
136
|
});
|
|
@@ -133,6 +133,9 @@ var PluginContext = class {
|
|
|
133
133
|
}
|
|
134
134
|
return join(this.serverHandlerRootDir, this.distDirParent);
|
|
135
135
|
}
|
|
136
|
+
get serverHandlerRuntimeModulesDir() {
|
|
137
|
+
return join(this.serverHandlerDir, ".netlify");
|
|
138
|
+
}
|
|
136
139
|
get nextServerHandler() {
|
|
137
140
|
if (this.relativeAppDir.length !== 0) {
|
|
138
141
|
return join(this.lambdaWorkingDirectory, ".netlify/dist/run/handlers/server.js");
|
|
@@ -103,11 +103,10 @@ async function verifyNetlifyFormsWorkaround(ctx) {
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
function verifyNetlifyForms(ctx, html) {
|
|
106
|
-
if (
|
|
107
|
-
|
|
106
|
+
if (process.env.NETLIFY_NEXT_VERIFY_FORMS !== "0" && process.env.NETLIFY_NEXT_VERIFY_FORMS?.toUpperCase() !== "FALSE" && !verifications.has("netlifyFormsWorkaround") && formDetectionRegex.test(html)) {
|
|
107
|
+
ctx.failBuild(
|
|
108
108
|
"@netlify/plugin-nextjs@5 requires migration steps to support Netlify Forms. Refer to https://ntl.fyi/next-runtime-forms-migration for migration example."
|
|
109
109
|
);
|
|
110
|
-
verifications.add("netlifyForms");
|
|
111
110
|
}
|
|
112
111
|
}
|
|
113
112
|
export {
|
|
@@ -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.6.0";
|
|
12
12
|
var description = "Run Next.js seamlessly on Netlify";
|
|
13
13
|
var main = "./dist/index.js";
|
|
14
14
|
var type = "module";
|
|
@@ -60,10 +60,10 @@ var devDependencies = {
|
|
|
60
60
|
"@netlify/blobs": "^7.3.0",
|
|
61
61
|
"@netlify/build": "^29.50.2",
|
|
62
62
|
"@netlify/edge-bundler": "^12.1.1",
|
|
63
|
-
"@netlify/edge-functions": "^2.
|
|
63
|
+
"@netlify/edge-functions": "^2.10.0",
|
|
64
64
|
"@netlify/eslint-config-node": "^7.0.1",
|
|
65
65
|
"@netlify/functions": "^2.8.1",
|
|
66
|
-
"@netlify/serverless-functions-api": "^1.
|
|
66
|
+
"@netlify/serverless-functions-api": "^1.22.0",
|
|
67
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",
|
|
@@ -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-OHGYB5OD.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,
|
|
@@ -2,6 +2,7 @@ import type { Context } from '@netlify/edge-functions'
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
addBasePath,
|
|
5
|
+
addLocale,
|
|
5
6
|
addTrailingSlash,
|
|
6
7
|
normalizeDataUrl,
|
|
7
8
|
normalizeLocalePath,
|
|
@@ -73,6 +74,33 @@ const normalizeRequestURL = (
|
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
76
|
|
|
77
|
+
export const localizeRequest = (
|
|
78
|
+
url: URL,
|
|
79
|
+
nextConfig?: {
|
|
80
|
+
basePath?: string
|
|
81
|
+
i18n?: I18NConfig | null
|
|
82
|
+
},
|
|
83
|
+
): { localizedUrl: URL; locale?: string } => {
|
|
84
|
+
const localizedUrl = new URL(url)
|
|
85
|
+
localizedUrl.pathname = removeBasePath(localizedUrl.pathname, nextConfig?.basePath)
|
|
86
|
+
|
|
87
|
+
// Detect the locale from the URL
|
|
88
|
+
const { detectedLocale } = normalizeLocalePath(localizedUrl.pathname, nextConfig?.i18n?.locales)
|
|
89
|
+
|
|
90
|
+
// Add the locale to the URL if not already present
|
|
91
|
+
localizedUrl.pathname = addLocale(
|
|
92
|
+
localizedUrl.pathname,
|
|
93
|
+
detectedLocale ?? nextConfig?.i18n?.defaultLocale,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
localizedUrl.pathname = addBasePath(localizedUrl.pathname, nextConfig?.basePath)
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
localizedUrl,
|
|
100
|
+
locale: detectedLocale,
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
76
104
|
export const buildNextRequest = (
|
|
77
105
|
request: Request,
|
|
78
106
|
context: Context,
|
package/edge-runtime/lib/util.ts
CHANGED
|
@@ -29,6 +29,20 @@ export const addBasePath = (path: string, basePath?: string) => {
|
|
|
29
29
|
return path
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
// add locale prefix if not present, allowing for locale fallbacks
|
|
33
|
+
export const addLocale = (path: string, locale?: string) => {
|
|
34
|
+
if (
|
|
35
|
+
locale &&
|
|
36
|
+
path.toLowerCase() !== `/${locale.toLowerCase()}` &&
|
|
37
|
+
!path.toLowerCase().startsWith(`/${locale.toLowerCase()}/`) &&
|
|
38
|
+
!path.startsWith(`/api/`) &&
|
|
39
|
+
!path.startsWith(`/_next/`)
|
|
40
|
+
) {
|
|
41
|
+
return `/${locale}${path}`
|
|
42
|
+
}
|
|
43
|
+
return path
|
|
44
|
+
}
|
|
45
|
+
|
|
32
46
|
// https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/i18n/normalize-locale-path.ts
|
|
33
47
|
|
|
34
48
|
export interface PathLocale {
|
|
@@ -5,7 +5,7 @@ import nextConfig from './next.config.json' with { type: 'json' }
|
|
|
5
5
|
|
|
6
6
|
import { InternalHeaders } from './lib/headers.ts'
|
|
7
7
|
import { logger, LogLevel } from './lib/logging.ts'
|
|
8
|
-
import { buildNextRequest, RequestData } from './lib/next-request.ts'
|
|
8
|
+
import { buildNextRequest, localizeRequest, RequestData } from './lib/next-request.ts'
|
|
9
9
|
import { buildResponse, FetchEventResult } from './lib/response.ts'
|
|
10
10
|
import {
|
|
11
11
|
getMiddlewareRouteMatcher,
|
|
@@ -31,8 +31,8 @@ export async function handleMiddleware(
|
|
|
31
31
|
context: Context,
|
|
32
32
|
nextHandler: NextHandler,
|
|
33
33
|
) {
|
|
34
|
-
const nextRequest = buildNextRequest(request, context, nextConfig)
|
|
35
34
|
const url = new URL(request.url)
|
|
35
|
+
|
|
36
36
|
const reqLogger = logger
|
|
37
37
|
.withLogLevel(
|
|
38
38
|
request.headers.has(InternalHeaders.NFDebugLogging) ? LogLevel.Debug : LogLevel.Log,
|
|
@@ -40,16 +40,20 @@ export async function handleMiddleware(
|
|
|
40
40
|
.withFields({ url_path: url.pathname })
|
|
41
41
|
.withRequestID(request.headers.get(InternalHeaders.NFRequestID))
|
|
42
42
|
|
|
43
|
+
const { localizedUrl } = localizeRequest(url, nextConfig)
|
|
43
44
|
// While we have already checked the path when mapping to the edge function,
|
|
44
45
|
// Next.js supports extra rules that we need to check here too, because we
|
|
45
46
|
// might be running an edge function for a path we should not. If we find
|
|
46
47
|
// that's the case, short-circuit the execution.
|
|
47
|
-
if (
|
|
48
|
+
if (
|
|
49
|
+
!matchesMiddleware(localizedUrl.pathname, request, searchParamsToUrlQuery(url.searchParams))
|
|
50
|
+
) {
|
|
48
51
|
reqLogger.debug('Aborting middleware due to runtime rules')
|
|
49
52
|
|
|
50
53
|
return
|
|
51
54
|
}
|
|
52
55
|
|
|
56
|
+
const nextRequest = buildNextRequest(request, context, nextConfig)
|
|
53
57
|
try {
|
|
54
58
|
const result = await nextHandler({ request: nextRequest })
|
|
55
59
|
const response = await buildResponse({
|