Skip to content

Commit 9d440ab

Browse files
authored
fix: correctly handle matchers with lookaheads and i18n (#1693)
* fix: correctly handle matchers with lookaheads and i18n * chore: add tests * fix: add back rest of matcher * chore: remove comment
1 parent 1763ba3 commit 9d440ab

File tree

9 files changed

+163
-46
lines changed

9 files changed

+163
-46
lines changed

cypress/integration/middleware/enhanced.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ describe('Enhanced middleware', () => {
1818
})
1919

2020
it('modifies the page props', () => {
21-
cy.request('/_next/data/build-id/static.json').then((response) => {
21+
cy.request('/_next/data/build-id/en/static.json').then((response) => {
2222
expect(response.body).to.have.nested.property('pageProps.showAd', true)
2323
expect(response.body)
2424
.to.have.nested.property('pageProps.message')

cypress/integration/middleware/standard.spec.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,22 @@ describe('Middleware matchers', () => {
3737
})
3838

3939
it('matches when headers are sent', () => {
40-
cy.request('/_next/data/build-id/static.json').then((response) => {
40+
cy.request('/_next/data/build-id/en/static.json').then((response) => {
4141
expect(response.headers).to.have.property('x-is-deno', 'true')
4242
expect(response.headers).to.have.property('x-modified-edge', 'true')
4343
})
4444
})
45+
46+
it('correctly handles negative lookaheads', () => {
47+
cy.request('/shows/11').then((response) => {
48+
expect(response.headers).to.have.property('x-is-deno', 'true')
49+
expect(response.headers).to.have.property('x-modified-edge', 'true')
50+
})
51+
cy.request('/shows/99').then((response) => {
52+
expect(response.headers).not.to.have.property('x-is-deno', 'true')
53+
expect(response.headers).not.to.have.property('x-modified-edge', 'true')
54+
})
55+
})
4556
})
4657

4758
describe('Middleware with edge API', () => {

demos/middleware/middleware.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export const config = {
9494
'/api/:all*',
9595
'/headers',
9696
{ source: '/static' },
97-
{ source: '/shows/:all*' },
97+
{ source: '/shows/((?!99|88).*)' },
9898
{
9999
source: '/conditional',
100100
has: [

demos/middleware/next.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ const nextConfig = {
77
ignoreDuringBuilds: true,
88
},
99
generateBuildId: () => 'build-id',
10+
i18n: {
11+
defaultLocale: 'en',
12+
locales: ['en'],
13+
},
1014
}
1115

1216
module.exports = nextConfig

package-lock.json

Lines changed: 28 additions & 41 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/runtime/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"p-limit": "^3.1.0",
2929
"pathe": "^0.2.0",
3030
"pretty-bytes": "^5.6.0",
31+
"regexp-tree": "^0.1.24",
3132
"semver": "^7.3.5",
3233
"slash": "^3.0.0",
3334
"tiny-glob": "^0.2.9"

packages/runtime/src/helpers/edge.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import type { MiddlewareManifest } from 'next/dist/build/webpack/plugins/middlew
1010
import type { RouteHas } from 'next/dist/lib/load-custom-routes'
1111
import { outdent } from 'outdent'
1212

13-
import { getRequiredServerFiles } from './config'
13+
import { getRequiredServerFiles, NextConfig } from './config'
14+
import { makeLocaleOptional, stripLookahead } from './matchers'
1415

1516
// This is the format as of [email protected]
1617
interface EdgeFunctionDefinitionV1 {
@@ -132,10 +133,12 @@ const writeEdgeFunction = async ({
132133
edgeFunctionDefinition,
133134
edgeFunctionRoot,
134135
netlifyConfig,
136+
nextConfig,
135137
}: {
136138
edgeFunctionDefinition: EdgeFunctionDefinition
137139
edgeFunctionRoot: string
138140
netlifyConfig: NetlifyConfig
141+
nextConfig: NextConfig
139142
}): Promise<
140143
Array<{
141144
function: string
@@ -165,14 +168,22 @@ const writeEdgeFunction = async ({
165168
// The v1 middleware manifest has a single regexp, but the v2 has an array of matchers
166169
if ('regexp' in edgeFunctionDefinition) {
167170
matchers.push({ regexp: edgeFunctionDefinition.regexp })
171+
} else if (nextConfig.i18n) {
172+
matchers.push(
173+
...edgeFunctionDefinition.matchers.map((matcher) => ({
174+
...matcher,
175+
regexp: makeLocaleOptional(matcher.regexp),
176+
})),
177+
)
168178
} else {
169179
matchers.push(...edgeFunctionDefinition.matchers)
170180
}
181+
171182
await writeJson(join(edgeFunctionDir, 'matchers.json'), matchers)
172183

173184
// We add a defintion for each matching path
174185
return matchers.map((matcher) => {
175-
const pattern = matcher.regexp
186+
const pattern = stripLookahead(matcher.regexp)
176187
return { function: name, pattern, name: edgeFunctionDefinition.name }
177188
})
178189
}
@@ -258,6 +269,7 @@ export const writeEdgeFunctions = async (netlifyConfig: NetlifyConfig) => {
258269
edgeFunctionDefinition,
259270
edgeFunctionRoot,
260271
netlifyConfig,
272+
nextConfig,
261273
})
262274
manifest.functions.push(...functionDefinitions)
263275
}
@@ -270,6 +282,7 @@ export const writeEdgeFunctions = async (netlifyConfig: NetlifyConfig) => {
270282
edgeFunctionDefinition,
271283
edgeFunctionRoot,
272284
netlifyConfig,
285+
nextConfig,
273286
})
274287
manifest.functions.push(...functionDefinitions)
275288
}

0 commit comments

Comments
 (0)