} from './types'
export type {
ParamsFromPath,
- _ExtractFirstParamName,
- _RemoveRegexpFromParam,
+ ParamsRawFromPath,
+ _StripRegex,
_RemoveUntilClosingPar,
+ _ExtractParamsOfPath,
+ _ParamExtractResult,
+ _ExtractModifier,
+ _ModifierExtracTResult,
_JoinPath,
_ParamDelimiter,
_ParamModifier,
RouteRecordRaw,
RouteRecordName,
} from '.'
-import type {
- _JoinPath,
- ParamsFromPath,
- ParamsRawFromPath,
- PathFromParams,
-} from './paths'
-import { LiteralUnion } from './utils'
+import type { _JoinPath, ParamsFromPath, ParamsRawFromPath } from './paths'
/**
* Creates a map with each named route as a properties. Each property contains the type of the params in raw and
| _ParamModifier
/**
- * Given a simple path, creates an object of the possible param values.
- *
- * @internal
- */
-export type _ExtractParamsPath<
- P extends string,
- isRaw extends boolean
-> = P extends `${string}{${infer PP}}${infer Rest}`
- ? (PP extends `${infer N}${_ParamModifier}`
- ? PP extends `${N}${infer M}`
- ? M extends _ParamModifier
- ? _ParamToObject<N, M, isRaw>
- : never
- : never
- : _ParamToObject<PP, '', isRaw>) &
- _ExtractParamsPath<Rest, isRaw>
- : {}
-
-/**
- * Given a path, extracts the possible params or {} when there are no params.
+ * Given a path, extracts the possible params or \{\} when there are no params.
*
* @internal
*/
>
? _ParamToObject<ParamName, Modifier, isRaw> &
_ExtractParamsOfPath<Rest2, isRaw>
- : {
- NO: 1 // this should never happen as the modifier can be empty
- }
+ : never // this should never happen as the modifier can be empty
: // Nothing after the param: /:id, we are done
_ParamToObject<HasParam, '', isRaw>
: {
// EMPTY: 1
}
-type a1 = _ExtractParamsOfPath<'/', false>
-type a2 = _ExtractParamsOfPath<'/:id', false>
-type a3 = _ExtractParamsOfPath<'/:id/:b', false>
-type a4 = _ExtractParamsOfPath<'/:id(.*)', false>
-type a5 = _ExtractParamsOfPath<'/:id(.*)/other', false>
-type a6 = _ExtractParamsOfPath<'/:id(.*)+', false>
-type a7 = _ExtractParamsOfPath<'/:id(.*)+/other', false>
-type a8 = _ExtractParamsOfPath<'/:id(.*)+/other/:b/:c/:d', false>
-
-type test1 =
- '/:id/:b' extends `${string}:${infer P}${_ParamDelimiter}${infer Rest}`
- ? [P, Rest]
- : never
-
/**
* Helper type to infer a param name extraction result
* @internal
*/
-interface _ParamExtractResult<P extends string, Rest extends string> {
+export interface _ParamExtractResult<P extends string, Rest extends string> {
param: P
rest: Rest
}
: // add the rest to the end after a % which is invalid in a path so it can be used as a delimiter
_ParamExtractResult<Head, Tail>
-type p1 = _ExtractParamName<'id'>
-type p2 = _ExtractParamName<'abc+/dos'>
-type p3 = _ExtractParamName<'abc/:dos)'>
-
/**
* We consider a what comes after a param, e.g. For `/:id(\\d+)+/edit`, it would be `(\\d+)+/edit`. This should output
* everything after the regex while handling escaped `)`: `+/edit`. Note this type should be used with a string that
: // nothing to remove
S
-const a = '/:id(\\d+)+/edit/:more(.*)' as '/:id+/edit/:more'
-
-type r1 = _StripRegex<'(\\d+)+/edit/'>
-type r3 = _StripRegex<'(.*)*'>
-type r4 = _StripRegex<'?/rest'>
-type r5 = _StripRegex<'*'>
-type r6 = _StripRegex<'-other-stuff'>
-type r7 = _StripRegex<'/edit'>
-
-// type r8 = _StripRegex<'?/rest/:other(.*)'>
-// type r9 = _StripRegex<'(\\d+)+/edit/:other(.*)*'>
-// type r10 = _StripRegex<'?/rest/:other(.*)/more/:b(.*)'>
-
/**
* Helper type to infer a modifier extraction result.
*
: // No modifier present
_ModifierExtracTResult<'', P>
-type m1 = _ExtractModifier<''>
-type m2 = _ExtractModifier<'-rest'>
-type m3 = _ExtractModifier<'edit'>
-type m4 = _ExtractModifier<'+'>
-type m5 = _ExtractModifier<'+/edit'>
-
/**
* Gets the possible type of a param based on its modifier M.
*
S extends `${infer A}\\)${infer Rest}`
? // the actual regexp finished before, A has no escaped )
A extends `${string})${infer Rest2}`
- ? Rest2 extends `${_ParamModifier}${infer Rest3}`
- ? Rest2 extends `${infer M}${Rest3}`
- ? `${M}}${Rest3}\\)${Rest}`
- : never
- : `}${Rest2}\\)${Rest}` // job done
+ ? `${Rest2}\\)${Rest}` // job done
: _RemoveUntilClosingPar<Rest> // we keep removing
: S extends `${string})${infer Rest}`
- ? Rest extends `${_ParamModifier}${infer Rest2}`
- ? Rest extends `${infer M}${Rest2}`
- ? `${M}}${Rest2}`
- : never
- : `}${Rest}`
+ ? Rest
: never // nothing to remove, should not have been called, easier to spot bugs
-type r = _RemoveUntilClosingPar<`aouest)/end`>
-type r2 = _RemoveUntilClosingPar<`aouest`>
-
-/**
- * Reformats a path string `/:id(custom-regex)/:other+` by wrapping params with
- * `{}` and removing custom regexps to make them easier to parse.
- *
- * @internal
- */
-export type _RemoveRegexpFromParam<S extends string> =
- S extends `${infer A}:${infer P}${_ParamDelimiter}${infer Rest}`
- ? P extends _ExtractFirstParamName<P>
- ? S extends `${A}:${P}${infer D}${Rest}`
- ? D extends _ParamModifier | ''
- ? `${A}{${P}${D}}${S extends `${A}:${P}${D}${infer Rest2}` // we need to infer again...
- ? _RemoveRegexpFromParam<Rest2>
- : never}`
- : D extends _ParamDelimiter
- ? '(' extends D
- ? `${A}{${P}${S extends `${A}:${P}(${infer Rest2}` // we need to infer again to include D
- ? _RemoveRegexpFromParam<_RemoveUntilClosingPar<Rest2>>
- : '}'}`
- : `${A}{${P}}${S extends `${A}:${P}${infer Rest2}` // we need to infer again to include D
- ? _RemoveRegexpFromParam<Rest2>
- : never}`
- : never
- : never
- : never
- : S extends `${infer A}:${infer P}`
- ? P extends _ExtractFirstParamName<P>
- ? `${A}{${P}}`
- : never
- : S
-
-/**
- * Extract the first param name (after a `:`) and ignores the rest.
- *
- * @internal
- */
-export type _ExtractFirstParamName<S extends string> =
- S extends `${infer P}${_ParamDelimiter}${string}`
- ? _ExtractFirstParamName<P>
- : S extends `${string}${_ParamDelimiter}${string}`
- ? never
- : S
-
/**
* Joins a prefix and a path putting a `/` between them when necessary
*
import type {
ParamsFromPath,
- _ExtractFirstParamName,
- _RemoveRegexpFromParam,
+ _StripRegex,
+ _ExtractParamsOfPath,
_RemoveUntilClosingPar,
+ _ExtractModifier,
+ _ModifierExtracTResult,
} from './'
import { expectType } from './'
}
// simple
-expectType<{}>(params('/static'))
+expectType<Record<any, never>>(params('/static'))
expectType<{ id: string }>(params('/users/:id'))
// simulate a part of the string unknown at compilation time
expectType<{ id: string }>(params(`/${encodeURI('')}/:id`))
expectType<{ date: string }>(params('/users/:date(\\d{4}-\\d{2}-\\d{2})'))
expectType<{ a: string }>(params('/:a(pre-(?:\\d{0,5}\\)-end)'))
+expectType<{
+ id: readonly [string, ...string[]]
+ b: string
+ c: string
+ d: string
+}>(params('/:id(.*)+/other/:b/:c/:d'))
+
// special characters
expectType<{ id: string }>(params('/:id$thing'))
expectType<{ id: string }>(params('/:id&thing'))
return '' as any
}
-expectType<'}'>(removeUntilClosingPar(')'))
-expectType<'+}'>(removeUntilClosingPar(')+'))
-expectType<'}more'>(removeUntilClosingPar(')more'))
-expectType<'}'>(removeUntilClosingPar('\\w+)'))
-expectType<'}/more-url'>(removeUntilClosingPar('\\w+)/more-url'))
-expectType<'}/:p'>(removeUntilClosingPar('\\w+)/:p'))
-expectType<'+}'>(removeUntilClosingPar('oe)+'))
-expectType<'}/:p(o)'>(removeUntilClosingPar('\\w+)/:p(o)'))
-expectType<'}/:p(o)'>(removeUntilClosingPar('(?:no\\)?-end)/:p(o)'))
-expectType<'}/:p(o(?:no\\)?-end)'>(
+expectType<''>(removeUntilClosingPar(')'))
+expectType<'+'>(removeUntilClosingPar(')+'))
+expectType<'more'>(removeUntilClosingPar(')more'))
+expectType<''>(removeUntilClosingPar('\\w+)'))
+expectType<'/more-url'>(removeUntilClosingPar('\\w+)/more-url'))
+expectType<'/:p'>(removeUntilClosingPar('\\w+)/:p'))
+expectType<'+'>(removeUntilClosingPar('oe)+'))
+expectType<'/:p(o)'>(removeUntilClosingPar('\\w+)/:p(o)'))
+expectType<'/:p(o)'>(removeUntilClosingPar('(?:no\\)?-end)/:p(o)'))
+expectType<'/:p(o(?:no\\)?-end)'>(
removeUntilClosingPar('-end)/:p(o(?:no\\)?-end)')
)
-expectType<'}:new(eg)other'>(removeUntilClosingPar('customr):new(eg)other'))
-expectType<'}:new(eg)+other'>(removeUntilClosingPar('customr):new(eg)+other'))
-expectType<'}/:new(eg)+other'>(removeUntilClosingPar('customr)/:new(eg)+other'))
-expectType<'?}/:new(eg)+other'>(
+expectType<':new(eg)other'>(removeUntilClosingPar('customr):new(eg)other'))
+expectType<':new(eg)+other'>(removeUntilClosingPar('customr):new(eg)+other'))
+expectType<'/:new(eg)+other'>(removeUntilClosingPar('customr)/:new(eg)+other'))
+expectType<'?/:new(eg)+other'>(
removeUntilClosingPar('customr)?/:new(eg)+other')
)
-function removeRegexp<S extends string>(_s: S): _RemoveRegexpFromParam<S> {
+
+function stripRegex<S extends string>(_s: S): _StripRegex<S> {
return '' as any
}
-expectType<'/{id?}/{b}'>(removeRegexp('/:id(aue(ee{2,3}\\))?/:b(hey)'))
-expectType<'/{id+}/b'>(removeRegexp('/:id+/b'))
-expectType<'/{id}'>(removeRegexp('/:id'))
-expectType<'/{id+}'>(removeRegexp('/:id+'))
-expectType<'+}'>(removeRegexp('+}'))
-expectType<'/{id+}'>(removeRegexp('/:id(e)+'))
-expectType<'/{id}/b'>(removeRegexp('/:id/b'))
-expectType<'/{id}/{b}'>(removeRegexp('/:id/:b'))
-expectType<'/users/{id}/{b}'>(removeRegexp('/users/:id/:b'))
-expectType<'/{id?}/{b+}'>(removeRegexp('/:id?/:b+'))
-expectType<'/{id?}/{b+}'>(removeRegexp('/:id(aue(ee{2,3}\\))?/:b+'))
-
-function extractParamName<S extends string>(_s: S): _ExtractFirstParamName<S> {
- return '' as any
+const a = '/:id(\\d+)+/edit/:more(.*)' as '/:id+/edit/:more'
+
+expectType<'+/edit/'>(stripRegex('(\\d+)+/edit/'))
+expectType<'*'>(stripRegex('(.*)*'))
+expectType<'?/rest'>(stripRegex('?/rest'))
+expectType<'*'>(stripRegex('*'))
+expectType<'-other-stuff'>(stripRegex('-other-stuff'))
+expectType<'/edit'>(stripRegex('/edit'))
+expectType<'?/rest/:other(.*)*'>(stripRegex('?/rest/:other(.*)*'))
+expectType<'+/edit/:other(.*)*'>(stripRegex('(\\d+)+/edit/:other(.*)*'))
+expectType<'?/rest/:other(.*)/more/:b(.*)'>(
+ stripRegex('?/rest/:other(.*)/more/:b(.*)')
+)
+
+function extractModifier<S extends string>(_s: S): _ExtractModifier<S> {
+ return {} as any
}
-expectType<'id'>(extractParamName('id(aue(ee{2,3}\\))?/:b(hey)'))
-expectType<'id'>(extractParamName('id(e)+:d(c)'))
-expectType<'id'>(extractParamName('id(e)/:d(c)'))
-expectType<'id'>(extractParamName('id:d'))
-expectType<'id'>(extractParamName('id/:d'))
-expectType<'id'>(extractParamName('id?/other/:d'))
-expectType<'id'>(extractParamName('id/b'))
-expectType<'id'>(extractParamName('id+'))
-expectType<'id'>(extractParamName('id'))
-expectType<'id'>(extractParamName('id-u'))
-expectType<'id'>(extractParamName('id:u'))
-expectType<'id'>(extractParamName('id(o(\\)e)o'))
-expectType<'id'>(extractParamName('id(o(\\)e)?o'))
+expectType<_ModifierExtracTResult<'', ''>>(extractModifier(''))
+expectType<_ModifierExtracTResult<'', '-rest'>>(extractModifier('-rest'))
+expectType<_ModifierExtracTResult<'', 'edit'>>(extractModifier('edit'))
+expectType<_ModifierExtracTResult<'+', ''>>(extractModifier('+'))
+expectType<_ModifierExtracTResult<'+', '/edit'>>(extractModifier('+/edit'))
+expectType<_ModifierExtracTResult<'+', '/edit/:a?'>>(
+ extractModifier('+/edit/:a?')
+)