@tanstack/react-router 1.41.0 → 1.42.0

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/src/route.ts CHANGED
@@ -91,10 +91,36 @@ export type RouteOptions<
91
91
  NoInfer<TLoaderDeps>
92
92
  >
93
93
 
94
- export type ParamsFallback<
95
- TPath extends string,
96
- TParams,
97
- > = unknown extends TParams ? Record<ParsePathParams<TPath>, string> : TParams
94
+ export type ParseParamsFn<TPath extends string, TParams> = (
95
+ rawParams: Record<ParsePathParams<TPath>, string>,
96
+ ) => TParams extends Record<ParsePathParams<TPath>, any>
97
+ ? TParams
98
+ : Record<ParsePathParams<TPath>, any>
99
+
100
+ export type StringifyParamsFn<TPath extends string, TParams> = (
101
+ params: TParams,
102
+ ) => Record<ParsePathParams<TPath>, string>
103
+
104
+ export type ParamsOptions<TPath extends string, TParams> = {
105
+ params?: {
106
+ parse: ParseParamsFn<TPath, TParams>
107
+ stringify: StringifyParamsFn<TPath, TParams>
108
+ }
109
+
110
+ /**
111
+ @deprecated Use params.parse instead
112
+ */
113
+ parseParams?: ParseParamsFn<TPath, TParams>
114
+
115
+ /**
116
+ @deprecated Use params.stringify instead
117
+ */
118
+ stringifyParams?: StringifyParamsFn<TPath, TParams>
119
+ }
120
+
121
+ export interface FullSearchSchemaOption<TFullSearchSchema> {
122
+ search: TFullSearchSchema
123
+ }
98
124
 
99
125
  export type FileBaseRouteOptions<
100
126
  TPath extends string = string,
@@ -102,14 +128,16 @@ export type FileBaseRouteOptions<
102
128
  TSearchSchema = {},
103
129
  TFullSearchSchema = TSearchSchema,
104
130
  TParams = {},
105
- TAllParams = ParamsFallback<TPath, TParams>,
131
+ TAllParams = {},
106
132
  TRouteContextReturn = RouteContext,
107
133
  TParentAllContext = AnyContext,
108
134
  TAllContext = AnyContext,
109
135
  TLoaderDeps extends Record<string, any> = {},
110
136
  TLoaderDataReturn = {},
111
137
  > = {
112
- validateSearch?: SearchSchemaValidator<TSearchSchemaInput, TSearchSchema>
138
+ validateSearch?:
139
+ | ((input: TSearchSchemaInput) => TSearchSchema)
140
+ | { parse: (input: TSearchSchemaInput) => TSearchSchema }
113
141
  shouldReload?:
114
142
  | boolean
115
143
  | ((
@@ -119,36 +147,14 @@ export type FileBaseRouteOptions<
119
147
  // If an error is thrown here, the route's loader will not be called.
120
148
  // If thrown during a navigation, the navigation will be cancelled and the error will be passed to the `onError` function.
121
149
  // If thrown during a preload event, the error will be logged to the console.
122
- beforeLoad?: BeforeLoadFn<
123
- TFullSearchSchema,
124
- TAllParams,
125
- TRouteContextReturn,
126
- TParentAllContext
127
- >
128
- loaderDeps?: (opts: { search: TFullSearchSchema }) => TLoaderDeps
129
- loader?: RouteLoaderFn<
130
- TAllParams,
131
- NoInfer<TLoaderDeps>,
132
- NoInfer<TAllContext>,
133
- TLoaderDataReturn
134
- >
135
- } & (
136
- | {
137
- // Both or none
138
- parseParams?: (
139
- rawParams: IsAny<TPath, any, Record<ParsePathParams<TPath>, string>>,
140
- ) => TParams extends Record<ParsePathParams<TPath>, any>
141
- ? TParams
142
- : 'parseParams must return an object'
143
- stringifyParams?: (
144
- params: NoInfer<ParamsFallback<TPath, TParams>>,
145
- ) => Record<ParsePathParams<TPath>, string>
146
- }
147
- | {
148
- stringifyParams?: never
149
- parseParams?: never
150
- }
151
- )
150
+ beforeLoad?: (
151
+ ctx: BeforeLoadContext<TFullSearchSchema, TAllParams, TParentAllContext>,
152
+ ) => Promise<TRouteContextReturn> | TRouteContextReturn | void
153
+ loaderDeps?: (opts: FullSearchSchemaOption<TFullSearchSchema>) => TLoaderDeps
154
+ loader?: (
155
+ ctx: LoaderFnContext<TAllParams, TLoaderDeps, TAllContext>,
156
+ ) => TLoaderDataReturn | Promise<TLoaderDataReturn>
157
+ } & ParamsOptions<TPath, TParams>
152
158
 
153
159
  export type BaseRouteOptions<
154
160
  TParentRoute extends AnyRoute = AnyRoute,
@@ -158,7 +164,7 @@ export type BaseRouteOptions<
158
164
  TSearchSchema = {},
159
165
  TFullSearchSchema = TSearchSchema,
160
166
  TParams = {},
161
- TAllParams = ParamsFallback<TPath, TParams>,
167
+ TAllParams = {},
162
168
  TRouteContextReturn = RouteContext,
163
169
  TParentAllContext = AnyContext,
164
170
  TAllContext = AnyContext,
@@ -181,16 +187,14 @@ export type BaseRouteOptions<
181
187
  getParentRoute: () => TParentRoute
182
188
  }
183
189
 
