-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,
/^\/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 }) => {
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,
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()
},
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[]