]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
fix(matcher): force leading slash with optional param in multi segments
authorEduardo San Martin Morote <posva13@gmail.com>
Fri, 15 Jan 2021 09:05:22 +0000 (10:05 +0100)
committerEduardo San Martin Morote <posva13@gmail.com>
Fri, 15 Jan 2021 09:06:28 +0000 (10:06 +0100)
__tests__/matcher/pathParser.spec.ts
src/matcher/pathParserRanker.ts

index f9b9be8b2f634f14a9c7a0a8e929d2afaf8ca45a..6c663a9b4f1139f022ebc0b429e88687c8f97f17 100644 (file)
@@ -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')
index c8e998c994377306210a8c159061d9cd2cb3984e..0a848ffd12d7e8d7ddbc02e735e8ce63511e6988 100644 (file)
@@ -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