From: Eduardo San Martin Morote Date: Wed, 20 Aug 2025 09:39:25 +0000 (+0200) Subject: refactor: adapt param parser types to work with queries X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b876b4a7574f222ebecc2c1babb76c00a59c2f76;p=thirdparty%2Fvuejs%2Frouter.git refactor: adapt param parser types to work with queries --- diff --git a/packages/router/src/experimental/route-resolver/matchers/matcher-pattern.test-d.ts b/packages/router/src/experimental/route-resolver/matchers/matcher-pattern.test-d.ts index de39f167..02f1c642 100644 --- a/packages/router/src/experimental/route-resolver/matchers/matcher-pattern.test-d.ts +++ b/packages/router/src/experimental/route-resolver/matchers/matcher-pattern.test-d.ts @@ -1,14 +1,14 @@ import { describe, expectTypeOf, it } from 'vitest' import { MatcherPatternPathDynamic } from './matcher-pattern' import { PARAM_INTEGER_SINGLE } from './param-parsers/numbers' -import { PATH_PARAM_DEFAULT_PARSER } from './param-parsers' +import { PATH_PARAM_PARSER_DEFAULTS } from './param-parsers' import { PATH_PARAM_SINGLE_DEFAULT } from './param-parsers' describe('MatcherPatternPathCustomParams', () => { it('can be generic', () => { const matcher = new MatcherPatternPathDynamic( /^\/users\/([^/]+)$/i, - { userId: { ...PATH_PARAM_DEFAULT_PARSER } }, + { userId: { ...PATH_PARAM_PARSER_DEFAULTS } }, ['users', 0] ) 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 index 89d4fcb4..d7eadc3b 100644 --- a/packages/router/src/experimental/route-resolver/matchers/param-parsers/index.ts +++ b/packages/router/src/experimental/route-resolver/matchers/param-parsers/index.ts @@ -13,19 +13,31 @@ export function defineParamParser(parser: { return parser } -export const PATH_PARAM_DEFAULT_GET = ( - value: string | string[] | null | undefined -) => value ?? null -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_SINGLE_DEFAULT: ParamParser = {} -export const PATH_PARAM_DEFAULT_PARSER = { - get: PATH_PARAM_DEFAULT_GET, - set: PATH_PARAM_DEFAULT_SET, + +/** + * Default parser for params that will keep values as is, and will use `String()` + */ +export const PARAM_PARSER_DEFAULTS = { + get: value => value ?? null, + set: value => + value == null + ? null + : Array.isArray(value) + ? value.map(v => (v == null ? null : String(v))) + : String(value), } satisfies ParamParser +export const PATH_PARAM_PARSER_DEFAULTS = { + get: value => value ?? null, + set: value => + value == null + ? null + : Array.isArray(value) + ? value.map(String) + : String(value), +} satisfies ParamParser + export type { 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 index 3fe9fa1f..1386b1a5 100644 --- a/packages/router/src/experimental/route-resolver/matchers/param-parsers/numbers.ts +++ b/packages/router/src/experimental/route-resolver/matchers/param-parsers/numbers.ts @@ -2,7 +2,7 @@ import { miss } from '../errors' import { ParamParser } from './types' export const PARAM_INTEGER_SINGLE = { - get: (value: string) => { + get: (value: string | null) => { const num = Number(value) if (value && Number.isInteger(num)) { return num @@ -10,7 +10,7 @@ export const PARAM_INTEGER_SINGLE = { throw miss() }, set: (value: number) => String(value), -} satisfies ParamParser +} satisfies ParamParser export const PARAM_INTEGER_OPTIONAL = { get: (value: string | null) => @@ -20,9 +20,9 @@ export const PARAM_INTEGER_OPTIONAL = { } satisfies ParamParser export const PARAM_INTEGER_REPEATABLE = { - get: (value: string[]) => value.map(PARAM_INTEGER_SINGLE.get), + get: (value: (string | null)[]) => value.map(PARAM_INTEGER_SINGLE.get), set: (value: number[]) => value.map(PARAM_INTEGER_SINGLE.set), -} satisfies ParamParser +} satisfies ParamParser export const PARAM_INTEGER_REPEATABLE_OPTIONAL = { get: (value: string[] | 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 index c4b65d27..59aea004 100644 --- a/packages/router/src/experimental/route-resolver/matchers/param-parsers/types.ts +++ b/packages/router/src/experimental/route-resolver/matchers/param-parsers/types.ts @@ -1,3 +1,5 @@ +import { MatcherQueryParamsValue } from '../matcher-pattern' + /** * Defines a parser that can read a param from the url (string-based) and * transform it into a more complex type, or vice versa. @@ -5,13 +7,17 @@ * @see MatcherPattern */ export interface ParamParser< - TOut = string | string[] | null, - TIn extends string | string[] | null = string | string[] | null, + TOut = MatcherQueryParamsValue, + TIn extends MatcherQueryParamsValue = MatcherQueryParamsValue, > { get?: (value: NoInfer) => TOut set?: (value: NoInfer) => TIn } +// TODO: I wonder if native param parsers should follow this or similar +// these parsers can be used for both query and path params +// export type ParamParserBoth = ParamParser + /** * Generic type for a param parser that can handle both single and repeatable params. *