]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
refactor: exports and rename MatcherPatternPathDynamic
authorEduardo San Martin Morote <posva13@gmail.com>
Sat, 16 Aug 2025 15:46:58 +0000 (17:46 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Sat, 16 Aug 2025 15:46:58 +0000 (17:46 +0200)
packages/router/src/experimental/index.ts
packages/router/src/experimental/route-resolver/matchers/matcher-pattern-path-star.ts [new file with mode: 0644]
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/route-resolver/matchers/param-parsers/index.ts [new file with mode: 0644]
packages/router/src/experimental/route-resolver/matchers/param-parsers/numbers.ts [new file with mode: 0644]
packages/router/src/experimental/route-resolver/matchers/param-parsers/types.ts [new file with mode: 0644]
packages/router/src/experimental/route-resolver/old/resolver-dynamic.spec.ts [deleted file]

index 7e1a0ff69d3027ac4613a768373805ad70d311a8..48a16279453e160ecf18d95efdaf74ccf3e189aa 100644 (file)
@@ -19,23 +19,26 @@ export type {
   MatcherQueryParamsValue,
 } from './route-resolver/resolver-abstract'
 export {
-  MatcherPatternPathDynamic,
   MatcherPatternPathStatic,
-  MatcherPatternPathStar,
-  MatcherPatternPathCustomParams,
-  // native param parsers
-  PARAM_PARSER_INT,
+  MatcherPatternPathDynamic,
 } from './route-resolver/matchers/matcher-pattern'
+
 export type {
+  EmptyParams,
   MatcherPattern,
   MatcherPatternHash,
   MatcherPatternPath,
   MatcherPatternQuery,
   MatcherParamsFormatted,
-  EmptyParams,
-  ParamParser,
+  MatcherPatternPathDynamic_ParamOptions,
 } from './route-resolver/matchers/matcher-pattern'
 
+export {
+  PARAM_PARSER_INT,
+  type ParamParser,
+  defineParamParser,
+} from './route-resolver/matchers/param-parsers'
+
 export { miss, MatchMiss } from './route-resolver/matchers/errors'
 
 // in the new experimental router, there are only parents
diff --git a/packages/router/src/experimental/route-resolver/matchers/matcher-pattern-path-star.ts b/packages/router/src/experimental/route-resolver/matchers/matcher-pattern-path-star.ts
new file mode 100644 (file)
index 0000000..7c28f7b
--- /dev/null
@@ -0,0 +1,38 @@
+import { miss } from './errors'
+import { MatcherPatternPath } from './matcher-pattern'
+
+/**
+ * Allows matching a static path folllowed by anything.
+ *
+ * @example
+ *
+ * ```ts
+ * const matcher = new MatcherPatternPathStar('/team')
+ * matcher.match('/team/123') // { pathMatch: '/123' }
+ * matcher.match('/team/123/more') // { pathMatch: '/123/more' }
+ * matcher.match('/team-123') // { pathMatch: '-123' }
+ * matcher.match('/team') // { pathMatch: '' }
+ * matcher.build({ pathMatch: '/123' }) // '/team/123'
+ * ```
+ */
+export class MatcherPatternPathStar
+  implements MatcherPatternPath<{ pathMatch: string }>
+{
+  private path: string
+  constructor(path: string = '') {
+    this.path = path.toLowerCase()
+  }
+
+  match(path: string): { pathMatch: string } {
+    if (!path.toLowerCase().startsWith(this.path)) {
+      throw miss()
+    }
+    return {
+      pathMatch: path.slice(this.path.length),
+    }
+  }
+
+  build(params: { pathMatch: string }): string {
+    return this.path + params.pathMatch
+  }
+}
index 74a8c3f692ba03b88afb61451be396b9bd5e28c3..2e4d491f3beac695f6c06efe80ea06727214f5d2 100644 (file)
@@ -1,9 +1,9 @@
 import { describe, expect, it } from 'vitest'
 import {
   MatcherPatternPathStatic,
-  MatcherPatternPathStar,
-  MatcherPatternPathCustomParams,
+  MatcherPatternPathDynamic,
 } from './matcher-pattern'
+import { MatcherPatternPathStar } from './matcher-pattern-path-star'
 
 describe('MatcherPatternPathStatic', () => {
   describe('match()', () => {
@@ -109,7 +109,7 @@ describe('MatcherPatternPathStar', () => {
 
 describe('MatcherPatternPathCustom', () => {
   it('single param', () => {
-    const pattern = new MatcherPatternPathCustomParams(
+    const pattern = new MatcherPatternPathDynamic(
       /^\/teams\/([^/]+?)\/b$/i,
       {
         // all defaults
@@ -131,7 +131,7 @@ describe('MatcherPatternPathCustom', () => {
   })
 
   it('decodes single param', () => {
-    const pattern = new MatcherPatternPathCustomParams(
+    const pattern = new MatcherPatternPathDynamic(
       /^\/teams\/([^/]+?)$/i,
       {
         teamId: {},
@@ -143,7 +143,7 @@ describe('MatcherPatternPathCustom', () => {
   })
 
   it('optional param', () => {
-    const pattern = new MatcherPatternPathCustomParams(
+    const pattern = new MatcherPatternPathDynamic(
       /^\/teams(?:\/([^/]+?))?\/b$/i,
       {
         teamId: {},
@@ -160,7 +160,7 @@ describe('MatcherPatternPathCustom', () => {
   })
 
   it('repeatable param', () => {
-    const pattern = new MatcherPatternPathCustomParams(
+    const pattern = new MatcherPatternPathDynamic(
       /^\/teams\/(.+?)\/b$/i,
       {
         teamId: { repeat: true },
@@ -179,7 +179,7 @@ describe('MatcherPatternPathCustom', () => {
   })
 
   it('repeatable optional param', () => {
-    const pattern = new MatcherPatternPathCustomParams(
+    const pattern = new MatcherPatternPathDynamic(
       /^\/teams(?:\/(.+?))?\/b$/i,
       {
         teamId: { repeat: true },
@@ -202,7 +202,7 @@ describe('MatcherPatternPathCustom', () => {
   })
 
   it('multiple params', () => {
-    const pattern = new MatcherPatternPathCustomParams(
+    const pattern = new MatcherPatternPathDynamic(
       /^\/teams\/([^/]+?)\/([^/]+?)$/i,
       {
         teamId: {},
@@ -224,7 +224,7 @@ describe('MatcherPatternPathCustom', () => {
   })
 
   it('sub segments (params + static)', () => {
-    const pattern = new MatcherPatternPathCustomParams(
+    const pattern = new MatcherPatternPathDynamic(
       /^\/teams\/([^/]+?)-b-([^/]+?)$/i,
       {
         teamId: {},
index d436153fb186895d37b5f900ab4b2995c6ef44b2..de39f16752b24cc0e8d46a25dbf7ddbcbcd07d77 100644 (file)
@@ -1,14 +1,12 @@
 import { describe, expectTypeOf, it } from 'vitest'
-import {
-  MatcherPatternPathCustomParams,
-  PARAM_INTEGER_SINGLE,
-  PATH_PARAM_DEFAULT_PARSER,
-  PATH_PARAM_SINGLE_DEFAULT,
-} from './matcher-pattern'
+import { MatcherPatternPathDynamic } from './matcher-pattern'
+import { PARAM_INTEGER_SINGLE } from './param-parsers/numbers'
+import { PATH_PARAM_DEFAULT_PARSER } from './param-parsers'
+import { PATH_PARAM_SINGLE_DEFAULT } from './param-parsers'
 
 describe('MatcherPatternPathCustomParams', () => {
   it('can be generic', () => {
-    const matcher = new MatcherPatternPathCustomParams(
+    const matcher = new MatcherPatternPathDynamic(
       /^\/users\/([^/]+)$/i,
       { userId: { ...PATH_PARAM_DEFAULT_PARSER } },
       ['users', 0]
@@ -33,7 +31,7 @@ describe('MatcherPatternPathCustomParams', () => {
   })
 
   it('can be a simple param', () => {
-    const matcher = new MatcherPatternPathCustomParams(
+    const matcher = new MatcherPatternPathDynamic(
       /^\/users\/([^/]+)\/([^/]+)$/i,
       { userId: { ...PATH_PARAM_SINGLE_DEFAULT, repeat: true } },
       ['users', 0]
@@ -51,7 +49,7 @@ describe('MatcherPatternPathCustomParams', () => {
   })
 
   it('can be a custom type', () => {
-    const matcher = new MatcherPatternPathCustomParams(
+    const matcher = new MatcherPatternPathDynamic(
       /^\/profiles\/([^/]+)$/i,
       {
         userId: {
index 901d7509910ffb67ec975480fd6b2917f8151349..73fe26ec222ec3fc23cfae5a5bcc3c83a224551f 100644 (file)
@@ -3,6 +3,7 @@ import { encodeParam } from '../../../encoding'
 import { warn } from '../../../warning'
 import { decode, MatcherQueryParams } from '../resolver-abstract'
 import { miss } from './errors'
+import { ParamParser } from './param-parsers/types'
 
 /**
  * Base interface for matcher patterns that extract params from a URL.
@@ -86,118 +87,9 @@ export class MatcherPatternPathStatic
 }
 
 /**
- * Allows matching a static path folllowed by anything.
- *
- * @example
- *
- * ```ts
- * const matcher = new MatcherPatternPathStar('/team')
- * matcher.match('/team/123') // { pathMatch: '/123' }
- * matcher.match('/team/123/more') // { pathMatch: '/123/more' }
- * matcher.match('/team-123') // { pathMatch: '-123' }
- * matcher.match('/team') // { pathMatch: '' }
- * matcher.build({ pathMatch: '/123' }) // '/team/123'
- * ```
+ * Options for param parsers in {@link MatcherPatternPathDynamic}.
  */
-export class MatcherPatternPathStar
-  implements MatcherPatternPath<{ pathMatch: string }>
-{
-  private path: string
-  constructor(path: string = '') {
-    this.path = path.toLowerCase()
-  }
-
-  match(path: string): { pathMatch: string } {
-    if (!path.toLowerCase().startsWith(this.path)) {
-      throw miss()
-    }
-    return {
-      pathMatch: path.slice(this.path.length),
-    }
-  }
-
-  build(params: { pathMatch: string }): string {
-    return this.path + params.pathMatch
-  }
-}
-
-// example of a static matcher built at runtime
-// new MatcherPatternPathStatic('/')
-// new MatcherPatternPathStatic('/team')
-
-export interface ParamParser<
-  TOut = string | string[] | null,
-  TIn extends string | string[] | null = string | string[] | null,
-> {
-  get?: (value: NoInfer<TIn>) => TOut
-  set?: (value: NoInfer<TOut>) => TIn
-}
-
-export type ParamParser_Generic =
-  | ParamParser<any, string>
-  | ParamParser<any, string[]>
-// TODO: these are possible values for optional params
-// | null | undefined
-
-/**
- * Type safe helper to define a param parser.
- *
- * @param parser - the parser to define. Will be returned as is.
- */
-/*! #__NO_SIDE_EFFECTS__ */
-export function defineParamParser<TOut, TIn extends string | string[]>(parser: {
-  get?: (value: TIn) => TOut
-  set?: (value: TOut) => TIn
-}): ParamParser<TOut, TIn> {
-  return parser
-}
-
-const PATH_PARAM_DEFAULT_GET = (value: string | string[] | null | undefined) =>
-  value ?? null
-export const PATH_PARAM_SINGLE_DEFAULT: ParamParser<string, string> = {}
-
-const PATH_PARAM_DEFAULT_SET = (value: string | string[] | null | undefined) =>
-  value && Array.isArray(value) ? value.map(String) : String(value)
-// TODO: `(value an null | undefined)` for types
-export const PATH_PARAM_DEFAULT_PARSER: ParamParser = {
-  get: PATH_PARAM_DEFAULT_GET,
-  set: PATH_PARAM_DEFAULT_SET,
-}
-
-/**
- * NOTE: I tried to make this generic and infer the types from the params but failed. This is what I tried:
- * ```ts
- * export type ParamsFromParsers<P extends Record<string, ParamParser_Generic>> = {
- *   [K in keyof P]: P[K] extends Param_GetSet<infer TIn, infer TOut>
- *     ? unknown extends TOut // if any or unknown, use the value of TIn, which defaults to string | string[]
- *       ? TIn
- *       : TOut
- *     : never
- * }
- *
- * export class MatcherPatternPathDynamic<
- *   ParamsParser extends Record<string, ParamParser_Generic>
- * > implements MatcherPatternPath<ParamsFromParsers<ParamsParser>>
- * {
- *   private params: Record<string, Required<ParamParser_Generic>> = {}
- *   constructor(
- *     private re: RegExp,
- *     params: ParamsParser,
- *     public build: (params: ParamsFromParsers<ParamsParser>) => string
- *     ) {}
- * ```
- * It ended up not working in one place or another. It could probably be fixed by
- */
-
-export type ParamsFromParsers<P extends Record<string, ParamParser_Generic>> = {
-  [K in keyof P]: P[K] extends ParamParser<infer TOut, infer TIn>
-    ? unknown extends TOut // if any or unknown, use the value of TIn, which defaults to string | string[]
-      ? TIn
-      : TOut
-    : never
-}
-
-interface MatcherPatternPathCustomParamOptions<
+export interface MatcherPatternPathDynamic_ParamOptions<
   TIn extends string | string[] | null = string | string[] | null,
   TOut = string | string[] | null,
 > extends ParamParser<TOut, TIn> {
@@ -212,7 +104,7 @@ interface MatcherPatternPathCustomParamOptions<
  * @internal
  */
 type ExtractParamTypeFromOptions<TParamsOptions> = {
-  [K in keyof TParamsOptions]: TParamsOptions[K] extends MatcherPatternPathCustomParamOptions<
+  [K in keyof TParamsOptions]: TParamsOptions[K] extends MatcherPatternPathDynamic_ParamOptions<
     any,
     infer TOut
   >
@@ -220,61 +112,10 @@ type ExtractParamTypeFromOptions<TParamsOptions> = {
     : never
 }
 
-const IS_INTEGER_RE = /^-?\d+$/
-
-export const PARAM_INTEGER_SINGLE = {
-  get: (value: string) => {
-    if (IS_INTEGER_RE.test(value)) {
-      const num = Number(value)
-      if (Number.isFinite(num)) {
-        return num
-      }
-    }
-    throw miss()
-  },
-  set: (value: number) => String(value),
-} satisfies ParamParser<number, string>
-
-export const PARAM_NUMBER_OPTIONAL = {
-  get: (value: string | null) =>
-    value == null ? null : PARAM_INTEGER_SINGLE.get(value),
-  set: (value: number | null) =>
-    value != null ? PARAM_INTEGER_SINGLE.set(value) : null,
-} satisfies ParamParser<number | null, string | null>
-
-export const PARAM_NUMBER_REPEATABLE = {
-  get: (value: string[]) => value.map(PARAM_INTEGER_SINGLE.get),
-  set: (value: number[]) => value.map(PARAM_INTEGER_SINGLE.set),
-} satisfies ParamParser<number[], string[]>
-
-export const PARAM_NUMBER_REPEATABLE_OPTIONAL = {
-  get: (value: string[] | null) =>
-    value == null ? null : PARAM_NUMBER_REPEATABLE.get(value),
-  set: (value: number[] | null) =>
-    value != null ? PARAM_NUMBER_REPEATABLE.set(value) : null,
-} satisfies ParamParser<number[] | null, string[] | null>
-
 /**
- * Native Param parser for integers.
- *
- * @internal
+ * Handles the `path` part of a URL with dynamic parameters.
  */
-export const PARAM_PARSER_INT: ParamParser<number | number[] | null> = {
-  get: value =>
-    Array.isArray(value)
-      ? PARAM_NUMBER_REPEATABLE.get(value)
-      : value != null
-        ? PARAM_INTEGER_SINGLE.get(value)
-        : null,
-  set: value =>
-    Array.isArray(value)
-      ? PARAM_NUMBER_REPEATABLE.set(value)
-      : value != null
-        ? PARAM_INTEGER_SINGLE.set(value)
-        : null,
-}
-
-export class MatcherPatternPathCustomParams<
+export class MatcherPatternPathDynamic<
   TParamsOptions,
   // TODO: | EmptyObject ?
   // TParamsOptions extends Record<string, MatcherPatternPathCustomParamOptions>,
@@ -292,7 +133,7 @@ export class MatcherPatternPathCustomParams<
     // to properly infer the types of the params when using `new MatcherPatternPathCustomParams()`
     // otherwise, we need to use a factory function: https://github.com/microsoft/TypeScript/issues/40451
     readonly params: TParamsOptions &
-      Record<string, MatcherPatternPathCustomParamOptions<any, any>>,
+      Record<string, MatcherPatternPathDynamic_ParamOptions<any, any>>,
     // A better version could be using all the parts to join them
     // .e.g ['users', 0, 'profile', 1] -> /users/123/profile/456
     // numbers are indexes of the params in the params object keys
@@ -376,83 +217,6 @@ export class MatcherPatternPathCustomParams<
   }
 }
 
-/**
- * Matcher for dynamic paths, e.g. `/team/:id/:name`.
- * Supports one, one or zero, one or more and zero or more params.
- */
-export class MatcherPatternPathDynamic<
-  TParams extends MatcherParamsFormatted = MatcherParamsFormatted,
-> implements MatcherPatternPath<TParams>
-{
-  private params: Record<string, Required<ParamParser_Generic>> = {}
-
-  constructor(
-    private re: RegExp,
-    params: Record<keyof TParams, ParamParser_Generic>,
-    public build: (params: TParams) => string,
-    private opts: { repeat?: boolean; optional?: boolean } = {}
-  ) {
-    for (const paramName in params) {
-      const param = params[paramName]
-      this.params[paramName] = {
-        get: param.get || PATH_PARAM_DEFAULT_GET,
-        // @ts-expect-error FIXME: should work
-        set: param.set || PATH_PARAM_DEFAULT_SET,
-      }
-    }
-  }
-
-  /**
-   * Match path against the pattern and return
-   *
-   * @param path - path to match
-   * @throws if the patch doesn't match
-   * @returns matched decoded params
-   */
-  match(path: string): TParams {
-    const match = path.match(this.re)
-    if (!match) {
-      throw miss()
-    }
-    let i = 1 // index in match array
-    const params = {} as TParams
-    for (const paramName in this.params) {
-      const currentParam = this.params[paramName]
-      const currentMatch = match[i++]
-      let value: string | null | string[] =
-        this.opts.optional && currentMatch == null ? null : currentMatch
-      value = this.opts.repeat && value ? value.split('/') : value
-
-      params[paramName as keyof typeof params] = currentParam.get(
-        // @ts-expect-error: FIXME: the type of currentParam['get'] is wrong
-        value && (Array.isArray(value) ? value.map(decode) : decode(value))
-      ) as (typeof params)[keyof typeof params]
-    }
-
-    if (__DEV__ && i !== match.length) {
-      warn(
-        `Regexp matched ${match.length} params, but ${i} params are defined. Found when matching "${path}" against ${String(this.re)}`
-      )
-    }
-    return params
-  }
-
-  // build(params: TParams): string {
-  //   let path = this.re.source
-  //   for (const param of this.params) {
-  //     const value = params[param.name as keyof TParams]
-  //     if (value == null) {
-  //       throw new Error(`Matcher build: missing param ${param.name}`)
-  //     }
-  //     path = path.replace(
-  //       /([^\\]|^)\([^?]*\)/,
-  //       `$1${encodeParam(param.set(value))}`
-  //     )
-  //   }
-  //   return path
-  // }
-}
-
 /**
  * Handles the `query` part of a URL. It can transform a query object into an
  * object of params and vice versa.
diff --git a/packages/router/src/experimental/route-resolver/matchers/param-parsers/index.ts b/packages/router/src/experimental/route-resolver/matchers/param-parsers/index.ts
new file mode 100644 (file)
index 0000000..166a87c
--- /dev/null
@@ -0,0 +1,33 @@
+import type { ParamParser } from './types'
+
+// TODO: these are possible values for optional params
+// | null | undefined
+/**
+ * Type safe helper to define a param parser.
+ *
+ * @param parser - the parser to define. Will be returned as is.
+ */
+/*! #__NO_SIDE_EFFECTS__ */
+
+export function defineParamParser<TOut, TIn extends string | string[]>(parser: {
+  get?: (value: TIn) => TOut
+  set?: (value: TOut) => TIn
+}): ParamParser<TOut, TIn> {
+  return parser
+}
+export const PATH_PARAM_DEFAULT_GET = (
+  value: string | string[] | null | undefined
+) => value ?? null
+export const PATH_PARAM_SINGLE_DEFAULT: ParamParser<string, string> = {}
+export const PATH_PARAM_DEFAULT_SET = (
+  value: string | string[] | null | undefined
+) => (value && Array.isArray(value) ? value.map(String) : String(value)) // TODO: `(value an null | undefined)` for types
+
+export const PATH_PARAM_DEFAULT_PARSER: ParamParser = {
+  get: PATH_PARAM_DEFAULT_GET,
+  set: PATH_PARAM_DEFAULT_SET,
+}
+
+export { ParamParser }
+
+export { PARAM_PARSER_INT } from './numbers'
diff --git a/packages/router/src/experimental/route-resolver/matchers/param-parsers/numbers.ts b/packages/router/src/experimental/route-resolver/matchers/param-parsers/numbers.ts
new file mode 100644 (file)
index 0000000..dabd952
--- /dev/null
@@ -0,0 +1,51 @@
+import { miss } from '../errors'
+import { ParamParser } from './types'
+
+export const PARAM_INTEGER_SINGLE = {
+  get: (value: string) => {
+    if (IS_INTEGER_RE.test(value)) {
+      const num = Number(value)
+      if (Number.isFinite(num)) {
+        return num
+      }
+    }
+    throw miss()
+  },
+  set: (value: number) => String(value),
+} satisfies ParamParser<number, string>
+export const IS_INTEGER_RE = /^-?\d+$/
+export const PARAM_NUMBER_OPTIONAL = {
+  get: (value: string | null) =>
+    value == null ? null : PARAM_INTEGER_SINGLE.get(value),
+  set: (value: number | null) =>
+    value != null ? PARAM_INTEGER_SINGLE.set(value) : null,
+} satisfies ParamParser<number | null, string | null>
+export const PARAM_NUMBER_REPEATABLE = {
+  get: (value: string[]) => value.map(PARAM_INTEGER_SINGLE.get),
+  set: (value: number[]) => value.map(PARAM_INTEGER_SINGLE.set),
+} satisfies ParamParser<number[], string[]>
+export const PARAM_NUMBER_REPEATABLE_OPTIONAL = {
+  get: (value: string[] | null) =>
+    value == null ? null : PARAM_NUMBER_REPEATABLE.get(value),
+  set: (value: number[] | null) =>
+    value != null ? PARAM_NUMBER_REPEATABLE.set(value) : null,
+} satisfies ParamParser<number[] | null, string[] | null> /**
+ * Native Param parser for integers.
+ *
+ * @internal
+ */
+
+export const PARAM_PARSER_INT: ParamParser<number | number[] | null> = {
+  get: value =>
+    Array.isArray(value)
+      ? PARAM_NUMBER_REPEATABLE.get(value)
+      : value != null
+        ? PARAM_INTEGER_SINGLE.get(value)
+        : null,
+  set: value =>
+    Array.isArray(value)
+      ? PARAM_NUMBER_REPEATABLE.set(value)
+      : value != null
+        ? PARAM_INTEGER_SINGLE.set(value)
+        : null,
+}
diff --git a/packages/router/src/experimental/route-resolver/matchers/param-parsers/types.ts b/packages/router/src/experimental/route-resolver/matchers/param-parsers/types.ts
new file mode 100644 (file)
index 0000000..c4b65d2
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * Defines a parser that can read a param from the url (string-based) and
+ * transform it into a more complex type, or vice versa.
+ *
+ * @see MatcherPattern
+ */
+export interface ParamParser<
+  TOut = string | string[] | null,
+  TIn extends string | string[] | null = string | string[] | null,
+> {
+  get?: (value: NoInfer<TIn>) => TOut
+  set?: (value: NoInfer<TOut>) => TIn
+}
+
+/**
+ * Generic type for a param parser that can handle both single and repeatable params.
+ *
+ * @see ParamParser
+ */
+export type ParamParser_Generic =
+  | ParamParser<any, string>
+  | ParamParser<any, string[]>
diff --git a/packages/router/src/experimental/route-resolver/old/resolver-dynamic.spec.ts b/packages/router/src/experimental/route-resolver/old/resolver-dynamic.spec.ts
deleted file mode 100644 (file)
index a1ebbde..0000000
+++ /dev/null
@@ -1,323 +0,0 @@
-import { describe, expect, it } from 'vitest'
-import { NO_MATCH_LOCATION, pathEncoded } from '../resolver-abstract'
-import { createCompiledMatcher } from './resolver-dynamic'
-import {
-  MatcherPatternQuery,
-  MatcherPatternPathStatic,
-  MatcherPatternPathDynamic,
-} from '../matchers/matcher-pattern'
-import {
-  EMPTY_PATH_ROUTE,
-  USER_ID_ROUTE,
-  ANY_PATH_ROUTE,
-  ANY_PATH_PATTERN_MATCHER,
-  EMPTY_PATH_PATTERN_MATCHER,
-  USER_ID_PATH_PATTERN_MATCHER,
-  ANY_HASH_PATTERN_MATCHER,
-} from '../matchers/test-utils'
-
-const PAGE_QUERY_PATTERN_MATCHER: MatcherPatternQuery<{ page: number }> = {
-  match: query => {
-    const page = Number(query.page)
-    return {
-      page: Number.isNaN(page) ? 1 : page,
-    }
-  },
-  build: params => ({ page: String(params.page) }),
-} satisfies MatcherPatternQuery<{ page: number }>
-
-describe('RouterMatcher', () => {
-  describe('new matchers', () => {
-    it('static path', () => {
-      const matcher = createCompiledMatcher([
-        { path: new MatcherPatternPathStatic('/'), score: [[80]] },
-        { path: new MatcherPatternPathStatic('/users'), score: [[80]] },
-      ])
-
-      expect(matcher.resolve({ path: '/' })).toMatchObject({
-        fullPath: '/',
-        path: '/',
-        params: {},
-        query: {},
-        hash: '',
-      })
-
-      expect(matcher.resolve({ path: '/users' })).toMatchObject({
-        fullPath: '/users',
-        path: '/users',
-        params: {},
-        query: {},
-        hash: '',
-      })
-    })
-
-    it('dynamic path', () => {
-      const matcher = createCompiledMatcher([
-        {
-          score: [[80], [70]],
-          path: new MatcherPatternPathDynamic<{ id: string }>(
-            /^\/users\/([^\/]+)$/,
-            {
-              id: {},
-            },
-            ({ id }) => pathEncoded`/users/${id}`
-          ),
-        },
-      ])
-
-      expect(matcher.resolve({ path: '/users/1' })).toMatchObject({
-        fullPath: '/users/1',
-        path: '/users/1',
-        params: { id: '1' },
-      })
-    })
-  })
-
-  describe('adding and removing', () => {
-    it('add static path', () => {
-      const matcher = createCompiledMatcher()
-      matcher.addMatcher(EMPTY_PATH_ROUTE)
-    })
-
-    it('adds dynamic path', () => {
-      const matcher = createCompiledMatcher()
-      matcher.addMatcher(USER_ID_ROUTE)
-    })
-
-    it('removes static path', () => {
-      const matcher = createCompiledMatcher()
-      matcher.addMatcher(EMPTY_PATH_ROUTE)
-      matcher.removeMatcher(EMPTY_PATH_ROUTE)
-      // Add assertions to verify the route was removed
-    })
-
-    it('removes dynamic path', () => {
-      const matcher = createCompiledMatcher()
-      matcher.addMatcher(USER_ID_ROUTE)
-      matcher.removeMatcher(USER_ID_ROUTE)
-      // Add assertions to verify the route was removed
-    })
-  })
-
-  describe('resolve()', () => {
-    describe.todo('absolute locations as strings', () => {
-      it('resolves string locations with no params', () => {
-        const matcher = createCompiledMatcher([EMPTY_PATH_ROUTE])
-
-        expect(matcher.resolve({ path: '/?a=a&b=b#h' })).toMatchObject({
-          path: '/',
-          params: {},
-          query: { a: 'a', b: 'b' },
-          hash: '#h',
-        })
-      })
-
-      it('resolves a not found string', () => {
-        const matcher = createCompiledMatcher()
-        expect(matcher.resolve({ path: '/bar?q=1#hash' })).toEqual({
-          ...NO_MATCH_LOCATION,
-          fullPath: '/bar?q=1#hash',
-          path: '/bar',
-          query: { q: '1' },
-          hash: '#hash',
-          matched: [],
-        })
-      })
-
-      it('resolves string locations with params', () => {
-        const matcher = createCompiledMatcher([USER_ID_ROUTE])
-
-        expect(matcher.resolve({ path: '/users/1?a=a&b=b#h' })).toMatchObject({
-          path: '/users/1',
-          params: { id: 1 },
-          query: { a: 'a', b: 'b' },
-          hash: '#h',
-        })
-        expect(matcher.resolve({ path: '/users/54?a=a&b=b#h' })).toMatchObject({
-          path: '/users/54',
-          params: { id: 54 },
-          query: { a: 'a', b: 'b' },
-          hash: '#h',
-        })
-      })
-
-      it('resolve string locations with query', () => {
-        const matcher = createCompiledMatcher([
-          {
-            path: ANY_PATH_PATTERN_MATCHER,
-            score: [[100, -10]],
-            query: PAGE_QUERY_PATTERN_MATCHER,
-          },
-        ])
-
-        expect(matcher.resolve({ path: '/foo?page=100&b=b#h' })).toMatchObject({
-          params: { page: 100 },
-          path: '/foo',
-          query: {
-            page: '100',
-            b: 'b',
-          },
-          hash: '#h',
-        })
-      })
-
-      it('resolves string locations with hash', () => {
-        const matcher = createCompiledMatcher([
-          {
-            score: [[100, -10]],
-            path: ANY_PATH_PATTERN_MATCHER,
-            hash: ANY_HASH_PATTERN_MATCHER,
-          },
-        ])
-
-        expect(matcher.resolve({ path: '/foo?a=a&b=b#bar' })).toMatchObject({
-          hash: '#bar',
-          params: { hash: 'bar' },
-          path: '/foo',
-          query: { a: 'a', b: 'b' },
-        })
-      })
-
-      it('combines path, query and hash params', () => {
-        const matcher = createCompiledMatcher([
-          {
-            score: [[200, 80], [72]],
-            path: USER_ID_PATH_PATTERN_MATCHER,
-            query: PAGE_QUERY_PATTERN_MATCHER,
-            hash: ANY_HASH_PATTERN_MATCHER,
-          },
-        ])
-
-        expect(
-          matcher.resolve({ path: '/users/24?page=100#bar' })
-        ).toMatchObject({
-          params: { id: 24, page: 100, hash: 'bar' },
-        })
-      })
-    })
-
-    describe('relative locations as strings', () => {
-      it('resolves a simple relative location', () => {
-        const matcher = createCompiledMatcher([
-          { path: ANY_PATH_PATTERN_MATCHER, score: [[-10]] },
-        ])
-
-        expect(
-          matcher.resolve(
-            { path: 'foo' },
-            matcher.resolve({ path: '/nested/' })
-          )
-        ).toMatchObject({
-          params: {},
-          path: '/nested/foo',
-          query: {},
-          hash: '',
-        })
-        expect(
-          matcher.resolve(
-            { path: '../foo' },
-            matcher.resolve({ path: '/nested/' })
-          )
-        ).toMatchObject({
-          params: {},
-          path: '/foo',
-          query: {},
-          hash: '',
-        })
-        expect(
-          matcher.resolve(
-            { path: './foo' },
-            matcher.resolve({ path: '/nested/' })
-          )
-        ).toMatchObject({
-          params: {},
-          path: '/nested/foo',
-          query: {},
-          hash: '',
-        })
-      })
-    })
-
-    describe('absolute locations as objects', () => {
-      it('resolves an object location', () => {
-        const matcher = createCompiledMatcher([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([
-          {
-            name: 'home',
-            path: EMPTY_PATH_PATTERN_MATCHER,
-            score: [[80]],
-          },
-        ])
-
-        expect(matcher.resolve({ name: 'home', params: {} })).toMatchObject({
-          name: 'home',
-          path: '/',
-          params: {},
-          query: {},
-          hash: '',
-        })
-      })
-    })
-
-    describe('encoding', () => {
-      const matcher = createCompiledMatcher([ANY_PATH_ROUTE])
-      describe('decodes', () => {
-        it('handles encoded string path', () => {
-          expect(matcher.resolve({ path: '/%23%2F%3F' })).toMatchObject({
-            fullPath: '/%23%2F%3F',
-            path: '/%23%2F%3F',
-            query: {},
-            params: {},
-            hash: '',
-          })
-        })
-
-        it('decodes query from a string', () => {
-          expect(matcher.resolve('/foo?foo=%23%2F%3F')).toMatchObject({
-            path: '/foo',
-            fullPath: '/foo?foo=%23%2F%3F',
-            query: { foo: '#/?' },
-          })
-        })
-
-        it('decodes hash from a string', () => {
-          expect(matcher.resolve('/foo#%22')).toMatchObject({
-            path: '/foo',
-            fullPath: '/foo#%22',
-            hash: '#"',
-          })
-        })
-      })
-
-      describe('encodes', () => {
-        it('encodes the query', () => {
-          expect(
-            matcher.resolve({ path: '/foo', query: { foo: '"' } })
-          ).toMatchObject({
-            fullPath: '/foo?foo=%22',
-            query: { foo: '"' },
-          })
-        })
-
-        it('encodes the hash', () => {
-          expect(matcher.resolve({ path: '/foo', hash: '#"' })).toMatchObject({
-            fullPath: '/foo#%22',
-            hash: '#"',
-          })
-        })
-      })
-    })
-  })
-})