From: Eduardo San Martin Morote Date: Sat, 14 Dec 2019 15:54:00 +0000 (+0100) Subject: feat(parser): strict option X-Git-Tag: v4.0.0-alpha.0~148 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fca4e6090d0f605c5beb69c6cc9de1af513fae45;p=thirdparty%2Fvuejs%2Frouter.git feat(parser): strict option --- diff --git a/__tests__/matcher/path-parser.spec.ts b/__tests__/matcher/path-parser.spec.ts index 63b2b916..631a75b3 100644 --- a/__tests__/matcher/path-parser.spec.ts +++ b/__tests__/matcher/path-parser.spec.ts @@ -449,6 +449,23 @@ describe('Path parser', () => { matchParams('/home', '/', null) }) + it('allow a trailing slash', () => { + matchParams('/home', '/home/', {}) + matchParams('/a/b', '/a/b/', {}) + }) + + it('allow a trailing slash in repeated params', () => { + matchParams('/a/:id+', '/a/b/c/d/', { id: ['b', 'c', 'd'] }) + matchParams('/a/:id*', '/a/b/c/d/', { id: ['b', 'c', 'd'] }) + matchParams('/a/:id*', '/a/', { id: '' }) + matchParams('/a/:id*', '/a', { id: '' }) + }) + + it('allow no slash', () => { + matchParams('/home', '/home/', null, { strict: true }) + matchParams('/home', '/home', {}, { strict: true }) + }) + it('is insensitive by default', () => { matchParams('/home', '/HOMe', {}) }) diff --git a/src/matcher/tokenizer.ts b/src/matcher/tokenizer.ts index 3030b264..1434027d 100644 --- a/src/matcher/tokenizer.ts +++ b/src/matcher/tokenizer.ts @@ -249,10 +249,13 @@ export function tokensToParser( const keys: ParamKey[] = [] for (const segment of segments) { - pattern += '/' + if (!segment.length) pattern += '/' - for (const token of segment) { + for (let tokenIndex = 0; tokenIndex < segment.length; tokenIndex++) { + const token = segment[tokenIndex] if (token.type === TokenType.Static) { + // prepend the slash if we are starting a new segment + if (!tokenIndex) pattern += '/' pattern += token.value } else if (token.type === TokenType.Param) { keys.push({ @@ -270,13 +273,24 @@ export function tokensToParser( ) } } - pattern += token.repeatable ? `((?:${re})(?:/(?:${re}))*)` : `(${re})` - if (token.optional) pattern += '?' + // (?:\/((?:${re})(?:\/(?:${re}))*)) + let subPattern = token.repeatable + ? `((?:${re})(?:/(?:${re}))*)` + : `(${re})` + + if (!tokenIndex) + subPattern = token.optional ? `(?:/${subPattern})?` : '/' + subPattern + else subPattern += token.optional ? '?' : '' + + pattern += subPattern } } } - pattern += options.end ? '$' : '' + // TODO: warn double trailing slash + if (!options.strict) pattern += '/?' + + if (options.end) pattern += '$' const re = new RegExp(pattern, options.sensitive ? '' : 'i')