From: Eduardo San Martin Morote Date: Fri, 15 Jan 2021 09:05:22 +0000 (+0100) Subject: fix(matcher): force leading slash with optional param in multi segments X-Git-Tag: v4.0.4~53 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=11c882f8f3b56d2c87fc095c46eb8050fbbf61df;p=thirdparty%2Fvuejs%2Frouter.git fix(matcher): force leading slash with optional param in multi segments --- diff --git a/__tests__/matcher/pathParser.spec.ts b/__tests__/matcher/pathParser.spec.ts index f9b9be8b..6c663a9b 100644 --- a/__tests__/matcher/pathParser.spec.ts +++ b/__tests__/matcher/pathParser.spec.ts @@ -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', {}) }) @@ -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') diff --git a/src/matcher/pathParserRanker.ts b/src/matcher/pathParserRanker.ts index c8e998c9..0a848ffd 100644 --- a/src/matcher/pathParserRanker.ts +++ b/src/matcher/pathParserRanker.ts @@ -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 @@ -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