@netlify/plugin-nextjs 5.5.0 → 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 +5 -5
- package/dist/build/functions/server.js +12 -10
- package/dist/build/plugin-context.js +3 -0
- package/dist/build/verification.js +2 -3
- package/dist/esm-chunks/{package-C5ZXMRQF.js → package-OHGYB5OD.js} +4 -4
- package/dist/index.js +8 -4
- 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,
|
|
@@ -501,8 +498,10 @@ var buildHandlerDefinition = (ctx, { name, matchers, page }) => {
|
|
|
501
498
|
generator
|
|
502
499
|
}));
|
|
503
500
|
};
|
|
504
|
-
var
|
|
501
|
+
var clearStaleEdgeHandlers = async (ctx) => {
|
|
505
502
|
await rm(ctx.edgeFunctionsDir, { recursive: true, force: true });
|
|
503
|
+
};
|
|
504
|
+
var createEdgeHandlers = async (ctx) => {
|
|
506
505
|
const nextManifest = await ctx.getMiddlewareManifest();
|
|
507
506
|
const nextDefinitions = [
|
|
508
507
|
...Object.values(nextManifest.middleware)
|
|
@@ -517,5 +516,6 @@ var createEdgeHandlers = async (ctx) => {
|
|
|
517
516
|
await writeEdgeManifest(ctx, netlifyManifest);
|
|
518
517
|
};
|
|
519
518
|
export {
|
|
519
|
+
clearStaleEdgeHandlers,
|
|
520
520
|
createEdgeHandlers
|
|
521
521
|
};
|
|
@@ -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);
|
|
@@ -121,19 +121,21 @@ var writeHandlerFile = async (ctx) => {
|
|
|
121
121
|
const handler = await getHandlerFile(ctx);
|
|
122
122
|
await writeFile(join(ctx.serverHandlerRootDir, `${SERVER_HANDLER_NAME}.mjs`), handler);
|
|
123
123
|
};
|
|
124
|
+
var clearStaleServerHandlers = async (ctx) => {
|
|
125
|
+
await rm(ctx.serverFunctionsDir, { recursive: true, force: true });
|
|
126
|
+
};
|
|
124
127
|
var createServerHandler = async (ctx) => {
|
|
125
128
|
await tracer.withActiveSpan("createServerHandler", async () => {
|
|
126
|
-
await
|
|
127
|
-
await mkdir(join(ctx.serverHandlerDir, ".netlify"), { recursive: true });
|
|
129
|
+
await mkdir(join(ctx.serverHandlerRuntimeModulesDir), { recursive: true });
|
|
128
130
|
await copyNextServerCode(ctx);
|
|
129
131
|
await copyNextDependencies(ctx);
|
|
130
132
|
await copyHandlerDependencies(ctx);
|
|
131
133
|
await writeHandlerManifest(ctx);
|
|
132
|
-
await writePackageMetadata(ctx);
|
|
133
134
|
await writeHandlerFile(ctx);
|
|
134
135
|
await verifyHandlerDirStructure(ctx);
|
|
135
136
|
});
|
|
136
137
|
};
|
|
137
138
|
export {
|
|
139
|
+
clearStaleServerHandlers,
|
|
138
140
|
createServerHandler
|
|
139
141
|
};
|
|
@@ -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
|
-
"@netlify/functions": "^2.8.
|
|
66
|
-
"@netlify/serverless-functions-api": "^1.
|
|
65
|
+
"@netlify/functions": "^2.8.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",
|
package/dist/index.js
CHANGED
|
@@ -25,8 +25,8 @@ import {
|
|
|
25
25
|
publishStaticDir,
|
|
26
26
|
unpublishStaticDir
|
|
27
27
|
} from "./build/content/static.js";
|
|
28
|
-
import { createEdgeHandlers } from "./build/functions/edge.js";
|
|
29
|
-
import { createServerHandler } from "./build/functions/server.js";
|
|
28
|
+
import { clearStaleEdgeHandlers, createEdgeHandlers } from "./build/functions/edge.js";
|
|
29
|
+
import { clearStaleServerHandlers, 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
32
|
import {
|
|
@@ -44,8 +44,12 @@ var onPreDev = async (options) => {
|
|
|
44
44
|
var onPreBuild = async (options) => {
|
|
45
45
|
await tracer.withActiveSpan("onPreBuild", async () => {
|
|
46
46
|
process.env.NEXT_PRIVATE_STANDALONE = "true";
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
const ctx = new PluginContext(options);
|
|
48
|
+
if (options.constants.IS_LOCAL) {
|
|
49
|
+
await clearStaleServerHandlers(ctx);
|
|
50
|
+
await clearStaleEdgeHandlers(ctx);
|
|
51
|
+
} else {
|
|
52
|
+
await restoreBuildCache(ctx);
|
|
49
53
|
}
|
|
50
54
|
});
|
|
51
55
|
};
|
|
@@ -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({
|