@@ -202,27 +202,16 @@ const writeEdgeFunction = async ({
202
202
edgeFunctionDefinition,
203
203
edgeFunctionRoot,
204
204
netlifyConfig,
205
- pageRegexMap,
206
- appPathRoutesManifest = { } ,
207
- nextConfig,
208
- cache,
205
+ functionName,
206
+ matchers,
209
207
} : {
210
208
edgeFunctionDefinition : EdgeFunctionDefinition
211
209
edgeFunctionRoot : string
212
210
netlifyConfig : NetlifyConfig
213
- pageRegexMap ?: Map < string , string >
214
- appPathRoutesManifest ?: Record < string , string >
215
- nextConfig : NextConfig
216
- cache ?: 'manual'
217
- } ) : Promise <
218
- Array < {
219
- function : string
220
- name : string
221
- pattern : string
222
- } >
223
- > => {
224
- const name = sanitizeName ( edgeFunctionDefinition . name )
225
- const edgeFunctionDir = join ( edgeFunctionRoot , name )
211
+ functionName : string
212
+ matchers : Array < MiddlewareMatcher >
213
+ } ) => {
214
+ const edgeFunctionDir = join ( edgeFunctionRoot , functionName )
226
215
227
216
const bundle = await getMiddlewareBundle ( {
228
217
edgeFunctionDefinition,
@@ -238,39 +227,45 @@ const writeEdgeFunction = async ({
238
227
target : 'index.ts' ,
239
228
} )
240
229
241
- const matchers : EdgeFunctionDefinitionV2 [ 'matchers' ] = [ ]
230
+ await writeJson ( join ( edgeFunctionDir , 'matchers.json' ) , matchers )
231
+ }
242
232
233
+ const generateEdgeFunctionMiddlewareMatchers = ( {
234
+ edgeFunctionDefinition,
235
+ nextConfig,
236
+ } : {
237
+ edgeFunctionDefinition : EdgeFunctionDefinition
238
+ edgeFunctionRoot : string
239
+ nextConfig : NextConfig
240
+ cache ?: 'manual'
241
+ } ) : Array < MiddlewareMatcher > => {
243
242
// The v1 middleware manifest has a single regexp, but the v2 has an array of matchers
244
243
if ( 'regexp' in edgeFunctionDefinition ) {
245
- matchers . push ( { regexp : edgeFunctionDefinition . regexp } )
246
- } else if ( nextConfig . i18n ) {
247
- matchers . push (
248
- ...edgeFunctionDefinition . matchers . map ( ( matcher ) => ( {
249
- ...matcher ,
250
- regexp : makeLocaleOptional ( matcher . regexp ) ,
251
- } ) ) ,
252
- )
253
- } else {
254
- matchers . push ( ...edgeFunctionDefinition . matchers )
244
+ return [ { regexp : edgeFunctionDefinition . regexp } ]
255
245
}
256
-
257
- // If the EF matches a page, it's an app dir page so needs a matcher too
258
- // The object will be empty if appDir isn't enabled in the Next config
259
- if ( pageRegexMap && edgeFunctionDefinition . page in appPathRoutesManifest ) {
260
- const regexp = pageRegexMap . get ( appPathRoutesManifest [ edgeFunctionDefinition . page ] )
261
- if ( regexp ) {
262
- matchers . push ( { regexp } )
263
- }
246
+ if ( nextConfig . i18n ) {
247
+ return edgeFunctionDefinition . matchers . map ( ( matcher ) => ( {
248
+ ...matcher ,
249
+ regexp : makeLocaleOptional ( matcher . regexp ) ,
250
+ } ) )
264
251
}
252
+ return edgeFunctionDefinition . matchers
253
+ }
265
254
266
- await writeJson ( join ( edgeFunctionDir , 'matchers.json' ) , matchers )
267
-
268
- // We add a defintion for each matching path
269
- return matchers . map ( ( matcher ) => {
270
- const pattern = transformCaptureGroups ( stripLookahead ( matcher . regexp ) )
271
- return { function : name , pattern, name : edgeFunctionDefinition . name , cache }
272
- } )
255
+ const middlewareMatcherToEdgeFunctionDefinition = (
256
+ matcher : MiddlewareMatcher ,
257
+ name : string ,
258
+ cache ?: 'manual' ,
259
+ ) : {
260
+ function : string
261
+ name ?: string
262
+ pattern : string
263
+ cache ?: 'manual'
264
+ } => {
265
+ const pattern = transformCaptureGroups ( stripLookahead ( matcher . regexp ) )
266
+ return { function : name , pattern, name, cache }
273
267
}
268
+
274
269
export const cleanupEdgeFunctions = ( {
275
270
INTERNAL_EDGE_FUNCTIONS_SRC = '.netlify/edge-functions' ,
276
271
} : NetlifyPluginConstants ) => emptyDir ( INTERNAL_EDGE_FUNCTIONS_SRC )
@@ -348,9 +343,27 @@ export const writeRscDataEdgeFunction = async ({
348
343
]
349
344
}
350
345
346
+ const getEdgeFunctionPatternForPage = ( {
347
+ edgeFunctionDefinition,
348
+ pageRegexMap,
349
+ appPathRoutesManifest,
350
+ } : {
351
+ edgeFunctionDefinition : EdgeFunctionDefinitionV2
352
+ pageRegexMap : Map < string , string >
353
+ appPathRoutesManifest ?: Record < string , string >
354
+ } ) : string => {
355
+ // We don't just use the matcher from the edge function definition, because it doesn't handle trailing slashes
356
+
357
+ // appDir functions have a name that _isn't_ the route name, but rather the route with `/page` appended
358
+ const regexp = pageRegexMap . get ( appPathRoutesManifest ?. [ edgeFunctionDefinition . page ] ?? edgeFunctionDefinition . page )
359
+ return regexp ?? edgeFunctionDefinition . matchers [ 0 ] . regexp
360
+ }
361
+
351
362
/**
352
363
* Writes Edge Functions for the Next middleware
353
364
*/
365
+
366
+ // eslint-disable-next-line max-lines-per-function
354
367
export const writeEdgeFunctions = async ( {
355
368
netlifyConfig,
356
369
routesManifest,
@@ -415,16 +428,24 @@ export const writeEdgeFunctions = async ({
415
428
for ( const middleware of middlewareManifest . sortedMiddleware ) {
416
429
usesEdge = true
417
430
const edgeFunctionDefinition = middlewareManifest . middleware [ middleware ]
418
- const functionDefinitions = await writeEdgeFunction ( {
431
+ const functionName = sanitizeName ( edgeFunctionDefinition . name )
432
+ const matchers = generateEdgeFunctionMiddlewareMatchers ( {
419
433
edgeFunctionDefinition,
420
434
edgeFunctionRoot,
421
- netlifyConfig,
422
435
nextConfig,
423
436
} )
424
- manifest . functions . push ( ...functionDefinitions )
437
+ await writeEdgeFunction ( {
438
+ edgeFunctionDefinition,
439
+ edgeFunctionRoot,
440
+ netlifyConfig,
441
+ functionName,
442
+ matchers,
443
+ } )
444
+
445
+ manifest . functions . push (
446
+ ...matchers . map ( ( matcher ) => middlewareMatcherToEdgeFunctionDefinition ( matcher , functionName ) ) ,
447
+ )
425
448
}
426
- // Older versions of the manifest format don't have the functions field
427
- // No, the version field was not incremented
428
449
if ( typeof middlewareManifest . functions === 'object' ) {
429
450
// When using the app dir, we also need to check if the EF matches a page
430
451
const appPathRoutesManifest = await loadAppPathRoutesManifest ( netlifyConfig )
@@ -438,17 +459,26 @@ export const writeEdgeFunctions = async ({
438
459
439
460
for ( const edgeFunctionDefinition of Object . values ( middlewareManifest . functions ) ) {
440
461
usesEdge = true
441
- const functionDefinitions = await writeEdgeFunction ( {
462
+ const functionName = sanitizeName ( edgeFunctionDefinition . name )
463
+ await writeEdgeFunction ( {
442
464
edgeFunctionDefinition,
443
465
edgeFunctionRoot,
444
466
netlifyConfig,
467
+ functionName,
468
+ matchers : edgeFunctionDefinition . matchers ,
469
+ } )
470
+ const pattern = getEdgeFunctionPatternForPage ( {
471
+ edgeFunctionDefinition,
445
472
pageRegexMap,
446
473
appPathRoutesManifest,
447
- nextConfig,
474
+ } )
475
+ manifest . functions . push ( {
476
+ function : functionName ,
477
+ name : edgeFunctionDefinition . name ,
478
+ pattern,
448
479
// cache: "manual" is currently experimental, so we restrict it to sites that use experimental appDir
449
480
cache : usesAppDir ? 'manual' : undefined ,
450
481
} )
451
- manifest . functions . push ( ...functionDefinitions )
452
482
}
453
483
}
454
484
if ( usesEdge ) {
0 commit comments