]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
chore: initial param parsers
authorEduardo San Martin Morote <posva13@gmail.com>
Thu, 7 Aug 2025 19:17:00 +0000 (21:17 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Thu, 7 Aug 2025 19:17:00 +0000 (21:17 +0200)
packages/experiments-playground/src/router/index.ts
packages/router/src/experimental/index.ts
packages/router/src/experimental/route-resolver/matchers/matcher-pattern.ts

index c646157268fcdb8f83c37400f80d069f7ac33dba..8e11bb1f8509782b5ce80876bfab3f4d4f899cc6 100644 (file)
@@ -1,10 +1,12 @@
-import { createWebHistory, type RouteParamValue } from 'vue-router'
+import { createWebHistory } from 'vue-router'
 import {
   experimental_createRouter,
   createStaticResolver,
   MatcherPatternPathStatic,
+  MatcherPatternPathStar,
   MatcherPatternPathCustomParams,
   normalizeRouteRecord,
+  PARAM_INTEGER,
 } from 'vue-router/experimental'
 import type {
   EXPERIMENTAL_RouteRecordNormalized_Matchable,
@@ -143,12 +145,8 @@ const r_profiles_detail = normalizeRouteRecord({
     /^\/profiles\/(?<userId>[^/]+)$/i,
     {
       userId: {
-        parser: {
-          // @ts-expect-error: FIXME: should would with generic class
-          get: (value: string): number => Number(value),
-          // @ts-expect-error: FIXME: should would with generic class
-          set: (value: number): string => String(value),
-        },
+        // @ts-expect-error: FIXME: should allow the type
+        parser: PARAM_INTEGER,
       },
     },
     ({ userId }) => {
index de1a58e8d9ddfdd4be5138c3096d3796228730e1..ab6f1c6ce0488b9cb34256005e73c36963f6583d 100644 (file)
@@ -23,6 +23,12 @@ export {
   MatcherPatternPathStatic,
   MatcherPatternPathStar,
   MatcherPatternPathCustomParams,
+  // custom param parsers
+  // TODO: find a more elegant format than having 4 variants per param type
+  PARAM_INTEGER,
+  PARAM_NUMBER_OPTIONAL,
+  PARAM_NUMBER_REPEATABLE,
+  PARAM_NUMBER_REPEATABLE_OPTIONAL,
 } from './route-resolver/matchers/matcher-pattern'
 export type {
   MatcherPattern,
index 465f75fe5eb11215dffa69603520ee4c350baf6a..d239ac7ffdae5c27e83755d89ab235c07757fec6 100644 (file)
@@ -202,11 +202,15 @@ interface MatcherPatternPathCustomParamOptions<
   parser?: Param_GetSet<TIn, TOut>
 }
 
-export const PARAM_NUMBER = {
+const IS_INTEGER_RE = /^-?[1-9]\d*$/
+
+export const PARAM_INTEGER = {
   get: (value: string) => {
-    const num = Number(value)
-    if (Number.isFinite(num)) {
-      return num
+    if (IS_INTEGER_RE.test(value)) {
+      const num = Number(value)
+      if (Number.isFinite(num)) {
+        return num
+      }
     }
     throw miss()
   },
@@ -215,16 +219,23 @@ export const PARAM_NUMBER = {
 
 export const PARAM_NUMBER_OPTIONAL = {
   get: (value: string | null) =>
-    value == null ? null : PARAM_NUMBER.get(value),
+    value == null ? null : PARAM_INTEGER.get(value),
   set: (value: number | null) =>
-    value != null ? PARAM_NUMBER.set(value) : null,
+    value != null ? PARAM_INTEGER.set(value) : null,
 } satisfies Param_GetSet<string | null, number | null>
 
 export const PARAM_NUMBER_REPEATABLE = {
-  get: (value: string[]) => value.map(PARAM_NUMBER.get),
-  set: (value: number[]) => value.map(PARAM_NUMBER.set),
+  get: (value: string[]) => value.map(PARAM_INTEGER.get),
+  set: (value: number[]) => value.map(PARAM_INTEGER.set),
 } satisfies Param_GetSet<string[], number[]>
 
+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 Param_GetSet<string[] | null, number[] | null>
+
 export class MatcherPatternPathCustomParams implements MatcherPatternPath {
   // private paramsKeys: string[]