@tanstack/react-router 0.0.1-beta.203 → 0.0.1-beta.205
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/RouterProvider.js +961 -0
- package/build/cjs/RouterProvider.js.map +1 -0
- package/build/cjs/fileRoute.js +29 -0
- package/build/cjs/fileRoute.js.map +1 -0
- package/build/cjs/index.js +69 -21
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/path.js +211 -0
- package/build/cjs/path.js.map +1 -0
- package/build/cjs/qss.js +65 -0
- package/build/cjs/qss.js.map +1 -0
- package/build/cjs/react.js +148 -190
- package/build/cjs/react.js.map +1 -1
- package/build/cjs/redirects.js +27 -0
- package/build/cjs/redirects.js.map +1 -0
- package/build/cjs/route.js +136 -0
- package/build/cjs/route.js.map +1 -0
- package/build/cjs/router.js +203 -0
- package/build/cjs/router.js.map +1 -0
- package/build/cjs/searchParams.js +83 -0
- package/build/cjs/searchParams.js.map +1 -0
- package/build/cjs/utils.js +196 -0
- package/build/cjs/utils.js.map +1 -0
- package/build/esm/index.js +1799 -211
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +385 -164
- package/build/types/RouteMatch.d.ts +23 -0
- package/build/types/RouterProvider.d.ts +54 -0
- package/build/types/awaited.d.ts +0 -8
- package/build/types/defer.d.ts +0 -0
- package/build/types/fileRoute.d.ts +17 -0
- package/build/types/history.d.ts +7 -0
- package/build/types/index.d.ts +17 -4
- package/build/types/link.d.ts +98 -0
- package/build/types/location.d.ts +14 -0
- package/build/types/path.d.ts +16 -0
- package/build/types/qss.d.ts +2 -0
- package/build/types/react.d.ts +23 -83
- package/build/types/redirects.d.ts +10 -0
- package/build/types/route.d.ts +222 -0
- package/build/types/routeInfo.d.ts +22 -0
- package/build/types/router.d.ts +115 -0
- package/build/types/scroll-restoration.d.ts +0 -3
- package/build/types/searchParams.d.ts +7 -0
- package/build/types/utils.d.ts +48 -0
- package/build/umd/index.development.js +1116 -1540
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +2 -33
- package/build/umd/index.production.js.map +1 -1
- package/package.json +4 -4
- package/src/RouteMatch.ts +28 -0
- package/src/RouterProvider.tsx +1384 -0
- package/src/awaited.tsx +40 -40
- package/src/defer.ts +55 -0
- package/src/fileRoute.ts +143 -0
- package/src/history.ts +8 -0
- package/src/index.tsx +18 -5
- package/src/link.ts +347 -0
- package/src/location.ts +14 -0
- package/src/path.ts +256 -0
- package/src/qss.ts +53 -0
- package/src/react.tsx +174 -422
- package/src/redirects.ts +31 -0
- package/src/route.ts +710 -0
- package/src/routeInfo.ts +68 -0
- package/src/router.ts +373 -0
- package/src/scroll-restoration.tsx +205 -27
- package/src/searchParams.ts +78 -0
- package/src/utils.ts +257 -0
- package/build/cjs/awaited.js +0 -45
- package/build/cjs/awaited.js.map +0 -1
- package/build/cjs/scroll-restoration.js +0 -56
- package/build/cjs/scroll-restoration.js.map +0 -1
package/src/awaited.tsx
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import { DeferredPromise, isDehydratedDeferred } from '@tanstack/router
|
|
2
|
-
import { useRouter } from './react'
|
|
3
|
-
|
|
4
|
-
export type AwaitOptions<T> = {
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function useAwaited<T>({ promise }: AwaitOptions<T>): [T] {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function Await<T>(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
1
|
+
// import { DeferredPromise, isDehydratedDeferred } from '@tanstack/react-router'
|
|
2
|
+
// import { useRouter } from './react'
|
|
3
|
+
|
|
4
|
+
// export type AwaitOptions<T> = {
|
|
5
|
+
// promise: DeferredPromise<T>
|
|
6
|
+
// }
|
|
7
|
+
|
|
8
|
+
// export function useAwaited<T>({ promise }: AwaitOptions<T>): [T] {
|
|
9
|
+
// const router = useRouter()
|
|
10
|
+
|
|
11
|
+
// let state = promise.__deferredState
|
|
12
|
+
// const key = `__TSR__DEFERRED__${state.uid}`
|
|
13
|
+
|
|
14
|
+
// if (isDehydratedDeferred(promise)) {
|
|
15
|
+
// state = router.hydrateData(key)!
|
|
16
|
+
// promise = Promise.resolve(state.data) as DeferredPromise<any>
|
|
17
|
+
// promise.__deferredState = state
|
|
18
|
+
// }
|
|
19
|
+
|
|
20
|
+
// if (state.status === 'pending') {
|
|
21
|
+
// throw promise
|
|
22
|
+
// }
|
|
23
|
+
|
|
24
|
+
// if (state.status === 'error') {
|
|
25
|
+
// throw state.error
|
|
26
|
+
// }
|
|
27
|
+
|
|
28
|
+
// router.dehydrateData(key, state)
|
|
29
|
+
|
|
30
|
+
// return [state.data]
|
|
31
|
+
// }
|
|
32
|
+
|
|
33
|
+
// export function Await<T>(
|
|
34
|
+
// props: AwaitOptions<T> & {
|
|
35
|
+
// children: (result: T) => JSX.Element
|
|
36
|
+
// },
|
|
37
|
+
// ) {
|
|
38
|
+
// const awaited = useAwaited(props)
|
|
39
|
+
// return props.children(...awaited)
|
|
40
|
+
// }
|
package/src/defer.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// export type DeferredPromiseState<T> = { uid: string } & (
|
|
2
|
+
// | {
|
|
3
|
+
// status: 'pending'
|
|
4
|
+
// data?: T
|
|
5
|
+
// error?: unknown
|
|
6
|
+
// }
|
|
7
|
+
// | {
|
|
8
|
+
// status: 'success'
|
|
9
|
+
// data: T
|
|
10
|
+
// }
|
|
11
|
+
// | {
|
|
12
|
+
// status: 'error'
|
|
13
|
+
// data?: T
|
|
14
|
+
// error: unknown
|
|
15
|
+
// }
|
|
16
|
+
// )
|
|
17
|
+
|
|
18
|
+
// export type DeferredPromise<T> = Promise<T> & {
|
|
19
|
+
// __deferredState: DeferredPromiseState<T>
|
|
20
|
+
// }
|
|
21
|
+
|
|
22
|
+
// export function defer<T>(_promise: Promise<T>) {
|
|
23
|
+
// const promise = _promise as DeferredPromise<T>
|
|
24
|
+
|
|
25
|
+
// if (!promise.__deferredState) {
|
|
26
|
+
// promise.__deferredState = {
|
|
27
|
+
// uid: Math.random().toString(36).slice(2),
|
|
28
|
+
// status: 'pending',
|
|
29
|
+
// }
|
|
30
|
+
|
|
31
|
+
// const state = promise.__deferredState
|
|
32
|
+
|
|
33
|
+
// promise
|
|
34
|
+
// .then((data) => {
|
|
35
|
+
// state.status = 'success' as any
|
|
36
|
+
// state.data = data
|
|
37
|
+
// })
|
|
38
|
+
// .catch((error) => {
|
|
39
|
+
// state.status = 'error' as any
|
|
40
|
+
// state.error = error
|
|
41
|
+
// })
|
|
42
|
+
// }
|
|
43
|
+
|
|
44
|
+
// return promise
|
|
45
|
+
// }
|
|
46
|
+
|
|
47
|
+
// export function isDehydratedDeferred(obj: any): boolean {
|
|
48
|
+
// return (
|
|
49
|
+
// typeof obj === 'object' &&
|
|
50
|
+
// obj !== null &&
|
|
51
|
+
// !(obj instanceof Promise) &&
|
|
52
|
+
// !obj.then &&
|
|
53
|
+
// '__deferredState' in obj
|
|
54
|
+
// )
|
|
55
|
+
// }
|
package/src/fileRoute.ts
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { ParsePathParams } from './link'
|
|
2
|
+
import {
|
|
3
|
+
AnyRoute,
|
|
4
|
+
ResolveFullPath,
|
|
5
|
+
ResolveFullSearchSchema,
|
|
6
|
+
MergeFromFromParent,
|
|
7
|
+
RouteMeta,
|
|
8
|
+
AnyContext,
|
|
9
|
+
RouteOptions,
|
|
10
|
+
UpdatableRouteOptions,
|
|
11
|
+
Route,
|
|
12
|
+
AnyPathParams,
|
|
13
|
+
RootRouteId,
|
|
14
|
+
TrimPathLeft,
|
|
15
|
+
RouteConstraints,
|
|
16
|
+
} from './route'
|
|
17
|
+
import { Assign, AssignAll, Expand, IsAny } from './utils'
|
|
18
|
+
|
|
19
|
+
export interface FileRoutesByPath {
|
|
20
|
+
// '/': {
|
|
21
|
+
// parentRoute: typeof rootRoute
|
|
22
|
+
// }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type Replace<
|
|
26
|
+
S extends string,
|
|
27
|
+
From extends string,
|
|
28
|
+
To extends string,
|
|
29
|
+
> = S extends `${infer Start}${From}${infer Rest}`
|
|
30
|
+
? `${Start}${To}${Replace<Rest, From, To>}`
|
|
31
|
+
: S
|
|
32
|
+
|
|
33
|
+
export type TrimLeft<
|
|
34
|
+
T extends string,
|
|
35
|
+
S extends string,
|
|
36
|
+
> = T extends `${S}${infer U}` ? U : T
|
|
37
|
+
|
|
38
|
+
export type TrimRight<
|
|
39
|
+
T extends string,
|
|
40
|
+
S extends string,
|
|
41
|
+
> = T extends `${infer U}${S}` ? U : T
|
|
42
|
+
|
|
43
|
+
export type Trim<T extends string, S extends string> = TrimLeft<
|
|
44
|
+
TrimRight<T, S>,
|
|
45
|
+
S
|
|
46
|
+
>
|
|
47
|
+
|
|
48
|
+
export type RemoveUnderScores<T extends string> = Replace<
|
|
49
|
+
Replace<TrimRight<TrimLeft<T, '/_'>, '_'>, '_/', '/'>,
|
|
50
|
+
'/_',
|
|
51
|
+
'/'
|
|
52
|
+
>
|
|
53
|
+
|
|
54
|
+
export type ResolveFilePath<
|
|
55
|
+
TParentRoute extends AnyRoute,
|
|
56
|
+
TFilePath extends string,
|
|
57
|
+
> = TParentRoute['id'] extends RootRouteId
|
|
58
|
+
? TrimPathLeft<TFilePath>
|
|
59
|
+
: Replace<
|
|
60
|
+
TrimPathLeft<TFilePath>,
|
|
61
|
+
TrimPathLeft<TParentRoute['types']['customId']>,
|
|
62
|
+
''
|
|
63
|
+
>
|
|
64
|
+
|
|
65
|
+
export type FileRoutePath<
|
|
66
|
+
TParentRoute extends AnyRoute,
|
|
67
|
+
TFilePath extends string,
|
|
68
|
+
> = ResolveFilePath<TParentRoute, TFilePath> extends `_${infer _}`
|
|
69
|
+
? string
|
|
70
|
+
: ResolveFilePath<TParentRoute, TFilePath>
|
|
71
|
+
|
|
72
|
+
export class FileRoute<
|
|
73
|
+
TFilePath extends keyof FileRoutesByPath,
|
|
74
|
+
TParentRoute extends AnyRoute = FileRoutesByPath[TFilePath]['parentRoute'],
|
|
75
|
+
TId extends RouteConstraints['TId'] = TFilePath,
|
|
76
|
+
TPath extends RouteConstraints['TPath'] = FileRoutePath<
|
|
77
|
+
TParentRoute,
|
|
78
|
+
TFilePath
|
|
79
|
+
>,
|
|
80
|
+
TFullPath extends RouteConstraints['TFullPath'] = ResolveFullPath<
|
|
81
|
+
TParentRoute,
|
|
82
|
+
RemoveUnderScores<TPath>
|
|
83
|
+
>,
|
|
84
|
+
> {
|
|
85
|
+
constructor(public path: TFilePath) {}
|
|
86
|
+
|
|
87
|
+
createRoute = <
|
|
88
|
+
TSearchSchema extends RouteConstraints['TSearchSchema'] = {},
|
|
89
|
+
TFullSearchSchema extends RouteConstraints['TFullSearchSchema'] = ResolveFullSearchSchema<
|
|
90
|
+
TParentRoute,
|
|
91
|
+
TSearchSchema
|
|
92
|
+
>,
|
|
93
|
+
TParams extends RouteConstraints['TParams'] = ParsePathParams<TPath> extends never
|
|
94
|
+
? AnyPathParams
|
|
95
|
+
: Record<ParsePathParams<TPath>, RouteConstraints['TPath']>,
|
|
96
|
+
TAllParams extends RouteConstraints['TAllParams'] = MergeFromFromParent<
|
|
97
|
+
TParentRoute['types']['allParams'],
|
|
98
|
+
TParams
|
|
99
|
+
>,
|
|
100
|
+
TRouteMeta extends RouteConstraints['TRouteMeta'] = RouteMeta,
|
|
101
|
+
TContext extends Expand<
|
|
102
|
+
Assign<IsAny<TParentRoute['types']['allMeta'], {}>, TRouteMeta>
|
|
103
|
+
> = Expand<Assign<IsAny<TParentRoute['types']['allMeta'], {}>, TRouteMeta>>,
|
|
104
|
+
TRouterMeta extends RouteConstraints['TRouterMeta'] = AnyContext,
|
|
105
|
+
TChildren extends RouteConstraints['TChildren'] = unknown,
|
|
106
|
+
TRouteTree extends RouteConstraints['TRouteTree'] = AnyRoute,
|
|
107
|
+
>(
|
|
108
|
+
options: Omit<
|
|
109
|
+
RouteOptions<
|
|
110
|
+
TParentRoute,
|
|
111
|
+
string,
|
|
112
|
+
string,
|
|
113
|
+
TSearchSchema,
|
|
114
|
+
TFullSearchSchema,
|
|
115
|
+
TParams,
|
|
116
|
+
TAllParams,
|
|
117
|
+
TRouteMeta,
|
|
118
|
+
TContext
|
|
119
|
+
>,
|
|
120
|
+
'getParentRoute' | 'path' | 'id'
|
|
121
|
+
> &
|
|
122
|
+
UpdatableRouteOptions<TFullSearchSchema, TAllParams, TContext>,
|
|
123
|
+
): Route<
|
|
124
|
+
TParentRoute,
|
|
125
|
+
TPath,
|
|
126
|
+
TFullPath,
|
|
127
|
+
TFilePath,
|
|
128
|
+
TId,
|
|
129
|
+
TSearchSchema,
|
|
130
|
+
TFullSearchSchema,
|
|
131
|
+
TParams,
|
|
132
|
+
TAllParams,
|
|
133
|
+
TRouteMeta,
|
|
134
|
+
TContext,
|
|
135
|
+
TRouterMeta,
|
|
136
|
+
TChildren,
|
|
137
|
+
TRouteTree
|
|
138
|
+
> => {
|
|
139
|
+
const route = new Route(options as any)
|
|
140
|
+
;(route as any).isRoot = false
|
|
141
|
+
return route as any
|
|
142
|
+
}
|
|
143
|
+
}
|
package/src/history.ts
ADDED
package/src/index.tsx
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
//
|
|
2
|
-
|
|
3
|
-
export {
|
|
4
|
-
export
|
|
2
|
+
export * from '@tanstack/history'
|
|
3
|
+
export { default as invariant } from 'tiny-invariant'
|
|
4
|
+
export { default as warning } from 'tiny-warning'
|
|
5
|
+
export * from './link'
|
|
6
|
+
export * from './path'
|
|
7
|
+
export * from './qss'
|
|
8
|
+
export * from './route'
|
|
9
|
+
export * from './fileRoute'
|
|
10
|
+
export * from './routeInfo'
|
|
11
|
+
export * from './router'
|
|
12
|
+
export * from './searchParams'
|
|
13
|
+
export * from './utils'
|
|
5
14
|
export * from './react'
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './
|
|
15
|
+
export * from './history'
|
|
16
|
+
export * from './RouteMatch'
|
|
17
|
+
export * from './redirects'
|
|
18
|
+
export * from './location'
|
|
19
|
+
export * from './RouterProvider'
|
|
20
|
+
// export * from './scroll-restoration'
|
package/src/link.ts
ADDED
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import { Trim } from './fileRoute'
|
|
2
|
+
import { AnyRoute } from './route'
|
|
3
|
+
import {
|
|
4
|
+
AllParams,
|
|
5
|
+
FullSearchSchema,
|
|
6
|
+
RouteByPath,
|
|
7
|
+
RouteIds,
|
|
8
|
+
RoutePaths,
|
|
9
|
+
} from './routeInfo'
|
|
10
|
+
import { RegisteredRouter } from './router'
|
|
11
|
+
import { LocationState } from './location'
|
|
12
|
+
import { ParsedLocation } from './location'
|
|
13
|
+
import {
|
|
14
|
+
Expand,
|
|
15
|
+
NoInfer,
|
|
16
|
+
NonNullableUpdater,
|
|
17
|
+
PickRequired,
|
|
18
|
+
UnionToIntersection,
|
|
19
|
+
Updater,
|
|
20
|
+
} from './utils'
|
|
21
|
+
|
|
22
|
+
export type LinkInfo =
|
|
23
|
+
| {
|
|
24
|
+
type: 'external'
|
|
25
|
+
href: string
|
|
26
|
+
}
|
|
27
|
+
| {
|
|
28
|
+
type: 'internal'
|
|
29
|
+
next: ParsedLocation
|
|
30
|
+
handleFocus: (e: any) => void
|
|
31
|
+
handleClick: (e: any) => void
|
|
32
|
+
handleEnter: (e: any) => void
|
|
33
|
+
handleLeave: (e: any) => void
|
|
34
|
+
handleTouchStart: (e: any) => void
|
|
35
|
+
isActive: boolean
|
|
36
|
+
disabled?: boolean
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type CleanPath<T extends string> = T extends `${infer L}//${infer R}`
|
|
40
|
+
? CleanPath<`${CleanPath<L>}/${CleanPath<R>}`>
|
|
41
|
+
: T extends `${infer L}//`
|
|
42
|
+
? `${CleanPath<L>}/`
|
|
43
|
+
: T extends `//${infer L}`
|
|
44
|
+
? `/${CleanPath<L>}`
|
|
45
|
+
: T
|
|
46
|
+
|
|
47
|
+
export type Split<S, TIncludeTrailingSlash = true> = S extends unknown
|
|
48
|
+
? string extends S
|
|
49
|
+
? string[]
|
|
50
|
+
: S extends string
|
|
51
|
+
? CleanPath<S> extends ''
|
|
52
|
+
? []
|
|
53
|
+
: TIncludeTrailingSlash extends true
|
|
54
|
+
? CleanPath<S> extends `${infer T}/`
|
|
55
|
+
? [...Split<T>, '/']
|
|
56
|
+
: CleanPath<S> extends `/${infer U}`
|
|
57
|
+
? Split<U>
|
|
58
|
+
: CleanPath<S> extends `${infer T}/${infer U}`
|
|
59
|
+
? [...Split<T>, ...Split<U>]
|
|
60
|
+
: [S]
|
|
61
|
+
: CleanPath<S> extends `${infer T}/${infer U}`
|
|
62
|
+
? [...Split<T>, ...Split<U>]
|
|
63
|
+
: S extends string
|
|
64
|
+
? [S]
|
|
65
|
+
: never
|
|
66
|
+
: never
|
|
67
|
+
: never
|
|
68
|
+
|
|
69
|
+
export type ParsePathParams<T extends string> = keyof {
|
|
70
|
+
[K in Trim<Split<T>[number], '_'> as K extends `$${infer L}` ? L : never]: K
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export type Join<T, Delimiter extends string = '/'> = T extends []
|
|
74
|
+
? ''
|
|
75
|
+
: T extends [infer L extends string]
|
|
76
|
+
? L
|
|
77
|
+
: T extends [infer L extends string, ...infer Tail extends [...string[]]]
|
|
78
|
+
? CleanPath<`${L}${Delimiter}${Join<Tail>}`>
|
|
79
|
+
: never
|
|
80
|
+
|
|
81
|
+
export type Last<T extends any[]> = T extends [...infer _, infer L] ? L : never
|
|
82
|
+
|
|
83
|
+
export type RelativeToPathAutoComplete<
|
|
84
|
+
AllPaths extends string,
|
|
85
|
+
TFrom extends string,
|
|
86
|
+
TTo extends string,
|
|
87
|
+
SplitPaths extends string[] = Split<AllPaths, false>,
|
|
88
|
+
> = TTo extends `..${infer _}`
|
|
89
|
+
? SplitPaths extends [
|
|
90
|
+
...Split<ResolveRelativePath<TFrom, TTo>, false>,
|
|
91
|
+
...infer TToRest,
|
|
92
|
+
]
|
|
93
|
+
? `${CleanPath<
|
|
94
|
+
Join<
|
|
95
|
+
[
|
|
96
|
+
...Split<TTo, false>,
|
|
97
|
+
...(
|
|
98
|
+
| TToRest
|
|
99
|
+
| (Split<
|
|
100
|
+
ResolveRelativePath<TFrom, TTo>,
|
|
101
|
+
false
|
|
102
|
+
>['length'] extends 1
|
|
103
|
+
? never
|
|
104
|
+
: ['../'])
|
|
105
|
+
),
|
|
106
|
+
]
|
|
107
|
+
>
|
|
108
|
+
>}`
|
|
109
|
+
: never
|
|
110
|
+
: TTo extends `./${infer RestTTo}`
|
|
111
|
+
? SplitPaths extends [
|
|
112
|
+
...Split<TFrom, false>,
|
|
113
|
+
...Split<RestTTo, false>,
|
|
114
|
+
...infer RestPath,
|
|
115
|
+
]
|
|
116
|
+
? `${TTo}${Join<RestPath>}`
|
|
117
|
+
: never
|
|
118
|
+
:
|
|
119
|
+
| (TFrom extends `/`
|
|
120
|
+
? never
|
|
121
|
+
: SplitPaths extends [...Split<TFrom, false>, ...infer RestPath]
|
|
122
|
+
? Join<RestPath> extends { length: 0 }
|
|
123
|
+
? never
|
|
124
|
+
: './'
|
|
125
|
+
: never)
|
|
126
|
+
| (TFrom extends `/` ? never : '../')
|
|
127
|
+
| AllPaths
|
|
128
|
+
|
|
129
|
+
export type NavigateOptions<
|
|
130
|
+
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
|
|
131
|
+
TFrom extends RoutePaths<TRouteTree> = '/',
|
|
132
|
+
TTo extends string = '',
|
|
133
|
+
TMaskFrom extends RoutePaths<TRouteTree> = TFrom,
|
|
134
|
+
TMaskTo extends string = '',
|
|
135
|
+
> = ToOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {
|
|
136
|
+
// `replace` is a boolean that determines whether the navigation should replace the current history entry or push a new one.
|
|
137
|
+
replace?: boolean
|
|
138
|
+
resetScroll?: boolean
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export type ToOptions<
|
|
142
|
+
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
|
|
143
|
+
TFrom extends RoutePaths<TRouteTree> = '/',
|
|
144
|
+
TTo extends string = '',
|
|
145
|
+
TMaskFrom extends RoutePaths<TRouteTree> = '/',
|
|
146
|
+
TMaskTo extends string = '',
|
|
147
|
+
> = ToSubOptions<TRouteTree, TFrom, TTo> & {
|
|
148
|
+
mask?: ToMaskOptions<TRouteTree, TMaskFrom, TMaskTo>
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export type ToMaskOptions<
|
|
152
|
+
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
|
|
153
|
+
TMaskFrom extends RoutePaths<TRouteTree> = '/',
|
|
154
|
+
TMaskTo extends string = '',
|
|
155
|
+
> = ToSubOptions<TRouteTree, TMaskFrom, TMaskTo> & {
|
|
156
|
+
unmaskOnReload?: boolean
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export type ToSubOptions<
|
|
160
|
+
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
|
|
161
|
+
TFrom extends RoutePaths<TRouteTree> = '/',
|
|
162
|
+
TTo extends string = '',
|
|
163
|
+
TResolved = ResolveRelativePath<TFrom, NoInfer<TTo>>,
|
|
164
|
+
> = {
|
|
165
|
+
to?: ToPathOption<TRouteTree, TFrom, TTo>
|
|
166
|
+
// The new has string or a function to update it
|
|
167
|
+
hash?: true | Updater<string>
|
|
168
|
+
// State to pass to the history stack
|
|
169
|
+
state?: true | NonNullableUpdater<LocationState>
|
|
170
|
+
// The source route path. This is automatically set when using route-level APIs, but for type-safe relative routing on the router itself, this is required
|
|
171
|
+
from?: TFrom
|
|
172
|
+
// // When using relative route paths, this option forces resolution from the current path, instead of the route API's path or `from` path
|
|
173
|
+
// fromCurrent?: boolean
|
|
174
|
+
} & CheckPath<TRouteTree, NoInfer<TResolved>, {}> &
|
|
175
|
+
SearchParamOptions<TRouteTree, TFrom, TTo, TResolved> &
|
|
176
|
+
PathParamOptions<TRouteTree, TFrom, TResolved>
|
|
177
|
+
|
|
178
|
+
export type SearchParamOptions<
|
|
179
|
+
TRouteTree extends AnyRoute,
|
|
180
|
+
TFrom,
|
|
181
|
+
TTo,
|
|
182
|
+
TResolved = ResolveRelativePath<TFrom, NoInfer<TTo>>,
|
|
183
|
+
TFromSearchEnsured = '/' extends TFrom
|
|
184
|
+
? FullSearchSchema<TRouteTree>
|
|
185
|
+
: Expand<
|
|
186
|
+
UnionToIntersection<
|
|
187
|
+
PickRequired<
|
|
188
|
+
RouteByPath<TRouteTree, TFrom>['types']['fullSearchSchema']
|
|
189
|
+
>
|
|
190
|
+
>
|
|
191
|
+
>,
|
|
192
|
+
TFromSearchOptional = Omit<AllParams<TRouteTree>, keyof TFromSearchEnsured>,
|
|
193
|
+
TFromSearch = Expand<TFromSearchEnsured & TFromSearchOptional>,
|
|
194
|
+
TToSearch = '' extends TTo
|
|
195
|
+
? FullSearchSchema<TRouteTree>
|
|
196
|
+
: Expand<RouteByPath<TRouteTree, TResolved>['types']['fullSearchSchema']>,
|
|
197
|
+
> = keyof PickRequired<TToSearch> extends never
|
|
198
|
+
? {
|
|
199
|
+
search?: true | SearchReducer<TFromSearch, TToSearch>
|
|
200
|
+
}
|
|
201
|
+
: {
|
|
202
|
+
search: TFromSearchEnsured extends PickRequired<TToSearch>
|
|
203
|
+
? true | SearchReducer<TFromSearch, TToSearch>
|
|
204
|
+
: SearchReducer<TFromSearch, TToSearch>
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
type SearchReducer<TFrom, TTo> = TTo | ((current: TFrom) => TTo)
|
|
208
|
+
|
|
209
|
+
export type PathParamOptions<
|
|
210
|
+
TRouteTree extends AnyRoute,
|
|
211
|
+
TFrom,
|
|
212
|
+
TTo,
|
|
213
|
+
TFromParamsEnsured = Expand<
|
|
214
|
+
UnionToIntersection<
|
|
215
|
+
PickRequired<RouteByPath<TRouteTree, TFrom>['types']['allParams']>
|
|
216
|
+
>
|
|
217
|
+
>,
|
|
218
|
+
TFromParamsOptional = Omit<AllParams<TRouteTree>, keyof TFromParamsEnsured>,
|
|
219
|
+
TFromParams = Expand<TFromParamsOptional & TFromParamsEnsured>,
|
|
220
|
+
TToParams = Expand<RouteByPath<TRouteTree, TTo>['types']['allParams']>,
|
|
221
|
+
> = keyof PickRequired<TToParams> extends never
|
|
222
|
+
? {
|
|
223
|
+
params?: true | ParamsReducer<TFromParams, TToParams>
|
|
224
|
+
}
|
|
225
|
+
: {
|
|
226
|
+
params: TFromParamsEnsured extends PickRequired<TToParams>
|
|
227
|
+
? true | ParamsReducer<TFromParams, TToParams>
|
|
228
|
+
: ParamsReducer<TFromParams, TToParams>
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
type ParamsReducer<TFrom, TTo> = TTo | ((current: TFrom) => TTo)
|
|
232
|
+
|
|
233
|
+
export type ToPathOption<
|
|
234
|
+
TRouteTree extends AnyRoute = AnyRoute,
|
|
235
|
+
TFrom extends RoutePaths<TRouteTree> = '/',
|
|
236
|
+
TTo extends string = '',
|
|
237
|
+
> =
|
|
238
|
+
| TTo
|
|
239
|
+
| RelativeToPathAutoComplete<
|
|
240
|
+
RoutePaths<TRouteTree>,
|
|
241
|
+
NoInfer<TFrom> extends string ? NoInfer<TFrom> : '',
|
|
242
|
+
NoInfer<TTo> & string
|
|
243
|
+
>
|
|
244
|
+
|
|
245
|
+
export type ToIdOption<
|
|
246
|
+
TRouteTree extends AnyRoute = AnyRoute,
|
|
247
|
+
TFrom extends RoutePaths<TRouteTree> = '/',
|
|
248
|
+
TTo extends string = '',
|
|
249
|
+
> =
|
|
250
|
+
| TTo
|
|
251
|
+
| RelativeToPathAutoComplete<
|
|
252
|
+
RouteIds<TRouteTree>,
|
|
253
|
+
NoInfer<TFrom> extends string ? NoInfer<TFrom> : '',
|
|
254
|
+
NoInfer<TTo> & string
|
|
255
|
+
>
|
|
256
|
+
|
|
257
|
+
export interface ActiveOptions {
|
|
258
|
+
exact?: boolean
|
|
259
|
+
includeHash?: boolean
|
|
260
|
+
includeSearch?: boolean
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export type LinkOptions<
|
|
264
|
+
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
|
|
265
|
+
TFrom extends RoutePaths<TRouteTree> = '/',
|
|
266
|
+
TTo extends string = '',
|
|
267
|
+
TMaskFrom extends RoutePaths<TRouteTree> = TFrom,
|
|
268
|
+
TMaskTo extends string = '',
|
|
269
|
+
> = NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {
|
|
270
|
+
// The standard anchor tag target attribute
|
|
271
|
+
target?: HTMLAnchorElement['target']
|
|
272
|
+
// Defaults to `{ exact: false, includeHash: false }`
|
|
273
|
+
activeOptions?: ActiveOptions
|
|
274
|
+
// If set, will preload the linked route on hover and cache it for this many milliseconds in hopes that the user will eventually navigate there.
|
|
275
|
+
preload?: false | 'intent'
|
|
276
|
+
// Delay intent preloading by this many milliseconds. If the intent exits before this delay, the preload will be cancelled.
|
|
277
|
+
preloadDelay?: number
|
|
278
|
+
// If true, will render the link without the href attribute
|
|
279
|
+
disabled?: boolean
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export type CheckRelativePath<
|
|
283
|
+
TRouteTree extends AnyRoute,
|
|
284
|
+
TFrom,
|
|
285
|
+
TTo,
|
|
286
|
+
> = TTo extends string
|
|
287
|
+
? TFrom extends string
|
|
288
|
+
? ResolveRelativePath<TFrom, TTo> extends RoutePaths<TRouteTree>
|
|
289
|
+
? {}
|
|
290
|
+
: {
|
|
291
|
+
Error: `${TFrom} + ${TTo} resolves to ${ResolveRelativePath<
|
|
292
|
+
TFrom,
|
|
293
|
+
TTo
|
|
294
|
+
>}, which is not a valid route path.`
|
|
295
|
+
'Valid Route Paths': RoutePaths<TRouteTree>
|
|
296
|
+
}
|
|
297
|
+
: {}
|
|
298
|
+
: {}
|
|
299
|
+
|
|
300
|
+
export type CheckPath<TRouteTree extends AnyRoute, TPath, TPass> = Exclude<
|
|
301
|
+
TPath,
|
|
302
|
+
RoutePaths<TRouteTree>
|
|
303
|
+
> extends never
|
|
304
|
+
? TPass
|
|
305
|
+
: CheckPathError<TRouteTree, Exclude<TPath, RoutePaths<TRouteTree>>>
|
|
306
|
+
|
|
307
|
+
export type CheckPathError<TRouteTree extends AnyRoute, TInvalids> = {
|
|
308
|
+
to: RoutePaths<TRouteTree>
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export type CheckId<TRouteTree extends AnyRoute, TPath, TPass> = Exclude<
|
|
312
|
+
TPath,
|
|
313
|
+
RouteIds<TRouteTree>
|
|
314
|
+
> extends never
|
|
315
|
+
? TPass
|
|
316
|
+
: CheckIdError<TRouteTree, Exclude<TPath, RouteIds<TRouteTree>>>
|
|
317
|
+
|
|
318
|
+
export type CheckIdError<TRouteTree extends AnyRoute, TInvalids> = {
|
|
319
|
+
Error: `${TInvalids extends string
|
|
320
|
+
? TInvalids
|
|
321
|
+
: never} is not a valid route ID.`
|
|
322
|
+
'Valid Route IDs': RouteIds<TRouteTree>
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
export type ResolveRelativePath<TFrom, TTo = '.'> = TFrom extends string
|
|
326
|
+
? TTo extends string
|
|
327
|
+
? TTo extends '.'
|
|
328
|
+
? TFrom
|
|
329
|
+
: TTo extends `./`
|
|
330
|
+
? Join<[TFrom, '/']>
|
|
331
|
+
: TTo extends `./${infer TRest}`
|
|
332
|
+
? ResolveRelativePath<TFrom, TRest>
|
|
333
|
+
: TTo extends `/${infer TRest}`
|
|
334
|
+
? TTo
|
|
335
|
+
: Split<TTo> extends ['..', ...infer ToRest]
|
|
336
|
+
? Split<TFrom> extends [...infer FromRest, infer FromTail]
|
|
337
|
+
? ToRest extends ['/']
|
|
338
|
+
? Join<[...FromRest, '/']>
|
|
339
|
+
: ResolveRelativePath<Join<FromRest>, Join<ToRest>>
|
|
340
|
+
: never
|
|
341
|
+
: Split<TTo> extends ['.', ...infer ToRest]
|
|
342
|
+
? ToRest extends ['/']
|
|
343
|
+
? Join<[TFrom, '/']>
|
|
344
|
+
: ResolveRelativePath<TFrom, Join<ToRest>>
|
|
345
|
+
: CleanPath<Join<['/', ...Split<TFrom>, ...Split<TTo>]>>
|
|
346
|
+
: never
|
|
347
|
+
: never
|
package/src/location.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { HistoryState } from '@tanstack/history'
|
|
2
|
+
import { AnySearchSchema } from './route'
|
|
3
|
+
|
|
4
|
+
export interface ParsedLocation<TSearchObj extends AnySearchSchema = {}> {
|
|
5
|
+
href: string
|
|
6
|
+
pathname: string
|
|
7
|
+
search: TSearchObj
|
|
8
|
+
searchStr: string
|
|
9
|
+
state: HistoryState
|
|
10
|
+
hash: string
|
|
11
|
+
maskedLocation?: ParsedLocation<TSearchObj>
|
|
12
|
+
unmaskOnReload?: boolean
|
|
13
|
+
}
|
|
14
|
+
export interface LocationState {}
|