]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
feat: inverse spalt and other params in MatcherPatternPathdynamic
authorEduardo San Martin Morote <posva13@gmail.com>
Sun, 24 Aug 2025 20:07:44 +0000 (22:07 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Sun, 24 Aug 2025 20:07:44 +0000 (22:07 +0200)
packages/experiments-playground/src/router/index.ts
packages/router/src/experimental/route-resolver/matchers/matcher-pattern.spec.ts
packages/router/src/experimental/route-resolver/matchers/matcher-pattern.test-d.ts
packages/router/src/experimental/route-resolver/matchers/matcher-pattern.ts
packages/router/src/experimental/router.spec.ts

index f53fb6a441a748d2e1ab9728db36987215cfb9d6..3f9c1bb32827c1d77f6b79da612278f8b854d577 100644 (file)
@@ -121,7 +121,7 @@ const r_profiles_detail = normalizeRouteRecord({
       // and therefore userId is of type number
       userId: PARAM_PARSER_INT,
     },
-    ['profiles', 0]
+    ['profiles', 1]
   ),
 })
 
index cc31a7658a71458dfca2da27bc6f2deed03068f3..cf50978444729fffba44412483a536a4c9a94876 100644 (file)
@@ -134,7 +134,7 @@ describe('MatcherPatternPathDynamic', () => {
         // all defaults
         teamId: {},
       },
-      ['teams', 0, 'b']
+      ['teams', 1, 'b']
     )
 
     expect(pattern.match('/teams/123/b')).toEqual({
@@ -155,7 +155,7 @@ describe('MatcherPatternPathDynamic', () => {
       {
         teamId: {},
       },
-      ['teams', 0]
+      ['teams', 1]
     )
     expect(pattern.match('/teams/a%20b')).toEqual({ teamId: 'a b' })
     expect(pattern.build({ teamId: 'a b' })).toBe('/teams/a%20b')
@@ -167,7 +167,7 @@ describe('MatcherPatternPathDynamic', () => {
       {
         teamId: {},
       },
-      ['teams', 0, 'b']
+      ['teams', 1, 'b']
     )
 
     expect(pattern.match('/teams/b')).toEqual({ teamId: null })
@@ -186,7 +186,7 @@ describe('MatcherPatternPathDynamic', () => {
       {
         teamId: {},
       },
-      ['teams', 0, 'b']
+      ['teams', 1, 'b']
     )
 
     expect(pattern.match('/teams/b')).toEqual({ teamId: null })
@@ -205,7 +205,7 @@ describe('MatcherPatternPathDynamic', () => {
       {
         teamId: { repeat: true },
       },
-      ['teams', 0, 'b']
+      ['teams', 1, 'b']
     )
 
     expect(pattern.match('/teams/123/b')).toEqual({ teamId: ['123'] })
@@ -228,7 +228,7 @@ describe('MatcherPatternPathDynamic', () => {
       {
         pathMatch: {},
       },
-      ['teams', 1]
+      ['teams', 0]
     )
     expect(pattern.match('/teams/')).toEqual({ pathMatch: '' })
     expect(pattern.match('/teams/123/b')).toEqual({ pathMatch: '123/b' })
@@ -247,7 +247,7 @@ describe('MatcherPatternPathDynamic', () => {
       {
         teamId: { repeat: true },
       },
-      ['teams', 0, 'b']
+      ['teams', 1, 'b']
     )
 
     expect(pattern.match('/teams/123/b')).toEqual({ teamId: ['123'] })
@@ -271,7 +271,7 @@ describe('MatcherPatternPathDynamic', () => {
         teamId: {},
         otherId: {},
       },
-      ['teams', 0, 0]
+      ['teams', 1, 1]
     )
 
     expect(pattern.match('/teams/123/456')).toEqual({
@@ -293,7 +293,7 @@ describe('MatcherPatternPathDynamic', () => {
         teamId: {},
         otherId: {},
       },
-      ['teams', [0, '-b-', 0]]
+      ['teams', [1, '-b-', 1]]
     )
 
     expect(pattern.match('/teams/123-b-456')).toEqual({
@@ -314,7 +314,7 @@ describe('MatcherPatternPathDynamic', () => {
       {
         teamId: {},
       },
-      ['teams', [0, '/']]
+      ['teams', [1, '/']]
     )
 
     expect(pattern.match('/teams/123/')).toEqual({
@@ -345,7 +345,7 @@ describe('MatcherPatternPathDynamic', () => {
       {
         teamId: { repeat: true },
       },
-      ['teams', [0, '/']]
+      ['teams', [1, '/']]
     )
 
     expect(pattern.match('/teams/123/')).toEqual({ teamId: ['123'] })
@@ -365,7 +365,7 @@ describe('MatcherPatternPathDynamic', () => {
       {
         teamId: { repeat: true },
       },
-      ['teams', [0, '/']]
+      ['teams', [1, '/']]
     )
 
     expect(pattern.match('/teams/123/')).toEqual({ teamId: ['123'] })
index 30dd53fff43f3cff1e7c55349844a6f0b55cf34c..ac515b102e15b75e311359d2fa39795646e5d561 100644 (file)
@@ -9,7 +9,7 @@ describe('MatcherPatternPathDynamic', () => {
     const matcher = new MatcherPatternPathDynamic(
       /^\/users\/([^/]+)$/i,
       { userId: { ...PATH_PARAM_PARSER_DEFAULTS } },
-      ['users', 0]
+      ['users', 1]
     )
 
     expectTypeOf(matcher.match('/users/123')).toEqualTypeOf<{
@@ -34,7 +34,7 @@ describe('MatcherPatternPathDynamic', () => {
     const matcher = new MatcherPatternPathDynamic(
       /^\/users\/([^/]+)\/([^/]+)$/i,
       { userId: { ...PATH_PARAM_SINGLE_DEFAULT, repeat: true } },
-      ['users', 0]
+      ['users', 1]
     )
     expectTypeOf(matcher.match('/users/123/456')).toEqualTypeOf<{
       userId: string
@@ -57,7 +57,7 @@ describe('MatcherPatternPathDynamic', () => {
           // parser: PATH_PARAM_DEFAULT_PARSER,
         },
       },
-      ['profiles', 0]
+      ['profiles', 1]
     )
 
     expectTypeOf(matcher.match('/profiles/2')).toEqualTypeOf<{
index c797711aad5a9bdb2c724783134814bdb4c6ceef..f59086ef2d026fad8e3d3baa11395721043fa185 100644 (file)
@@ -137,7 +137,7 @@ export class MatcherPatternPathDynamic<
     // otherwise, we need to use a factory function: https://github.com/microsoft/TypeScript/issues/40451
     readonly params: TParamsOptions &
       Record<string, MatcherPatternPathDynamic_ParamOptions<any, any>>,
-    // 0 means a regular param, 1 means a splat, the order comes from the keys in params
+    // 1 means a regular param, 0 means a splat, the order comes from the keys in params
     readonly pathParts: Array<string | number | Array<string | number>>
   ) {
     this.paramsKeys = Object.keys(this.params) as Array<keyof TParamsOptions>
@@ -198,8 +198,8 @@ export class MatcherPatternPathDynamic<
 
             return Array.isArray(value)
               ? value.map(encodeParam).join('/')
-              : // part == 0 means a regular param, 1 means a splat
-                (part /* part !== 0 */ ? encodePath : encodeParam)(value)
+              : // part == 1 means a regular param, 0 means a splat
+                (part ? encodeParam : encodePath)(value)
           } else {
             return part
               .map(subPart => {
@@ -235,7 +235,9 @@ export class MatcherPatternPathDynamic<
      * with the original splat path: e.g. /teams/[...pathMatch] does not match /teams, so it makes
      * no sense to build a path it cannot match.
      */
-    return lastParamPart && !value ? path + '/' : path
+    return !lastParamPart /** lastParamPart == 0 */ && !value
+      ? path + '/'
+      : path
   }
 }
 
index c97bcd0d7e23f3c04dfa69764c6b7df911c13aa4..358e46e425be19da03fdeb44a60da12e5d269a71 100644 (file)
@@ -55,25 +55,25 @@ import { mockWarn } from '../../__tests__/vitest-mock-warn'
 const paramMatcher = new MatcherPatternPathDynamic(
   /^\/p\/([^/]+)$/,
   { p: {} },
-  ['p', 0]
+  ['p', 1]
 )
 
 const optionalMatcher = new MatcherPatternPathDynamic(
   /^\/optional(?:\/([^/]+))?$/,
   { p: {} },
-  ['optional', 0]
+  ['optional', 1]
 )
 
 const repeatMatcher = new MatcherPatternPathDynamic(
   /^\/repeat\/(.+)$/,
   { r: { repeat: true } },
-  ['repeat', 1]
+  ['repeat', 0]
 )
 
 const catchAllMatcher = new MatcherPatternPathDynamic(
   /^\/(.*)$/,
   { pathMatch: { repeat: true } },
-  [1]
+  [0]
 )
 
 // Create experimental route records using proper structure
@@ -380,7 +380,7 @@ describe('Experimental Router', () => {
     const testCatchAllMatcher = new MatcherPatternPathDynamic(
       /^\/(.*)$/,
       { pathMatch: { repeat: true } },
-      [1]
+      [0]
     )
     const catchAllRecord = normalizeRouteRecord({
       name: 'notfound',