Skip to content

Commit 97a154e

Browse files
committed
Turbopack: Fix middleware matcher suffix (#93590)
## What? The Turbopack path incorrectly included a double backslash instead of one backslash in the regex matcher.
1 parent 83899bc commit 97a154e

2 files changed

Lines changed: 80 additions & 3 deletions

File tree

crates/next-api/src/middleware.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,11 +187,11 @@ impl MiddlewareEndpoint {
187187
if is_root {
188188
source.push('(');
189189
if has_i18n {
190-
source.push_str("|\\\\.json|");
190+
source.push_str("|\\.json|");
191191
}
192-
source.push_str("/?index|/?index\\\\.json)?")
192+
source.push_str("/?index|/?index\\.json)?")
193193
} else {
194-
source.push_str("{(\\\\.json)}?")
194+
source.push_str("{(\\.json)}?")
195195
};
196196

197197
source.insert_str(0, "/:nextData(_next/data/[^/]{1,})?");

test/e2e/middleware-matcher/index.test.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,83 @@ describe('Middleware can set the matcher in its config', () => {
111111
}, 'success')
112112
})
113113

114+
if ((global as any).isNextStart) {
115+
it('produces the expected middleware manifest', async () => {
116+
const manifest = JSON.parse(
117+
await next.readFile('.next/server/middleware-manifest.json')
118+
)
119+
120+
// Redact volatile fields so the snapshot is stable across builds:
121+
// - `env` values are randomly generated per build (encryption keys,
122+
// preview mode ids, build id).
123+
// - `files` and `entrypoint` paths contain content hashes and may
124+
// differ between webpack and Turbopack.
125+
const normalize = (value: unknown, key?: string): unknown => {
126+
if (key === 'env' && value && typeof value === 'object') {
127+
return Object.fromEntries(
128+
Object.keys(value)
129+
.sort()
130+
.map((k) => [k, '<redacted>'])
131+
)
132+
}
133+
if (key === 'files') return '<files>'
134+
if (key === 'entrypoint') return '<entrypoint>'
135+
if (Array.isArray(value)) return value.map((v) => normalize(v))
136+
if (value && typeof value === 'object') {
137+
return Object.fromEntries(
138+
Object.entries(value).map(([k, v]) => [k, normalize(v, k)])
139+
)
140+
}
141+
return value
142+
}
143+
144+
expect(normalize(manifest)).toMatchInlineSnapshot(`
145+
{
146+
"functions": {},
147+
"middleware": {
148+
"/": {
149+
"assets": [],
150+
"entrypoint": "<entrypoint>",
151+
"env": {
152+
"NEXT_SERVER_ACTIONS_ENCRYPTION_KEY": "<redacted>",
153+
"__NEXT_BUILD_ID": "<redacted>",
154+
"__NEXT_PREVIEW_MODE_ENCRYPTION_KEY": "<redacted>",
155+
"__NEXT_PREVIEW_MODE_ID": "<redacted>",
156+
"__NEXT_PREVIEW_MODE_SIGNING_KEY": "<redacted>",
157+
},
158+
"files": "<files>",
159+
"matchers": [
160+
{
161+
"originalSource": "/",
162+
"regexp": "^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/(\\/?index|\\/?index\\.json))?[\\/#\\?]?$",
163+
},
164+
{
165+
"originalSource": "/with-middleware/:path*",
166+
"regexp": "^(?:\\/(_next\\/data\\/[^/]{1,}))?\\/with-middleware(?:\\/((?:[^\\/#\\?]+?)(?:\\/(?:[^\\/#\\?]+?))*))?(\\.json)?[\\/#\\?]?$",
167+
},
168+
{
169+
"originalSource": "/another-middleware/:path*",
170+
"regexp": "^(?:\\/(_next\\/data\\/[^/]{1,}))?\\/another-middleware(?:\\/((?:[^\\/#\\?]+?)(?:\\/(?:[^\\/#\\?]+?))*))?(\\.json)?[\\/#\\?]?$",
171+
},
172+
{
173+
"originalSource": "/_sites/:path((?![^/]*\\.json$)[^/]+$)",
174+
"regexp": "^(?:\\/(_next\\/data\\/[^/]{1,}))?\\/_sites(?:\\/((?![^/]*\\.json$)[^/]+$))(\\.json)?[\\/#\\?]?$",
175+
},
176+
],
177+
"name": "middleware",
178+
"page": "/",
179+
"wasm": [],
180+
},
181+
},
182+
"sortedMiddleware": [
183+
"/",
184+
],
185+
"version": 3,
186+
}
187+
`)
188+
})
189+
}
190+
114191
it('should navigate correctly with matchers', async () => {
115192
const browser = await webdriver(next.url, '/')
116193
await browser.eval('window.beforeNav = 1')

0 commit comments

Comments
 (0)