@netlify/plugin-nextjs 4.30.2 → 4.30.3
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/edge.js
CHANGED
|
@@ -87,6 +87,7 @@ const IMPORT_UNSUPPORTED = [
|
|
|
87
87
|
const getMiddlewareBundle = async ({ edgeFunctionDefinition, netlifyConfig, }) => {
|
|
88
88
|
const { publish } = netlifyConfig.build;
|
|
89
89
|
const chunks = [preamble];
|
|
90
|
+
chunks.push(`export const _DEFINITION = ${JSON.stringify(edgeFunctionDefinition)}`);
|
|
90
91
|
if ('wasm' in edgeFunctionDefinition) {
|
|
91
92
|
for (const { name, filePath } of edgeFunctionDefinition.wasm) {
|
|
92
93
|
const wasm = await fs_1.promises.readFile((0, path_1.join)(publish, filePath));
|
|
@@ -289,13 +290,17 @@ const writeEdgeFunctions = async ({ netlifyConfig, routesManifest, }) => {
|
|
|
289
290
|
});
|
|
290
291
|
manifest.functions.push(...matchers.map((matcher) => middlewareMatcherToEdgeFunctionDefinition(matcher, functionName)));
|
|
291
292
|
}
|
|
293
|
+
// Functions (i.e. not middleware, but edge SSR and API routes)
|
|
292
294
|
if (typeof middlewareManifest.functions === 'object') {
|
|
293
295
|
// When using the app dir, we also need to check if the EF matches a page
|
|
294
296
|
const appPathRoutesManifest = await (0, exports.loadAppPathRoutesManifest)(netlifyConfig);
|
|
297
|
+
// A map of all route pages to their page regex. This is used for pages dir and appDir.
|
|
295
298
|
const pageRegexMap = new Map([...(routesManifest.dynamicRoutes || []), ...(routesManifest.staticRoutes || [])].map((route) => [
|
|
296
299
|
route.page,
|
|
297
300
|
route.regex,
|
|
298
301
|
]));
|
|
302
|
+
// Create a map of pages-dir routes to their data route regex (appDir uses the same route as the HTML)
|
|
303
|
+
const dataRoutesMap = new Map([...(routesManifest.dataRoutes || [])].map((route) => [route.page, route.dataRouteRegex]));
|
|
299
304
|
for (const edgeFunctionDefinition of Object.values(middlewareManifest.functions)) {
|
|
300
305
|
usesEdge = true;
|
|
301
306
|
const functionName = sanitizeName(edgeFunctionDefinition.name);
|
|
@@ -317,6 +322,16 @@ const writeEdgeFunctions = async ({ netlifyConfig, routesManifest, }) => {
|
|
|
317
322
|
// cache: "manual" is currently experimental, so we restrict it to sites that use experimental appDir
|
|
318
323
|
cache: usesAppDir ? 'manual' : undefined,
|
|
319
324
|
});
|
|
325
|
+
// pages-dir page routes also have a data route. If there's a match, add an entry mapping that to the function too
|
|
326
|
+
const dataRoute = dataRoutesMap.get(edgeFunctionDefinition.page);
|
|
327
|
+
if (dataRoute) {
|
|
328
|
+
manifest.functions.push({
|
|
329
|
+
function: functionName,
|
|
330
|
+
name: edgeFunctionDefinition.name,
|
|
331
|
+
pattern: dataRoute,
|
|
332
|
+
cache: usesAppDir ? 'manual' : undefined,
|
|
333
|
+
});
|
|
334
|
+
}
|
|
320
335
|
}
|
|
321
336
|
}
|
|
322
337
|
if (usesEdge) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* This placeholder is replaced with the compiled Next.js bundle at build time
|
|
3
3
|
* @param {Object} props
|
|
4
|
-
* @param {import("./runtime.ts").RequestData} props.request
|
|
4
|
+
* @param {import("./function-runtime.ts").RequestData} props.request
|
|
5
5
|
* @returns {Promise<import("../edge-shared/utils.ts").FetchEventResult>}
|
|
6
6
|
*/
|
|
7
7
|
export default async ({ request }) => {}
|
|
8
|
+
export const _DEFINITION = { env: [], files: [], page: 'placeholder', name: 'pages_placeholder', matchers: [] }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Context } from 'https://edge.netlify.com'
|
|
2
2
|
// Available at build time
|
|
3
|
-
import edgeFunction from './bundle.js'
|
|
3
|
+
import { _DEFINITION as edgeFunctionDefinition, default as edgeFunction } from './bundle.js'
|
|
4
4
|
import { buildNextRequest, buildResponse, redirectTrailingSlash } from '../edge-shared/utils.ts'
|
|
5
5
|
import nextConfig from '../edge-shared/nextConfig.json' assert { type: 'json' }
|
|
6
6
|
|
|
@@ -11,6 +11,7 @@ const handler = async (req: Request, context: Context) => {
|
|
|
11
11
|
return redirect
|
|
12
12
|
}
|
|
13
13
|
const request = buildNextRequest(req, context, nextConfig)
|
|
14
|
+
request.headers['x-matched-path'] ||= edgeFunctionDefinition.page
|
|
14
15
|
try {
|
|
15
16
|
const result = await edgeFunction({ request })
|
|
16
17
|
return buildResponse({ result, request: req, context })
|
|
@@ -42,6 +42,7 @@ export type Rewrite = {
|
|
|
42
42
|
basePath?: false
|
|
43
43
|
locale?: false
|
|
44
44
|
has?: RouteHas[]
|
|
45
|
+
missing?: RouteHas[]
|
|
45
46
|
regex: string
|
|
46
47
|
}
|
|
47
48
|
|
|
@@ -51,6 +52,7 @@ export type Header = {
|
|
|
51
52
|
locale?: false
|
|
52
53
|
headers: Array<{ key: string; value: string }>
|
|
53
54
|
has?: RouteHas[]
|
|
55
|
+
missing?: RouteHas[]
|
|
54
56
|
regex: string
|
|
55
57
|
}
|
|
56
58
|
export type Redirect = {
|
|
@@ -59,6 +61,7 @@ export type Redirect = {
|
|
|
59
61
|
basePath?: false
|
|
60
62
|
locale?: false
|
|
61
63
|
has?: RouteHas[]
|
|
64
|
+
missing?: RouteHas[]
|
|
62
65
|
statusCode?: number
|
|
63
66
|
permanent?: boolean
|
|
64
67
|
regex: string
|
|
@@ -138,11 +141,16 @@ export function parseUrl(url: string): ParsedUrl {
|
|
|
138
141
|
|
|
139
142
|
// prepare-destination.ts
|
|
140
143
|
// Changed to use WHATWG Fetch Request instead of IncomingMessage
|
|
141
|
-
export function matchHas(
|
|
144
|
+
export function matchHas(
|
|
145
|
+
req: Pick<Request, 'headers' | 'url'>,
|
|
146
|
+
query: Params,
|
|
147
|
+
has: RouteHas[] = [],
|
|
148
|
+
missing: RouteHas[] = [],
|
|
149
|
+
): false | Params {
|
|
142
150
|
const params: Params = {}
|
|
143
151
|
const cookies = getCookies(req.headers)
|
|
144
152
|
const url = new URL(req.url)
|
|
145
|
-
const
|
|
153
|
+
const hasMatch = (hasItem: RouteHas) => {
|
|
146
154
|
let value: undefined | string | null
|
|
147
155
|
let key = hasItem.key
|
|
148
156
|
|
|
@@ -189,7 +197,9 @@ export function matchHas(req: Pick<Request, 'headers' | 'url'>, has: RouteHas[],
|
|
|
189
197
|
}
|
|
190
198
|
}
|
|
191
199
|
return false
|
|
192
|
-
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const allMatch = has.every((item) => hasMatch(item)) && !missing.some((item) => hasMatch(item))
|
|
193
203
|
|
|
194
204
|
if (allMatch) {
|
|
195
205
|
return params
|
|
@@ -371,6 +381,7 @@ export interface MiddlewareMatcher {
|
|
|
371
381
|
regexp: string
|
|
372
382
|
locale?: false
|
|
373
383
|
has?: RouteHas[]
|
|
384
|
+
missing?: RouteHas[]
|
|
374
385
|
}
|
|
375
386
|
|
|
376
387
|
export function getMiddlewareRouteMatcher(matchers: MiddlewareMatcher[]): MiddlewareRouteMatch {
|
|
@@ -381,8 +392,8 @@ export function getMiddlewareRouteMatcher(matchers: MiddlewareMatcher[]): Middle
|
|
|
381
392
|
continue
|
|
382
393
|
}
|
|
383
394
|
|
|
384
|
-
if (matcher.has) {
|
|
385
|
-
const hasParams = matchHas(req, matcher.has,
|
|
395
|
+
if (matcher.has || matcher.missing) {
|
|
396
|
+
const hasParams = matchHas(req, query, matcher.has, matcher.missing)
|
|
386
397
|
if (!hasParams) {
|
|
387
398
|
continue
|
|
388
399
|
}
|