@tanstack/react-router 1.34.9 → 1.35.1
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/dist/cjs/index.d.cts +1 -1
- package/dist/cjs/link.cjs +1 -2
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/link.d.cts +9 -7
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +7 -5
- package/dist/cjs/routeInfo.d.cts +6 -5
- package/dist/cjs/router.cjs +14 -7
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/useNavigate.cjs +2 -4
- package/dist/cjs/useNavigate.cjs.map +1 -1
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +1 -2
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/link.d.ts +9 -7
- package/dist/esm/link.js +1 -2
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/route.d.ts +7 -5
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/routeInfo.d.ts +6 -5
- package/dist/esm/router.js +14 -7
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/useNavigate.js +2 -4
- package/dist/esm/useNavigate.js.map +1 -1
- package/dist/esm/utils.d.ts +1 -2
- package/dist/esm/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/index.tsx +0 -1
- package/src/link.tsx +48 -37
- package/src/route.ts +7 -17
- package/src/routeInfo.ts +14 -9
- package/src/router.ts +17 -6
- package/src/useNavigate.tsx +0 -2
- package/src/utils.ts +1 -7
package/dist/esm/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["import * as React from 'react'\n\nexport type NoInfer<T> = [T][T extends any ? 0 : never]\nexport type IsAny<TValue, TYesResult, TNoResult = TValue> = 1 extends 0 & TValue\n ? TYesResult\n : TNoResult\nexport type PickAsRequired<TValue, TKey extends keyof TValue> = Omit<\n TValue,\n TKey\n> &\n Required<Pick<TValue, TKey>>\n\nexport type PickRequired<T> = {\n [K in keyof T as undefined extends T[K] ? never : K]: T[K]\n}\n\n// from https://stackoverflow.com/a/76458160\nexport type WithoutEmpty<T> = T extends any ? ({} extends T ? never : T) : never\n\n// export type Expand<T> = T\nexport type Expand<T> = T extends object\n ? T extends infer O\n ? O extends Function\n ? O\n : { [K in keyof O]: O[K] }\n : never\n : T\n\nexport type UnionToIntersection<T> = (\n T extends any ? (k: T) => void : never\n) extends (k: infer I) => any\n ? I\n : never\n\nexport type DeepPartial<T> = T extends object\n ? {\n [P in keyof T]?: DeepPartial<T[P]>\n }\n : T\n\nexport type MakeDifferenceOptional<TLeft, TRight> = Omit<\n TRight,\n keyof TLeft\n> & {\n [K in keyof TLeft & keyof TRight]?: TRight[K]\n}\n\n// from https://stackoverflow.com/a/53955431\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type IsUnion<T, U extends T = T> = (\n T extends any ? (U extends T ? false : true) : never\n) extends false\n ? false\n : true\n\nexport type Assign<TLeft, TRight> = keyof TLeft extends never\n ? TRight\n : keyof TRight extends never\n ? TLeft\n : Omit<TLeft, keyof TRight> & TRight\n\nexport type Timeout = ReturnType<typeof setTimeout>\n\nexport type Updater<TPrevious, TResult = TPrevious> =\n | TResult\n | ((prev?: TPrevious) => TResult)\n\nexport type NonNullableUpdater<TPrevious, TResult = TPrevious> =\n | TResult\n | ((prev: TPrevious) => TResult)\n\nexport type MergeUnionObjects<TUnion> = TUnion extends MergeUnionPrimitive\n ? never\n : TUnion\n\nexport type MergeUnionObject<TUnion> =\n MergeUnionObjects<TUnion> extends infer TObj\n ? {\n [TKey in TObj extends any ? keyof TObj : never]?: TObj extends any\n ? TKey extends keyof TObj\n ? TObj[TKey]\n : never\n : never\n }\n : never\n\nexport type MergeUnionPrimitive =\n | ReadonlyArray<any>\n | number\n | string\n | bigint\n | boolean\n | symbol\n\nexport type MergeUnionPrimitives<TUnion> = TUnion extends MergeUnionPrimitive\n ? TUnion\n : TUnion extends object\n ? never\n : TUnion\n\nexport type MergeUnion<TUnion> =\n | MergeUnionPrimitives<TUnion>\n | MergeUnionObject<MergeUnionObjects<TUnion>>\n\nexport function last<T>(arr: Array<T>) {\n return arr[arr.length - 1]\n}\n\nfunction isFunction(d: any): d is Function {\n return typeof d === 'function'\n}\n\nexport function functionalUpdate<TResult>(\n updater: Updater<TResult> | NonNullableUpdater<TResult>,\n previous: TResult,\n): TResult {\n if (isFunction(updater)) {\n return updater(previous)\n }\n\n return updater\n}\n\nexport function pick<TValue, TKey extends keyof TValue>(\n parent: TValue,\n keys: Array<TKey>,\n): Pick<TValue, TKey> {\n return keys.reduce((obj: any, key: TKey) => {\n obj[key] = parent[key]\n return obj\n }, {} as any)\n}\n\n/**\n * This function returns `prev` if `_next` is deeply equal.\n * If not, it will replace any deeply equal children of `b` with those of `a`.\n * This can be used for structural sharing between immutable JSON values for example.\n * Do not use this with signals\n */\nexport function replaceEqualDeep<T>(prev: any, _next: T): T {\n if (prev === _next) {\n return prev\n }\n\n const next = _next as any\n\n const array = isPlainArray(prev) && isPlainArray(next)\n\n if (array || (isPlainObject(prev) && isPlainObject(next))) {\n const prevItems = array ? prev : Object.keys(prev)\n const prevSize = prevItems.length\n const nextItems = array ? next : Object.keys(next)\n const nextSize = nextItems.length\n const copy: any = array ? [] : {}\n\n let equalItems = 0\n\n for (let i = 0; i < nextSize; i++) {\n const key = array ? i : nextItems[i]\n if (\n ((!array && prevItems.includes(key)) || array) &&\n prev[key] === undefined &&\n next[key] === undefined\n ) {\n copy[key] = undefined\n equalItems++\n } else {\n copy[key] = replaceEqualDeep(prev[key], next[key])\n if (copy[key] === prev[key] && prev[key] !== undefined) {\n equalItems++\n }\n }\n }\n\n return prevSize === nextSize && equalItems === prevSize ? prev : copy\n }\n\n return next\n}\n\n// Copied from: https://github.com/jonschlinkert/is-plain-object\nexport function isPlainObject(o: any) {\n if (!hasObjectPrototype(o)) {\n return false\n }\n\n // If has modified constructor\n const ctor = o.constructor\n if (typeof ctor === 'undefined') {\n return true\n }\n\n // If has modified prototype\n const prot = ctor.prototype\n if (!hasObjectPrototype(prot)) {\n return false\n }\n\n // If constructor does not have an Object-specific method\n if (!prot.hasOwnProperty('isPrototypeOf')) {\n return false\n }\n\n // Most likely a plain Object\n return true\n}\n\nfunction hasObjectPrototype(o: any) {\n return Object.prototype.toString.call(o) === '[object Object]'\n}\n\nexport function isPlainArray(value: unknown) {\n return Array.isArray(value) && value.length === Object.keys(value).length\n}\n\nexport function deepEqual(a: any, b: any, partial: boolean = false): boolean {\n if (a === b) {\n return true\n }\n\n if (typeof a !== typeof b) {\n return false\n }\n\n if (isPlainObject(a) && isPlainObject(b)) {\n const aKeys = Object.keys(a)\n const bKeys = Object.keys(b)\n\n if (!partial && aKeys.length !== bKeys.length) {\n return false\n }\n\n return !bKeys.some(\n (key) => !(key in a) || !deepEqual(a[key], b[key], partial),\n )\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n return !a.some((item, index) => !deepEqual(item, b[index], partial))\n }\n\n return false\n}\n\nexport function useStableCallback<T extends (...args: Array<any>) => any>(\n fn: T,\n): T {\n const fnRef = React.useRef(fn)\n fnRef.current = fn\n\n const ref = React.useRef((...args: Array<any>) => fnRef.current(...args))\n return ref.current as T\n}\n\nexport function shallow<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n const keysA = Object.keys(objA)\n if (keysA.length !== Object.keys(objB).length) {\n return false\n }\n\n for (const item of keysA) {\n if (\n !Object.prototype.hasOwnProperty.call(objB, item) ||\n !Object.is(objA[item as keyof T], objB[item as keyof T])\n ) {\n return false\n }\n }\n return true\n}\n\nexport type StringLiteral<T> = T extends string\n ? string extends T\n ? string\n : T\n : never\n\nexport type StrictOrFrom<\n TFrom,\n TStrict extends boolean = true,\n> = TStrict extends false\n ? {\n from?: never\n strict: TStrict\n }\n : {\n from: StringLiteral<TFrom> | TFrom\n strict?: TStrict\n }\n\nexport const useLayoutEffect =\n typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect\n\n/**\n *\n * @deprecated use `jsesc` instead\n */\nexport function escapeJSON(jsonString: string) {\n return jsonString\n .replace(/\\\\/g, '\\\\\\\\') // Escape backslashes\n .replace(/'/g, \"\\\\'\") // Escape single quotes\n .replace(/\"/g, '\\\\\"') // Escape double quotes\n}\n\nexport function removeTrailingSlash(value: string): string {\n if (value.endsWith('/') && value !== '/') {\n return value.slice(0, -1)\n }\n return value\n}\n\n// intended to only compare path name\n// see the usage in the isActive under useLinkProps\n// /sample/path1 = /sample/path1/\n// /sample/path1/some <> /sample/path1\nexport function exactPathTest(pathName1: string, pathName2: string): boolean {\n return removeTrailingSlash(pathName1) === removeTrailingSlash(pathName2)\n}\n\nexport type ControlledPromise<T> = Promise<T> & {\n resolve: (value: T) => void\n reject: (value: any) => void\n status: 'pending' | 'resolved' | 'rejected'\n}\n\nexport function createControlledPromise<T>(onResolve?: () => void) {\n let resolveLoadPromise!: () => void\n let rejectLoadPromise!: (value: any) => void\n\n const controlledPromise = new Promise<void>((resolve, reject) => {\n resolveLoadPromise = resolve\n rejectLoadPromise = reject\n }) as ControlledPromise<T>\n\n controlledPromise.status = 'pending'\n\n controlledPromise.resolve = () => {\n controlledPromise.status = 'resolved'\n resolveLoadPromise()\n onResolve?.()\n }\n\n controlledPromise.reject = (e) => {\n controlledPromise.status = 'rejected'\n rejectLoadPromise(e)\n }\n\n return controlledPromise\n}\n\n/**\n * Taken from https://www.developerway.com/posts/implementing-advanced-use-previous-hook#part3\n */\nexport function usePrevious<T>(value: T): T | null {\n // initialise the ref with previous and current values\n const ref = React.useRef<{ value: T; prev: T | null }>({\n value: value,\n prev: null,\n })\n\n const current = ref.current.value\n\n // if the value passed into hook doesn't match what we store as \"current\"\n // move the \"current\" to the \"previous\"\n // and store the passed value as \"current\"\n if (value !== current) {\n ref.current = {\n value: value,\n prev: current,\n }\n }\n\n // return the previous value only\n return ref.current.prev\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["import * as React from 'react'\n\nexport type NoInfer<T> = [T][T extends any ? 0 : never]\nexport type IsAny<TValue, TYesResult, TNoResult = TValue> = 1 extends 0 & TValue\n ? TYesResult\n : TNoResult\nexport type PickAsRequired<TValue, TKey extends keyof TValue> = Omit<\n TValue,\n TKey\n> &\n Required<Pick<TValue, TKey>>\n\nexport type PickRequired<T> = {\n [K in keyof T as undefined extends T[K] ? never : K]: T[K]\n}\n\n// from https://stackoverflow.com/a/76458160\nexport type WithoutEmpty<T> = T extends any ? ({} extends T ? never : T) : never\n\n// export type Expand<T> = T\nexport type Expand<T> = T extends object\n ? T extends infer O\n ? O extends Function\n ? O\n : { [K in keyof O]: O[K] }\n : never\n : T\n\nexport type DeepPartial<T> = T extends object\n ? {\n [P in keyof T]?: DeepPartial<T[P]>\n }\n : T\n\nexport type MakeDifferenceOptional<TLeft, TRight> = Omit<\n TRight,\n keyof TLeft\n> & {\n [K in keyof TLeft & keyof TRight]?: TRight[K]\n}\n\n// from https://stackoverflow.com/a/53955431\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type IsUnion<T, U extends T = T> = (\n T extends any ? (U extends T ? false : true) : never\n) extends false\n ? false\n : true\n\nexport type Assign<TLeft, TRight> = keyof TLeft extends never\n ? TRight\n : keyof TRight extends never\n ? TLeft\n : Omit<TLeft, keyof TRight> & TRight\n\nexport type Timeout = ReturnType<typeof setTimeout>\n\nexport type Updater<TPrevious, TResult = TPrevious> =\n | TResult\n | ((prev?: TPrevious) => TResult)\n\nexport type NonNullableUpdater<TPrevious, TResult = TPrevious> =\n | TResult\n | ((prev: TPrevious) => TResult)\n\nexport type MergeUnionObjects<TUnion> = TUnion extends MergeUnionPrimitive\n ? never\n : TUnion\n\nexport type MergeUnionObject<TUnion> =\n MergeUnionObjects<TUnion> extends infer TObj\n ? {\n [TKey in TObj extends any ? keyof TObj : never]?: TObj extends any\n ? TKey extends keyof TObj\n ? TObj[TKey]\n : never\n : never\n }\n : never\n\nexport type MergeUnionPrimitive =\n | ReadonlyArray<any>\n | number\n | string\n | bigint\n | boolean\n | symbol\n\nexport type MergeUnionPrimitives<TUnion> = TUnion extends MergeUnionPrimitive\n ? TUnion\n : TUnion extends object\n ? never\n : TUnion\n\nexport type MergeUnion<TUnion> =\n | MergeUnionPrimitives<TUnion>\n | MergeUnionObject<TUnion>\n\nexport function last<T>(arr: Array<T>) {\n return arr[arr.length - 1]\n}\n\nfunction isFunction(d: any): d is Function {\n return typeof d === 'function'\n}\n\nexport function functionalUpdate<TResult>(\n updater: Updater<TResult> | NonNullableUpdater<TResult>,\n previous: TResult,\n): TResult {\n if (isFunction(updater)) {\n return updater(previous)\n }\n\n return updater\n}\n\nexport function pick<TValue, TKey extends keyof TValue>(\n parent: TValue,\n keys: Array<TKey>,\n): Pick<TValue, TKey> {\n return keys.reduce((obj: any, key: TKey) => {\n obj[key] = parent[key]\n return obj\n }, {} as any)\n}\n\n/**\n * This function returns `prev` if `_next` is deeply equal.\n * If not, it will replace any deeply equal children of `b` with those of `a`.\n * This can be used for structural sharing between immutable JSON values for example.\n * Do not use this with signals\n */\nexport function replaceEqualDeep<T>(prev: any, _next: T): T {\n if (prev === _next) {\n return prev\n }\n\n const next = _next as any\n\n const array = isPlainArray(prev) && isPlainArray(next)\n\n if (array || (isPlainObject(prev) && isPlainObject(next))) {\n const prevItems = array ? prev : Object.keys(prev)\n const prevSize = prevItems.length\n const nextItems = array ? next : Object.keys(next)\n const nextSize = nextItems.length\n const copy: any = array ? [] : {}\n\n let equalItems = 0\n\n for (let i = 0; i < nextSize; i++) {\n const key = array ? i : nextItems[i]\n if (\n ((!array && prevItems.includes(key)) || array) &&\n prev[key] === undefined &&\n next[key] === undefined\n ) {\n copy[key] = undefined\n equalItems++\n } else {\n copy[key] = replaceEqualDeep(prev[key], next[key])\n if (copy[key] === prev[key] && prev[key] !== undefined) {\n equalItems++\n }\n }\n }\n\n return prevSize === nextSize && equalItems === prevSize ? prev : copy\n }\n\n return next\n}\n\n// Copied from: https://github.com/jonschlinkert/is-plain-object\nexport function isPlainObject(o: any) {\n if (!hasObjectPrototype(o)) {\n return false\n }\n\n // If has modified constructor\n const ctor = o.constructor\n if (typeof ctor === 'undefined') {\n return true\n }\n\n // If has modified prototype\n const prot = ctor.prototype\n if (!hasObjectPrototype(prot)) {\n return false\n }\n\n // If constructor does not have an Object-specific method\n if (!prot.hasOwnProperty('isPrototypeOf')) {\n return false\n }\n\n // Most likely a plain Object\n return true\n}\n\nfunction hasObjectPrototype(o: any) {\n return Object.prototype.toString.call(o) === '[object Object]'\n}\n\nexport function isPlainArray(value: unknown) {\n return Array.isArray(value) && value.length === Object.keys(value).length\n}\n\nexport function deepEqual(a: any, b: any, partial: boolean = false): boolean {\n if (a === b) {\n return true\n }\n\n if (typeof a !== typeof b) {\n return false\n }\n\n if (isPlainObject(a) && isPlainObject(b)) {\n const aKeys = Object.keys(a)\n const bKeys = Object.keys(b)\n\n if (!partial && aKeys.length !== bKeys.length) {\n return false\n }\n\n return !bKeys.some(\n (key) => !(key in a) || !deepEqual(a[key], b[key], partial),\n )\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n return !a.some((item, index) => !deepEqual(item, b[index], partial))\n }\n\n return false\n}\n\nexport function useStableCallback<T extends (...args: Array<any>) => any>(\n fn: T,\n): T {\n const fnRef = React.useRef(fn)\n fnRef.current = fn\n\n const ref = React.useRef((...args: Array<any>) => fnRef.current(...args))\n return ref.current as T\n}\n\nexport function shallow<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n const keysA = Object.keys(objA)\n if (keysA.length !== Object.keys(objB).length) {\n return false\n }\n\n for (const item of keysA) {\n if (\n !Object.prototype.hasOwnProperty.call(objB, item) ||\n !Object.is(objA[item as keyof T], objB[item as keyof T])\n ) {\n return false\n }\n }\n return true\n}\n\nexport type StringLiteral<T> = T extends string\n ? string extends T\n ? string\n : T\n : never\n\nexport type StrictOrFrom<\n TFrom,\n TStrict extends boolean = true,\n> = TStrict extends false\n ? {\n from?: never\n strict: TStrict\n }\n : {\n from: StringLiteral<TFrom> | TFrom\n strict?: TStrict\n }\n\nexport const useLayoutEffect =\n typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect\n\n/**\n *\n * @deprecated use `jsesc` instead\n */\nexport function escapeJSON(jsonString: string) {\n return jsonString\n .replace(/\\\\/g, '\\\\\\\\') // Escape backslashes\n .replace(/'/g, \"\\\\'\") // Escape single quotes\n .replace(/\"/g, '\\\\\"') // Escape double quotes\n}\n\nexport function removeTrailingSlash(value: string): string {\n if (value.endsWith('/') && value !== '/') {\n return value.slice(0, -1)\n }\n return value\n}\n\n// intended to only compare path name\n// see the usage in the isActive under useLinkProps\n// /sample/path1 = /sample/path1/\n// /sample/path1/some <> /sample/path1\nexport function exactPathTest(pathName1: string, pathName2: string): boolean {\n return removeTrailingSlash(pathName1) === removeTrailingSlash(pathName2)\n}\n\nexport type ControlledPromise<T> = Promise<T> & {\n resolve: (value: T) => void\n reject: (value: any) => void\n status: 'pending' | 'resolved' | 'rejected'\n}\n\nexport function createControlledPromise<T>(onResolve?: () => void) {\n let resolveLoadPromise!: () => void\n let rejectLoadPromise!: (value: any) => void\n\n const controlledPromise = new Promise<void>((resolve, reject) => {\n resolveLoadPromise = resolve\n rejectLoadPromise = reject\n }) as ControlledPromise<T>\n\n controlledPromise.status = 'pending'\n\n controlledPromise.resolve = () => {\n controlledPromise.status = 'resolved'\n resolveLoadPromise()\n onResolve?.()\n }\n\n controlledPromise.reject = (e) => {\n controlledPromise.status = 'rejected'\n rejectLoadPromise(e)\n }\n\n return controlledPromise\n}\n\n/**\n * Taken from https://www.developerway.com/posts/implementing-advanced-use-previous-hook#part3\n */\nexport function usePrevious<T>(value: T): T | null {\n // initialise the ref with previous and current values\n const ref = React.useRef<{ value: T; prev: T | null }>({\n value: value,\n prev: null,\n })\n\n const current = ref.current.value\n\n // if the value passed into hook doesn't match what we store as \"current\"\n // move the \"current\" to the \"previous\"\n // and store the passed value as \"current\"\n if (value !== current) {\n ref.current = {\n value: value,\n prev: current,\n }\n }\n\n // return the previous value only\n return ref.current.prev\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/index.tsx
CHANGED
package/src/link.tsx
CHANGED
|
@@ -8,9 +8,10 @@ import type { AnyRouter, ParsedLocation } from '.'
|
|
|
8
8
|
import type { HistoryState } from '@tanstack/history'
|
|
9
9
|
import type { AnyRoute, RootSearchSchema } from './route'
|
|
10
10
|
import type {
|
|
11
|
+
AllParams,
|
|
11
12
|
CatchAllPaths,
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
FullSearchSchema,
|
|
14
|
+
FullSearchSchemaInput,
|
|
14
15
|
RouteByPath,
|
|
15
16
|
RouteByToPath,
|
|
16
17
|
RoutePaths,
|
|
@@ -257,15 +258,11 @@ export type ResolveRoute<
|
|
|
257
258
|
TFrom,
|
|
258
259
|
TTo,
|
|
259
260
|
TPath = ResolveRelativePath<TFrom, TTo>,
|
|
260
|
-
> =
|
|
261
|
-
?
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
? string extends TTo
|
|
266
|
-
? RouteByPath<TRouter['routeTree'], TPath>
|
|
267
|
-
: RouteByToPath<TRouter, TPath>
|
|
268
|
-
: never
|
|
261
|
+
> = TPath extends string
|
|
262
|
+
? string extends TTo
|
|
263
|
+
? RouteByPath<TRouter['routeTree'], TPath>
|
|
264
|
+
: RouteByToPath<TRouter, TPath>
|
|
265
|
+
: never
|
|
269
266
|
|
|
270
267
|
type PostProcessParams<
|
|
271
268
|
T,
|
|
@@ -275,17 +272,19 @@ type PostProcessParams<
|
|
|
275
272
|
type ResolveFromParamType<TParamVariant extends ParamVariant> =
|
|
276
273
|
TParamVariant extends 'PATH' ? 'allParams' : 'fullSearchSchema'
|
|
277
274
|
|
|
275
|
+
type ResolveFromAllParams<
|
|
276
|
+
TRouter extends AnyRouter,
|
|
277
|
+
TParamVariant extends ParamVariant,
|
|
278
|
+
> = TParamVariant extends 'PATH'
|
|
279
|
+
? AllParams<TRouter['routeTree']>
|
|
280
|
+
: FullSearchSchema<TRouter['routeTree']>
|
|
281
|
+
|
|
278
282
|
type ResolveFromParams<
|
|
279
283
|
TRouter extends AnyRouter,
|
|
280
284
|
TParamVariant extends ParamVariant,
|
|
281
285
|
TFrom,
|
|
282
286
|
> = string extends TFrom
|
|
283
|
-
?
|
|
284
|
-
ParseRoute<
|
|
285
|
-
TRouter['routeTree']
|
|
286
|
-
>['types'][ResolveFromParamType<TParamVariant>],
|
|
287
|
-
TParamVariant
|
|
288
|
-
>
|
|
287
|
+
? ResolveFromAllParams<TRouter, TParamVariant>
|
|
289
288
|
: RouteByPath<
|
|
290
289
|
TRouter['routeTree'],
|
|
291
290
|
TFrom
|
|
@@ -294,16 +293,33 @@ type ResolveFromParams<
|
|
|
294
293
|
type ResolveToParamType<TParamVariant extends ParamVariant> =
|
|
295
294
|
TParamVariant extends 'PATH' ? 'allParams' : 'fullSearchSchemaInput'
|
|
296
295
|
|
|
296
|
+
type ResolveAllToParams<
|
|
297
|
+
TRouter extends AnyRouter,
|
|
298
|
+
TParamVariant extends ParamVariant,
|
|
299
|
+
> = TParamVariant extends 'PATH'
|
|
300
|
+
? AllParams<TRouter['routeTree']>
|
|
301
|
+
: FullSearchSchemaInput<TRouter['routeTree']>
|
|
302
|
+
|
|
297
303
|
export type ResolveToParams<
|
|
298
304
|
TRouter extends AnyRouter,
|
|
299
305
|
TParamVariant extends ParamVariant,
|
|
300
306
|
TFrom,
|
|
301
307
|
TTo,
|
|
302
|
-
|
|
303
|
-
>
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
308
|
+
> =
|
|
309
|
+
ResolveRelativePath<TFrom, TTo> extends infer TPath
|
|
310
|
+
? string extends TPath
|
|
311
|
+
? ResolveAllToParams<TRouter, TParamVariant>
|
|
312
|
+
: TPath extends CatchAllPaths
|
|
313
|
+
? ResolveAllToParams<TRouter, TParamVariant>
|
|
314
|
+
: PostProcessParams<
|
|
315
|
+
ResolveRoute<
|
|
316
|
+
TRouter,
|
|
317
|
+
TFrom,
|
|
318
|
+
TTo
|
|
319
|
+
>['types'][ResolveToParamType<TParamVariant>],
|
|
320
|
+
TParamVariant
|
|
321
|
+
>
|
|
322
|
+
: never
|
|
307
323
|
|
|
308
324
|
type ResolveRelativeToParams<
|
|
309
325
|
TRouter extends AnyRouter,
|
|
@@ -369,14 +385,8 @@ export interface MakeRequiredSearchParams<
|
|
|
369
385
|
search: MakeRequiredParamsReducer<TRouter, 'SEARCH', TFrom, TTo> & {}
|
|
370
386
|
}
|
|
371
387
|
|
|
372
|
-
export type IsRequiredParams<TParams> =
|
|
373
|
-
|
|
374
|
-
? K extends any
|
|
375
|
-
? undefined extends TParams[K]
|
|
376
|
-
? never
|
|
377
|
-
: true
|
|
378
|
-
: never
|
|
379
|
-
: never
|
|
388
|
+
export type IsRequiredParams<TParams> =
|
|
389
|
+
Record<never, never> extends TParams ? never : true
|
|
380
390
|
|
|
381
391
|
export type IsRequired<
|
|
382
392
|
TRouter extends AnyRouter,
|
|
@@ -384,13 +394,15 @@ export type IsRequired<
|
|
|
384
394
|
TFrom,
|
|
385
395
|
TTo,
|
|
386
396
|
> =
|
|
387
|
-
|
|
388
|
-
?
|
|
389
|
-
: ResolveRelativePath<TFrom, TTo> extends CatchAllPaths
|
|
397
|
+
ResolveRelativePath<TFrom, TTo> extends infer TPath
|
|
398
|
+
? string extends TPath
|
|
390
399
|
? never
|
|
391
|
-
:
|
|
392
|
-
|
|
393
|
-
|
|
400
|
+
: TPath extends CatchAllPaths
|
|
401
|
+
? never
|
|
402
|
+
: IsRequiredParams<
|
|
403
|
+
ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>
|
|
404
|
+
>
|
|
405
|
+
: never
|
|
394
406
|
|
|
395
407
|
export type SearchParamOptions<
|
|
396
408
|
TRouter extends AnyRouter,
|
|
@@ -585,7 +597,6 @@ export function useLinkProps<
|
|
|
585
597
|
// null for LinkUtils
|
|
586
598
|
|
|
587
599
|
const dest = {
|
|
588
|
-
...(options.to && { from: matchPathname }),
|
|
589
600
|
...options,
|
|
590
601
|
}
|
|
591
602
|
|
package/src/route.ts
CHANGED
|
@@ -16,14 +16,7 @@ import type { NavigateOptions, ParsePathParams, ToSubOptions } from './link'
|
|
|
16
16
|
import type { ParsedLocation } from './location'
|
|
17
17
|
import type { RouteById, RouteIds, RoutePaths } from './routeInfo'
|
|
18
18
|
import type { AnyRouter, RegisteredRouter, Router } from './router'
|
|
19
|
-
import type {
|
|
20
|
-
Assign,
|
|
21
|
-
Expand,
|
|
22
|
-
IsAny,
|
|
23
|
-
NoInfer,
|
|
24
|
-
PickRequired,
|
|
25
|
-
UnionToIntersection,
|
|
26
|
-
} from './utils'
|
|
19
|
+
import type { Assign, Expand, IsAny, NoInfer, PickRequired } from './utils'
|
|
27
20
|
import type { BuildLocationFn, NavigateFn } from './RouterProvider'
|
|
28
21
|
import type { NotFoundError } from './not-found'
|
|
29
22
|
import type { LazyRoute } from './fileRoute'
|
|
@@ -52,8 +45,10 @@ export type RoutePathOptions<TCustomId, TPath> =
|
|
|
52
45
|
|
|
53
46
|
export interface StaticDataRouteOption {}
|
|
54
47
|
|
|
55
|
-
export type RoutePathOptionsIntersection<TCustomId, TPath> =
|
|
56
|
-
|
|
48
|
+
export type RoutePathOptionsIntersection<TCustomId, TPath> = {
|
|
49
|
+
path: TPath
|
|
50
|
+
id: TCustomId
|
|
51
|
+
}
|
|
57
52
|
|
|
58
53
|
export type RouteOptions<
|
|
59
54
|
TParentRoute extends AnyRoute = AnyRoute,
|
|
@@ -474,11 +469,6 @@ export type ResolveAllParamsFromParent<
|
|
|
474
469
|
? TParams
|
|
475
470
|
: Assign<TParentRoute['types']['allParams'], TParams>
|
|
476
471
|
|
|
477
|
-
export type ResolveAllParams<TParentRoute extends AnyRoute, TParams> =
|
|
478
|
-
Record<never, string> extends TParentRoute['types']['allParams']
|
|
479
|
-
? TParams
|
|
480
|
-
: UnionToIntersection<TParentRoute['types']['allParams'] & TParams> & {}
|
|
481
|
-
|
|
482
472
|
export type RouteConstraints = {
|
|
483
473
|
TParentRoute: AnyRoute
|
|
484
474
|
TPath: string
|
|
@@ -618,7 +608,7 @@ export class Route<
|
|
|
618
608
|
TSearchSchema
|
|
619
609
|
>,
|
|
620
610
|
in out TParams = Record<ParsePathParams<TPath>, string>,
|
|
621
|
-
in out TAllParams =
|
|
611
|
+
in out TAllParams = ResolveAllParamsFromParent<TParentRoute, TParams>,
|
|
622
612
|
TRouteContextReturn = RouteContext,
|
|
623
613
|
in out TRouteContext = ResolveRouteContext<TRouteContextReturn>,
|
|
624
614
|
in out TAllContext = Assign<
|
|
@@ -960,7 +950,7 @@ export function createRoute<
|
|
|
960
950
|
>,
|
|
961
951
|
TFullSearchSchema = ResolveFullSearchSchema<TParentRoute, TSearchSchema>,
|
|
962
952
|
TParams = Record<ParsePathParams<TPath>, string>,
|
|
963
|
-
TAllParams =
|
|
953
|
+
TAllParams = ResolveAllParamsFromParent<TParentRoute, TParams>,
|
|
964
954
|
TRouteContextReturn = RouteContext,
|
|
965
955
|
TRouteContext = ResolveRouteContext<TRouteContextReturn>,
|
|
966
956
|
TAllContext = Assign<
|
package/src/routeInfo.ts
CHANGED
|
@@ -114,20 +114,25 @@ export type RouteByToPath<TRouter extends AnyRouter, TTo> = Extract<
|
|
|
114
114
|
AnyRoute
|
|
115
115
|
>
|
|
116
116
|
|
|
117
|
-
export type FullSearchSchema<TRouteTree extends AnyRoute> =
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
export type FullSearchSchema<TRouteTree extends AnyRoute> = MergeUnion<
|
|
118
|
+
Exclude<ParseRoute<TRouteTree>['types']['fullSearchSchema'], RootSearchSchema>
|
|
119
|
+
>
|
|
120
|
+
|
|
121
|
+
export type FullSearchSchemaInput<TRouteTree extends AnyRoute> = MergeUnion<
|
|
122
|
+
Exclude<
|
|
123
|
+
ParseRoute<TRouteTree>['types']['fullSearchSchemaInput'],
|
|
124
|
+
RootSearchSchema
|
|
120
125
|
>
|
|
121
126
|
>
|
|
122
127
|
|
|
123
|
-
export type AllParams<TRouteTree extends AnyRoute> =
|
|
124
|
-
|
|
128
|
+
export type AllParams<TRouteTree extends AnyRoute> = MergeUnion<
|
|
129
|
+
ParseRoute<TRouteTree>['types']['allParams']
|
|
125
130
|
>
|
|
126
131
|
|
|
127
|
-
export type AllContext<TRouteTree extends AnyRoute> =
|
|
128
|
-
|
|
132
|
+
export type AllContext<TRouteTree extends AnyRoute> = MergeUnion<
|
|
133
|
+
ParseRoute<TRouteTree>['types']['allContext']
|
|
129
134
|
>
|
|
130
135
|
|
|
131
|
-
export type AllLoaderData<TRouteTree extends AnyRoute> =
|
|
132
|
-
|
|
136
|
+
export type AllLoaderData<TRouteTree extends AnyRoute> = MergeUnion<
|
|
137
|
+
ParseRoute<TRouteTree>['types']['loaderData']
|
|
133
138
|
>
|
package/src/router.ts
CHANGED
|
@@ -1102,14 +1102,27 @@ export class Router<
|
|
|
1102
1102
|
): ParsedLocation => {
|
|
1103
1103
|
let fromPath = this.latestLocation.pathname
|
|
1104
1104
|
let fromSearch = dest.fromSearch || this.latestLocation.search
|
|
1105
|
+
const looseRoutesByPath = this.routesByPath as Record<string, AnyRoute>
|
|
1106
|
+
|
|
1107
|
+
const fromRoute =
|
|
1108
|
+
dest.from !== undefined
|
|
1109
|
+
? looseRoutesByPath[trimPathRight(dest.from)]
|
|
1110
|
+
: undefined
|
|
1105
1111
|
|
|
1106
1112
|
const fromMatches = this.matchRoutes(
|
|
1107
1113
|
this.latestLocation.pathname,
|
|
1108
1114
|
fromSearch,
|
|
1109
1115
|
)
|
|
1110
1116
|
|
|
1111
|
-
|
|
1112
|
-
|
|
1117
|
+
const fromMatch = fromMatches.find((d) => d.routeId === fromRoute?.id)
|
|
1118
|
+
|
|
1119
|
+
fromPath = fromMatch?.pathname || fromPath
|
|
1120
|
+
|
|
1121
|
+
invariant(
|
|
1122
|
+
dest.from == null || fromMatch != null,
|
|
1123
|
+
'Could not find match for from: ' + dest.from,
|
|
1124
|
+
)
|
|
1125
|
+
|
|
1113
1126
|
fromSearch = last(fromMatches)?.search || this.latestLocation.search
|
|
1114
1127
|
|
|
1115
1128
|
const stayingMatches = matches?.filter((d) =>
|
|
@@ -1773,8 +1786,7 @@ export class Router<
|
|
|
1773
1786
|
preload: !!preload,
|
|
1774
1787
|
context: parentContext,
|
|
1775
1788
|
location,
|
|
1776
|
-
navigate: (opts: any) =>
|
|
1777
|
-
this.navigate({ ...opts, from: match.pathname }),
|
|
1789
|
+
navigate: (opts: any) => this.navigate({ ...opts }),
|
|
1778
1790
|
buildLocation: this.buildLocation,
|
|
1779
1791
|
cause: preload ? 'preload' : match.cause,
|
|
1780
1792
|
})) ?? ({} as any)
|
|
@@ -1827,8 +1839,7 @@ export class Router<
|
|
|
1827
1839
|
abortController: match.abortController,
|
|
1828
1840
|
context: match.context,
|
|
1829
1841
|
location,
|
|
1830
|
-
navigate: (opts) =>
|
|
1831
|
-
this.navigate({ ...opts, from: match.pathname } as any),
|
|
1842
|
+
navigate: (opts) => this.navigate({ ...opts } as any),
|
|
1832
1843
|
cause: preload ? 'preload' : match.cause,
|
|
1833
1844
|
route,
|
|
1834
1845
|
}
|
package/src/useNavigate.tsx
CHANGED
|
@@ -29,7 +29,6 @@ export function useNavigate<
|
|
|
29
29
|
(options: NavigateOptions) => {
|
|
30
30
|
return router.navigate({
|
|
31
31
|
...options,
|
|
32
|
-
from: options.to ? router.state.resolvedLocation.pathname : undefined,
|
|
33
32
|
})
|
|
34
33
|
},
|
|
35
34
|
[router],
|
|
@@ -63,7 +62,6 @@ export function Navigate<
|
|
|
63
62
|
|
|
64
63
|
React.useEffect(() => {
|
|
65
64
|
navigate({
|
|
66
|
-
from: props.to ? match.pathname : undefined,
|
|
67
65
|
...props,
|
|
68
66
|
} as any)
|
|
69
67
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
package/src/utils.ts
CHANGED
|
@@ -26,12 +26,6 @@ export type Expand<T> = T extends object
|
|
|
26
26
|
: never
|
|
27
27
|
: T
|
|
28
28
|
|
|
29
|
-
export type UnionToIntersection<T> = (
|
|
30
|
-
T extends any ? (k: T) => void : never
|
|
31
|
-
) extends (k: infer I) => any
|
|
32
|
-
? I
|
|
33
|
-
: never
|
|
34
|
-
|
|
35
29
|
export type DeepPartial<T> = T extends object
|
|
36
30
|
? {
|
|
37
31
|
[P in keyof T]?: DeepPartial<T[P]>
|
|
@@ -100,7 +94,7 @@ export type MergeUnionPrimitives<TUnion> = TUnion extends MergeUnionPrimitive
|
|
|
100
94
|
|
|
101
95
|
export type MergeUnion<TUnion> =
|
|
102
96
|
| MergeUnionPrimitives<TUnion>
|
|
103
|
-
| MergeUnionObject<
|
|
97
|
+
| MergeUnionObject<TUnion>
|
|
104
98
|
|
|
105
99
|
export function last<T>(arr: Array<T>) {
|
|
106
100
|
return arr[arr.length - 1]
|