]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
refactor: add methods needed by router
authorEduardo San Martin Morote <posva13@gmail.com>
Tue, 10 Dec 2024 13:41:31 +0000 (14:41 +0100)
committerEduardo San Martin Morote <posva13@gmail.com>
Tue, 10 Dec 2024 13:41:31 +0000 (14:41 +0100)
packages/router/src/new-route-resolver/matcher-location.ts
packages/router/src/new-route-resolver/matcher.spec.ts
packages/router/src/new-route-resolver/matcher.test-d.ts
packages/router/src/new-route-resolver/matcher.ts

index 3744e8cececd1687aff23b4a0418feaeeba9927d..b9ca1ab0cc2948f9fe37163b3123e9a463525cf4 100644 (file)
@@ -19,25 +19,41 @@ export interface MatcherLocationAsNamed {
   hash?: string
 
   /**
-   * A path is ignored if `name` is provided.
+   * @deprecated This is ignored when `name` is provided
    */
   path?: undefined
 }
 
-export interface MatcherLocationAsPath {
+export interface MatcherLocationAsPathRelative {
   path: string
   query?: LocationQueryRaw
   hash?: string
 
+  /**
+   * @deprecated This is ignored when `path` is provided
+   */
   name?: undefined
+  /**
+   * @deprecated This is ignored when `path` (instead of `name`) is provided
+   */
   params?: undefined
 }
+export interface MatcherLocationAsPathAbsolute
+  extends MatcherLocationAsPathRelative {
+  path: `/${string}`
+}
 
 export interface MatcherLocationAsRelative {
   params?: MatcherParamsFormatted
   query?: LocationQueryRaw
   hash?: string
 
+  /**
+   * @deprecated This location is relative to the next parameter. This `name` will be ignored.
+   */
   name?: undefined
+  /**
+   * @deprecated This location is relative to the next parameter. This `path` will be ignored.
+   */
   path?: undefined
 }
index 15ca09f832d1aa1d1d7060714e670f624bd56a5a..c15561f53db0712d76fd1a76e894803d2006a788 100644 (file)
@@ -209,6 +209,20 @@ describe('Matcher', () => {
       })
     })
 
+    describe('absolute locations as objects', () => {
+      it('resolves an object location', () => {
+        const matcher = createCompiledMatcher()
+        matcher.addRoute(EMPTY_PATH_ROUTE)
+        expect(matcher.resolve({ path: '/' })).toMatchObject({
+          fullPath: '/',
+          path: '/',
+          params: {},
+          query: {},
+          hash: '',
+        })
+      })
+    })
+
     describe('named locations', () => {
       it('resolves named locations with no params', () => {
         const matcher = createCompiledMatcher()
index c50731a1e43b8e94434740329b45c10a08edc330..a60874518a3812312d901fb6e776bd27234d2d64 100644 (file)
@@ -39,4 +39,16 @@ describe('Matcher', () => {
       ).toEqualTypeOf<NEW_LocationResolved>()
     })
   })
+
+  it('does not allow a name + path', () => {
+    matcher.resolve({
+      // ...({} as NEW_LocationResolved),
+      name: 'foo',
+      params: {},
+      // @ts-expect-error: name + path
+      path: '/e',
+    })
+    // @ts-expect-error: name + currentLocation
+    matcher.resolve({ name: 'a', params: {} }, {} as NEW_LocationResolved)
+  })
 })
index 26805ddaf053c37e8adec4aa6e53e4dbd137a59a..f9fa1c6f83253c07cb41519437fdba56b93f1093 100644 (file)
@@ -15,6 +15,8 @@ import { encodeQueryValue as _encodeQueryValue } from '../encoding'
 import { parseURL, stringifyURL } from '../location'
 import type {
   MatcherLocationAsNamed,
+  MatcherLocationAsPathAbsolute,
+  MatcherLocationAsPathRelative,
   MatcherLocationAsRelative,
   MatcherParamsFormatted,
 } from './matcher-location'
@@ -48,10 +50,16 @@ export interface RouteResolver<Matcher, MatcherNormalized> {
   resolve(location: MatcherLocationAsNamed): NEW_LocationResolved
 
   /**
-   * Resolves a location by its path. Any required query must be passed.
+   * Resolves a location by its absolute path (starts with `/`). Any required query must be passed.
    * @param location - The location to resolve.
    */
-  // resolve(location: MatcherLocationAsPath): NEW_MatcherLocationResolved
+  resolve(location: MatcherLocationAsPathAbsolute): NEW_LocationResolved
+
+  resolve(
+    location: MatcherLocationAsPathRelative,
+    currentLocation: NEW_LocationResolved
+  ): NEW_LocationResolved
+
   // NOTE: in practice, this overload can cause bugs. It's better to use named locations
 
   /**
@@ -66,11 +74,28 @@ export interface RouteResolver<Matcher, MatcherNormalized> {
   addRoute(matcher: Matcher, parent?: MatcherNormalized): MatcherNormalized
   removeRoute(matcher: MatcherNormalized): void
   clearRoutes(): void
+
+  /**
+   * Get a list of all matchers.
+   * Previously named `getRoutes()`
+   */
+  getMatchers(): MatcherNormalized[]
+
+  /**
+   * Get a matcher by its name.
+   * Previously named `getRecordMatcher()`
+   */
+  getMatcher(name: MatcherName): MatcherNormalized | undefined
 }
 
 type MatcherResolveArgs =
   | [absoluteLocation: `/${string}`]
   | [relativeLocation: string, currentLocation: NEW_LocationResolved]
+  | [absoluteLocation: MatcherLocationAsPathAbsolute]
+  | [
+      relativeLocation: MatcherLocationAsPathRelative,
+      currentLocation: NEW_LocationResolved
+    ]
   | [location: MatcherLocationAsNamed]
   | [
       relativeLocation: MatcherLocationAsRelative,
@@ -224,6 +249,7 @@ export function createCompiledMatcher(): RouteResolver<
   MatcherRecordRaw,
   MatcherPattern
 > {
+  // TODO: we also need an array that has the correct order
   const matchers = new Map<MatcherName, MatcherPattern>()
 
   // TODO: allow custom encode/decode functions
@@ -241,6 +267,7 @@ export function createCompiledMatcher(): RouteResolver<
 
     // string location, e.g. '/foo', '../bar', 'baz', '?page=1'
     if (typeof location === 'string') {
+      // parseURL handles relative paths
       const url = parseURL(parseQuery, location, currentLocation?.path)
 
       let matcher: MatcherPattern | undefined
@@ -266,7 +293,6 @@ export function createCompiledMatcher(): RouteResolver<
           // }
 
           parsedParams = { ...pathParams, ...queryParams, ...hashParams }
-          // console.log('parsedParams', parsedParams)
 
           if (parsedParams) break
         } catch (e) {
@@ -296,6 +322,7 @@ export function createCompiledMatcher(): RouteResolver<
         hash: url.hash,
         matched,
       }
+      // TODO: handle object location { path, query, hash }
     } else {
       // relative location or by name
       if (__DEV__ && location.name == null && currentLocation == null) {
@@ -368,11 +395,21 @@ export function createCompiledMatcher(): RouteResolver<
     matchers.clear()
   }
 
+  function getMatchers() {
+    return Array.from(matchers.values())
+  }
+
+  function getMatcher(name: MatcherName) {
+    return matchers.get(name)
+  }
+
   return {
     resolve,
 
     addRoute,
     removeRoute,
     clearRoutes,
+    getMatcher,
+    getMatchers,
   }
 }