@@ -5,7 +5,6 @@ import type { Manifest, ManifestFunction } from '@netlify/edge-functions'
55import { glob } from 'fast-glob'
66import type { FunctionsConfigManifest } from 'next-with-cache-handler-v2/dist/build/index.js'
77import type { EdgeFunctionDefinition as EdgeMiddlewareDefinition } from 'next-with-cache-handler-v2/dist/build/webpack/plugins/middleware-plugin.js'
8- import { pathToRegexp } from 'path-to-regexp'
98
109import { EDGE_HANDLER_NAME , PluginContext } from '../plugin-context.js'
1110
@@ -56,6 +55,20 @@ const copyRuntime = async (ctx: PluginContext, handlerDirectory: string): Promis
5655 )
5756}
5857
58+ const fixEdgeRuntimeTurbopackMatcherJsonPart = ( matchers : EdgeMiddlewareDefinition [ 'matchers' ] ) => {
59+ return matchers . map ( ( matcher ) => {
60+ if ( matcher . regexp ) {
61+ return {
62+ ...matcher ,
63+ // Next.js in some versions produces "\\\\.json" for edge runtime middleware when built with turbopack
64+ // with too many escapes preventing proper matching
65+ regexp : matcher . regexp . replaceAll ( '\\\\.json' , '\\.json' ) ,
66+ }
67+ }
68+ return matcher
69+ } )
70+ }
71+
5972/**
6073 * When i18n is enabled the matchers assume that paths _always_ include the
6174 * locale. We manually add an extra matcher for the original path without
@@ -80,13 +93,18 @@ const augmentMatchers = (
8093 // Next is producing pretty broad matcher for i18n locale. Presumably rest of their infrastructure protects this broad matcher
8194 // from matching on non-locale paths. For us this becomes request entry point, so we need to narrow it down to just defined locales
8295 // otherwise users might get unexpected matches on paths like `/api*`
83- regexp : matcher . regexp . replace ( / \[ \^ \/ \. ] + / g, `(${ i18NConfig . locales . join ( '|' ) } )` ) ,
96+ // additionally we don't have a way to normalize i18n paths for request without locale information, so we need to adjust the regexp to mark locale part as optional
97+ regexp : matcher . regexp
98+ // replace i18n part matching:
99+ // - target locales only
100+ // - make it optional to allow matching both with and without locale
101+ // (?:\\/((?!_next\\/)[^/.]{1,}))
102+ . replace (
103+ '(?:\\/((?!_next\\/)[^/.]{1,}))' ,
104+ `(?:\\/((?!_next\\/)(${ i18NConfig . locales . join ( '|' ) } ){1,}))?` ,
105+ ) ,
84106 }
85107 : matcher ,
86- {
87- ...matcher ,
88- regexp : pathToRegexp ( matcher . originalSource ) . source ,
89- } ,
90108 ]
91109 }
92110 return matcher
@@ -330,7 +348,7 @@ export const createEdgeHandlers = async (ctx: PluginContext) => {
330348 runtime : 'edge' ,
331349 functionDefinition : edgeDefinition ,
332350 name : edgeDefinition . name ,
333- matchers : edgeDefinition . matchers ,
351+ matchers : fixEdgeRuntimeTurbopackMatcherJsonPart ( edgeDefinition . matchers ) ,
334352 }
335353 } )
336354
0 commit comments