]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
feat(parser): strict option
authorEduardo San Martin Morote <posva13@gmail.com>
Sat, 14 Dec 2019 15:54:00 +0000 (16:54 +0100)
committerEduardo San Martin Morote <posva13@gmail.com>
Wed, 18 Dec 2019 09:26:15 +0000 (10:26 +0100)
__tests__/matcher/path-parser.spec.ts
src/matcher/tokenizer.ts

index 63b2b916f3ff10f812c13797417fb787d1b75fb4..631a75b3b58d418934cbe6a3aa73e7c87458e4bf 100644 (file)
@@ -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', {})
     })
index 3030b264d9bfaed74c1c761951141d6f0c65c2fa..1434027d5bad9e5468911be390e5d8eb547fde48 100644 (file)
@@ -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')