From: Eduardo San Martin Morote Date: Thu, 7 Aug 2025 19:17:00 +0000 (+0200) Subject: chore: initial param parsers X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f0060326abd1ad56fdab3b45a7715e2310fc70e8;p=thirdparty%2Fvuejs%2Frouter.git chore: initial param parsers --- diff --git a/packages/experiments-playground/src/router/index.ts b/packages/experiments-playground/src/router/index.ts index c6461572..8e11bb1f 100644 --- a/packages/experiments-playground/src/router/index.ts +++ b/packages/experiments-playground/src/router/index.ts @@ -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\/(?[^/]+)$/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 }) => { diff --git a/packages/router/src/experimental/index.ts b/packages/router/src/experimental/index.ts index de1a58e8..ab6f1c6c 100644 --- a/packages/router/src/experimental/index.ts +++ b/packages/router/src/experimental/index.ts @@ -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, diff --git a/packages/router/src/experimental/route-resolver/matchers/matcher-pattern.ts b/packages/router/src/experimental/route-resolver/matchers/matcher-pattern.ts index 465f75fe..d239ac7f 100644 --- a/packages/router/src/experimental/route-resolver/matchers/matcher-pattern.ts +++ b/packages/router/src/experimental/route-resolver/matchers/matcher-pattern.ts @@ -202,11 +202,15 @@ interface MatcherPatternPathCustomParamOptions< parser?: Param_GetSet } -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 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 +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 + export class MatcherPatternPathCustomParams implements MatcherPatternPath { // private paramsKeys: string[]