// new MatcherPatternPathStatic('/team')
export interface Param_GetSet<
- TIn extends string | string[] | null | undefined =
- | string
- | string[]
- | null
- | undefined,
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 =
- | Param_GetSet<string, any>
- | Param_GetSet<string[], any>
+ | Param_GetSet<any, string>
+ | Param_GetSet<any, string[]>
// TODO: these are possible values for optional params
// | null | undefined
export function defineParamParser<TOut, TIn extends string | string[]>(parser: {
get?: (value: TIn) => TOut
set?: (value: TOut) => TIn
-}): Param_GetSet<TIn, TOut> {
+}): Param_GetSet<TOut, TIn> {
return parser
}
*/
export type ParamsFromParsers<P extends Record<string, ParamParser_Generic>> = {
- [K in keyof P]: P[K] extends Param_GetSet<infer TIn, infer TOut>
+ [K in keyof P]: P[K] extends Param_GetSet<infer TOut, infer TIn>
? unknown extends TOut // if any or unknown, use the value of TIn, which defaults to string | string[]
? TIn
: TOut
interface MatcherPatternPathCustomParamOptions<
TIn extends string | string[] | null = string | string[] | null,
TOut = string | string[] | null,
-> extends Param_GetSet<TIn, TOut> {
+> extends Param_GetSet<TOut, TIn> {
repeat?: boolean
// NOTE: not needed because in the regexp, the value is undefined if
// the group is optional and not given
const IS_INTEGER_RE = /^-?[1-9]\d*$/
-export const PARAM_INTEGER = {
+export const PARAM_INTEGER_SINGLE = {
get: (value: string) => {
if (IS_INTEGER_RE.test(value)) {
const num = Number(value)
throw miss()
},
set: (value: number) => String(value),
-} satisfies Param_GetSet<string, number>
+} satisfies Param_GetSet<number, string>
export const PARAM_NUMBER_OPTIONAL = {
get: (value: string | null) =>
- value == null ? null : PARAM_INTEGER.get(value),
+ value == null ? null : PARAM_INTEGER_SINGLE.get(value),
set: (value: number | null) =>
- value != null ? PARAM_INTEGER.set(value) : null,
-} satisfies Param_GetSet<string | null, number | null>
+ value != null ? PARAM_INTEGER_SINGLE.set(value) : null,
+} satisfies Param_GetSet<number | null, string | null>
export const PARAM_NUMBER_REPEATABLE = {
- get: (value: string[]) => value.map(PARAM_INTEGER.get),
- set: (value: number[]) => value.map(PARAM_INTEGER.set),
-} satisfies Param_GetSet<string[], number[]>
+ get: (value: string[]) => value.map(PARAM_INTEGER_SINGLE.get),
+ set: (value: number[]) => value.map(PARAM_INTEGER_SINGLE.set),
+} satisfies Param_GetSet<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 Param_GetSet<string[] | null, number[] | null>
+} satisfies Param_GetSet<number[] | null, string[] | null>
+
+/**
+ * Native Param parser for integers.
+ *
+ * @internal
+ */
+export const PARAM_PARSER_INTEGER: Param_GetSet<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<
TParamsOptions,