184
- type BeforeLoadFn<
185
- in out TFullSearchSchema,
186
- in out TAllParams,
187
- TRouteContextReturn,
188
- in out TParentAllContext,
189
- > = (opts: {
190
- search: TFullSearchSchema
190
+ export interface BeforeLoadContext<
191
+ TFullSearchSchema,
192
+ TAllParams,
193
+ TParentAllContext,
194
+ > extends FullSearchSchemaOption<TFullSearchSchema> {
191
195
  abortController: AbortController
192
196
  preload: boolean
193
- params: TAllParams
197
+ params: Expand<TAllParams>
194
198
  context: TParentAllContext
195
199
  location: ParsedLocation
196
200
  /**
@@ -199,7 +203,7 @@ type BeforeLoadFn<
199
203
  navigate: NavigateFn
200
204
  buildLocation: BuildLocationFn
201
205
  cause: 'preload' | 'enter' | 'stay'
202
- }) => Promise<TRouteContextReturn> | TRouteContextReturn | void
206
+ }
203
207
 
204
208
  export type UpdatableRouteOptions<
205
209
  TRouteId,
@@ -286,21 +290,6 @@ type LdJsonValue = LdJsonPrimitive | LdJsonObject | LdJsonArray
286
290
 
287
291
  export type RouteLinkEntry = {}
288
292
 
289
- export type ParseParamsOption<TPath extends string, TParams> = ParseParamsFn<
290
- TPath,
291
- TParams
292
- >
293
-
294
- export type ParseParamsFn<TPath extends string, TParams> = (
295
- rawParams: IsAny<TPath, any, Record<ParsePathParams<TPath>, string>>,
296
- ) => TParams extends Record<ParsePathParams<TPath>, any>
297
- ? TParams
298
- : 'parseParams must return an object'
299
-
300
- export type ParseParamsObj<TPath extends string, TParams> = {
301
- parse?: ParseParamsFn<TPath, TParams>
302
- }
303
-
304
293
  // The parse type here allows a zod schema to be passed directly to the validator
305
294
  export type SearchSchemaValidator<TInput, TReturn> =
306
295
  | SearchSchemaValidatorObj<TInput, TReturn>
@@ -321,7 +310,7 @@ export type RouteLoaderFn<
321
310
  TLoaderData = undefined,
322
311
  > = (
323
312
  match: LoaderFnContext<TAllParams, TLoaderDeps, TAllContext>,
324
- ) => Promise<TLoaderData> | TLoaderData
313
+ ) => TLoaderData | Promise<TLoaderData>
325
314
 
326
315
  export interface LoaderFnContext<
327
316
  in out TAllParams = {},
@@ -330,7 +319,7 @@ export interface LoaderFnContext<
330
319
  > {
331
320
  abortController: AbortController
332
321
  preload: boolean
333
- params: TAllParams
322
+ params: Expand<TAllParams>
334
323
  deps: TLoaderDeps
335
324
  context: TAllContext
336
325
  location: ParsedLocation // Do not supply search schema here so as to demotivate people from trying to shortcut loaderDeps
@@ -992,6 +981,7 @@ export type RootRouteOptions<
992
981
  | 'caseSensitive'
993
982
  | 'parseParams'
994
983
  | 'stringifyParams'
984
+ | 'params'
995
985
  >
996
986
 
997
987
  export function createRootRouteWithContext<TRouterContext extends {}>() {
@@ -1126,6 +1116,7 @@ export function createRootRoute<
1126
1116
  | 'caseSensitive'
1127
1117
  | 'parseParams'
1128
1118
  | 'stringifyParams'
1119
+ | 'params'
1129
1120
  >,
1130
1121
  ) {
1131
1122
  return new RootRoute<
@@ -1294,7 +1285,12 @@ export class NotFoundRoute<
1294
1285
  TLoaderDataReturn,
1295
1286
  TLoaderData
1296
1287
  >,
1297
- 'caseSensitive' | 'parseParams' | 'stringifyParams' | 'path' | 'id'
1288
+ | 'caseSensitive'
1289
+ | 'parseParams'
1290
+ | 'stringifyParams'
1291
+ | 'path'
1292
+ | 'id'
1293
+ | 'params'
1298
1294
  >,
1299
1295
  ) {
1300
1296
  super({
package/src/router.ts CHANGED
@@ -934,9 +934,12 @@ export class Router<
934
934
  const parseErrors = matchedRoutes.map((route) => {
935
935
  let parsedParamsError
936
936
 
937
- if (route.options.parseParams) {
937
+ const parseParams =
938
+ route.options.params?.parse ?? route.options.parseParams
939
+
940
+ if (parseParams) {
938
941
  try {
939
- const parsedParams = route.options.parseParams(routeParams)
942
+ const parsedParams = parseParams(routeParams)
940
943
  // Add the parsed params to the accumulated params bag
941
944
  Object.assign(routeParams, parsedParams)
942
945
  } catch (err: any) {
@@ -1193,7 +1196,12 @@ export class Router<
1193
1196
 
1194
1197
  if (Object.keys(nextParams).length > 0) {
1195
1198
  matches
1196
- ?.map((d) => this.looseRoutesById[d.routeId]!.options.stringifyParams)
1199
+ ?.map((d) => {
1200
+ const route = this.looseRoutesById[d.routeId]
1201
+ return (
1202
+ route?.options.params?.stringify ?? route!.options.stringifyParams
1203
+ )
1204
+ })
1197
1205
  .filter(Boolean)
1198
1206
  .forEach((fn) => {
1199
1207
  nextParams = { ...nextParams!, ...fn!(nextParams) }