Skip to content

Commit

Permalink
fix(matcher): force leading slash with optional param in multi segments
Browse files Browse the repository at this point in the history
  • Loading branch information
posva committed Jan 15, 2021
1 parent ecb67ec commit 11c882f
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
12 changes: 12 additions & 0 deletions __tests__/matcher/pathParser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,12 @@ describe('Path parser', () => {
matchParams('/home', '/home/other', {}, { end: false })
})

it('should not match optional params + static without leading slash', () => {
matchParams('/a/:p?-b', '/a-b', null)
matchParams('/a/:p?-b', '/a/-b', { p: '' })
matchParams('/a/:p?-b', '/a/e-b', { p: 'e' })
})

it('returns an empty object with no keys', () => {
matchParams('/home', '/home', {})
})
Expand Down Expand Up @@ -799,6 +805,12 @@ describe('Path parser', () => {
matchStringify('/b-:a?/other', {}, '/b-/other')
})

it('starting optional param? with static segment should not drop the initial /', () => {
matchStringify('/a/:a?-other/other', { a: '' }, '/a/-other/other')
matchStringify('/a/:a?-other/other', {}, '/a/-other/other')
matchStringify('/a/:a?-other/other', { a: 'p' }, '/a/p-other/other')
})

it('optional param*', () => {
matchStringify('/:a*/other', { a: '' }, '/other')
matchStringify('/:a*/other', { a: [] }, '/other')
Expand Down
19 changes: 14 additions & 5 deletions src/matcher/pathParserRanker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,12 @@ export function tokensToParser(

// prepend the slash if we are starting a new segment
if (!tokenIndex)
subPattern = optional ? `(?:/${subPattern})` : '/' + subPattern
subPattern =
// avoid an optional / if there are more segments e.g. /:p?-static
// or /:p?-:p2
optional && segment.length < 2
? `(?:/${subPattern})`
: '/' + subPattern
if (optional) subPattern += '?'

pattern += subPattern
Expand Down Expand Up @@ -239,10 +244,14 @@ export function tokensToParser(
const text: string = Array.isArray(param) ? param.join('/') : param
if (!text) {
if (optional) {
// remove the last slash as we could be at the end
if (path.endsWith('/')) path = path.slice(0, -1)
// do not append a slash on the next iteration
else avoidDuplicatedSlash = true
// if we have more than one optional param like /:a?-static we
// don't need to care about the optional param
if (segment.length < 2) {
// remove the last slash as we could be at the end
if (path.endsWith('/')) path = path.slice(0, -1)
// do not append a slash on the next iteration
else avoidDuplicatedSlash = true
}
} else throw new Error(`Missing required param "${value}"`)
}
path += text
Expand Down

0 comments on commit 11c882f

Please sign in to comment.