Skip to content

Commit

Permalink
Use regex lexer for gathering named groups from has (#23626)
Browse files Browse the repository at this point in the history
This is a follow-up to #23588 to update to use a regex lexer to gather the named regex groups instead of attempting to gather them through executing the regex since it can fail to gather the regex groups when they are using specific matching. This also ensures we don't pass the value as a segment when value is defined and it doesn't use a capture group. Additional tests are added to cover these cases and documentation updated to reflect this. 

Closes: #23415

## Bug

- [x] Related issues linked using `fixes #number`
- [x] Integration tests added

## Documentation / Examples

- [x] Make sure the linting passes
  • Loading branch information
ijjk committed Apr 13, 2021
1 parent 9a548b6 commit 4d291bd
Show file tree
Hide file tree
Showing 15 changed files with 1,672 additions and 28 deletions.
3 changes: 2 additions & 1 deletion .eslintignore
Expand Up @@ -16,4 +16,5 @@ packages/next-codemod/**/*.js
packages/next-codemod/**/*.d.ts
packages/next-env/**/*.d.ts
test/integration/async-modules/**
test-timings.json
test-timings.json
packages/next/lib/regexr/**/*
3 changes: 3 additions & 0 deletions docs/api-reference/next.config.js/headers.md
Expand Up @@ -195,6 +195,9 @@ module.exports = {
{
type: 'query',
key: 'page',
// the page value will not be available in the
// header key/values since value is provided and
// doesn't use a named capture group e.g. (?<page>home)
value: 'home',
},
{
Expand Down
3 changes: 3 additions & 0 deletions docs/api-reference/next.config.js/redirects.md
Expand Up @@ -135,6 +135,9 @@ module.exports = {
{
type: 'query',
key: 'page',
// the page value will not be available in the
// destination since value is provided and doesn't
// use a named capture group e.g. (?<page>home)
value: 'home',
},
{
Expand Down
5 changes: 4 additions & 1 deletion docs/api-reference/next.config.js/rewrites.md
Expand Up @@ -214,6 +214,9 @@ module.exports = {
{
type: 'query',
key: 'page',
// the page value will not be available in the
// destination since value is provided and doesn't
// use a named capture group e.g. (?<page>home)
value: 'home',
},
{
Expand All @@ -222,7 +225,7 @@ module.exports = {
value: 'true',
},
],
destination: '/:path*/:page',
destination: '/:path*/home',
},
// if the header `x-authorized` is present and
// contains a matching value, this rewrite will be applied
Expand Down
29 changes: 14 additions & 15 deletions packages/next/lib/load-custom-routes.ts
Expand Up @@ -8,7 +8,10 @@ import {
} from '../next-server/lib/constants'
import { execOnce } from '../next-server/lib/utils'
import * as Log from '../build/output/log'
import { getSafeParamName } from '../next-server/lib/router/utils/prepare-destination'
// @ts-ignore
import Lexer from 'next/dist/compiled/regexr-lexer/lexer'
// @ts-ignore
import lexerProfiles from 'next/dist/compiled/regexr-lexer/profiles'

export type RouteHas =
| {
Expand Down Expand Up @@ -336,20 +339,16 @@ function checkCustomRoutes(

if (hasItem.value) {
const matcher = new RegExp(`^${hasItem.value}$`)
const matches = matcher.exec('')

if (matches) {
if (matches.groups) {
Object.keys(matches.groups).forEach((groupKey) => {
const safeKey = getSafeParamName(groupKey)

if (safeKey && matches.groups![groupKey]) {
hasSegments.add(safeKey)
}
})
} else {
hasSegments.add(hasItem.key || 'host')
}
const lexer = new Lexer()
lexer.profile = lexerProfiles.js
lexer.parse(`/${matcher.source}/`)

Object.keys(lexer.namedGroups).forEach((groupKey) => {
hasSegments.add(groupKey)
})

if (hasItem.type === 'host') {
hasSegments.add('host')
}
}
}
Expand Down

0 comments on commit 4d291bd

Please sign in to comment.