@tanstack/react-router 1.90.0 → 1.91.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.
@@ -0,0 +1,62 @@
1
+ import { FromPathOption, NavigateOptions, PathParamOptions, SearchParamOptions, ToPathOption } from './link.js';
2
+ import { RouteIds } from './routeInfo.js';
3
+ import { AnyRouter, RegisteredRouter } from './router.js';
4
+ import { UseParamsOptions, UseParamsResult } from './useParams.js';
5
+ import { UseSearchOptions, UseSearchResult } from './useSearch.js';
6
+ import { Constrain, ConstrainLiteral } from './utils.js';
7
+ export type ValidateFromPath<TFrom, TRouter extends AnyRouter = RegisteredRouter> = FromPathOption<TRouter, TFrom>;
8
+ export type ValidateToPath<TTo extends string | undefined, TFrom extends string = string, TRouter extends AnyRouter = RegisteredRouter> = ToPathOption<TRouter, TFrom, TTo>;
9
+ export type ValidateSearch<TTo extends string | undefined, TFrom extends string = string, TRouter extends AnyRouter = RegisteredRouter> = SearchParamOptions<TRouter, TFrom, TTo>;
10
+ export type ValidateParams<TTo extends string | undefined, TFrom extends string = string, TRouter extends AnyRouter = RegisteredRouter> = PathParamOptions<TRouter, TFrom, TTo>;
11
+ /**
12
+ * @internal
13
+ */
14
+ export type InferFrom<TOptions> = TOptions extends {
15
+ from: infer TFrom extends string;
16
+ } ? TFrom : string;
17
+ /**
18
+ * @internal
19
+ */
20
+ export type InferTo<TOptions> = TOptions extends {
21
+ to: infer TTo extends string;
22
+ } ? TTo : undefined;
23
+ /**
24
+ * @internal
25
+ */
26
+ export type InferMaskTo<TOptions> = TOptions extends {
27
+ mask: {
28
+ to: infer TTo extends string;
29
+ };
30
+ } ? TTo : string;
31
+ export type InferMaskFrom<TOptions> = TOptions extends {
32
+ mask: {
33
+ from: infer TFrom extends string;
34
+ };
35
+ } ? TFrom : string;
36
+ export type ValidateNavigateOptions<TOptions, TRouter extends AnyRouter = RegisteredRouter> = Constrain<TOptions, NavigateOptions<TRouter, InferFrom<TOptions>, InferTo<TOptions>, InferMaskFrom<TOptions>, InferMaskTo<TOptions>>>;
37
+ export type ValidateNavigateOptionsArray<TOptions extends ReadonlyArray<any>> = {
38
+ [K in keyof TOptions]: ValidateNavigateOptions<TOptions[K]>;
39
+ };
40
+ export type ValidateId<TId extends string, TRouter extends AnyRouter = RegisteredRouter> = ConstrainLiteral<TId, RouteIds<TRouter['routeTree']>>;
41
+ /**
42
+ * @internal
43
+ */
44
+ export type InferStrict<TOptions> = TOptions extends {
45
+ strict: infer TStrict extends boolean;
46
+ } ? TStrict : true;
47
+ /**
48
+ * @internal
49
+ */
50
+ export type InferSelected<TOptions> = TOptions extends {
51
+ select: (...args: Array<any>) => infer TSelected;
52
+ } ? TSelected : unknown;
53
+ /**
54
+ * @internal
55
+ */
56
+ export type InferStructuralSharing<TOptions> = TOptions extends {
57
+ structuralSharing: infer TStructuralSharing;
58
+ } ? TStructuralSharing : unknown;
59
+ export type ValidateUseSearchOptions<TOptions, TRouter extends AnyRouter = RegisteredRouter> = Constrain<TOptions, UseSearchOptions<TRouter, InferFrom<TOptions>, InferStrict<TOptions>, InferSelected<TOptions>, InferStructuralSharing<TOptions>>>;
60
+ export type ValidateUseSearchResult<TOptions, TRouter extends AnyRouter = RegisteredRouter> = UseSearchResult<TRouter, InferFrom<TOptions>, InferStrict<TOptions>, InferSelected<TOptions>>;
61
+ export type ValidateUseParamsOptions<TOptions, TRouter extends AnyRouter = RegisteredRouter> = Constrain<TOptions, UseParamsOptions<TRouter, InferFrom<TOptions>, InferStrict<TOptions>, InferSelected<TOptions>, InferSelected<TOptions>>>;
62
+ export type ValidateUseParamsResult<TOptions, TRouter extends AnyRouter = RegisteredRouter> = Constrain<TOptions, UseParamsResult<TRouter, InferFrom<TOptions>, InferStrict<TOptions>, InferSelected<TOptions>>>;
@@ -32,6 +32,8 @@ export type PartialMergeAllObject<TUnion> = ExtractObjects<TUnion> extends infer
32
32
  export type MergeAllPrimitive = ReadonlyArray<any> | number | string | bigint | boolean | symbol | undefined | null;
33
33
  export type ExtractPrimitives<TUnion> = TUnion extends MergeAllPrimitive ? TUnion : TUnion extends object ? never : TUnion;
34
34
  export type PartialMergeAll<TUnion> = ExtractPrimitives<TUnion> | PartialMergeAllObject<TUnion>;
35
+ export type Constrain<T, TConstraint, TDefault = TConstraint> = (T extends TConstraint ? T : never) | TDefault;
36
+ export type ConstrainLiteral<T, TConstraint, TDefault = TConstraint> = (T & TConstraint) | TDefault;
35
37
  /**
36
38
  * To be added to router types
37
39
  */
@@ -44,7 +46,6 @@ export type MergeAllObjects<TUnion, TIntersected = UnionToIntersection<ExtractOb
44
46
  [TKey in keyof TIntersected]: TUnion extends any ? TUnion[TKey & keyof TUnion] : never;
45
47
  };
46
48
  export type MergeAll<TUnion> = MergeAllObjects<TUnion> | ExtractPrimitives<TUnion>;
47
- export type Constrain<T, TConstraint, TDefault = TConstraint> = (T extends TConstraint ? T : never) | TDefault;
48
49
  export type ValidateJSON<T> = ((...args: Array<any>) => any) extends T ? unknown extends T ? never : 'Function is not serializable' : {
49
50
  [K in keyof T]: ValidateJSON<T[K]>;
50
51
  };
@@ -71,7 +72,7 @@ export type StrictOrFrom<TRouter extends AnyRouter, TFrom, TStrict extends boole
71
72
  from?: never;
72
73
  strict: TStrict;
73
74
  } : {
74
- from: StringLiteral<Constrain<TFrom, RouteIds<TRouter['routeTree']>>>;
75
+ from: ConstrainLiteral<TFrom, RouteIds<TRouter['routeTree']>>;
75
76
  strict?: TStrict;
76
77
  };
77
78
  export type ThrowOrOptional<T, TThrow extends boolean> = TThrow extends true ? T : T | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["import * as React from 'react'\nimport type { RouteIds } from './routeInfo'\nimport type { AnyRouter } from './router'\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\n\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\nexport type PickOptional<T> = {\n [K in keyof T as undefined extends T[K] ? K : never]: 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> = TLeft extends any\n ? TRight extends any\n ? keyof TLeft extends never\n ? TRight\n : keyof TRight extends never\n ? TLeft\n : keyof TLeft & keyof TRight extends never\n ? TLeft & TRight\n : Omit<TLeft, keyof TRight> & TRight\n : never\n : never\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 ExtractObjects<TUnion> = TUnion extends MergeAllPrimitive\n ? never\n : TUnion\n\nexport type PartialMergeAllObject<TUnion> =\n ExtractObjects<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 MergeAllPrimitive =\n | ReadonlyArray<any>\n | number\n | string\n | bigint\n | boolean\n | symbol\n | undefined\n | null\n\nexport type ExtractPrimitives<TUnion> = TUnion extends MergeAllPrimitive\n ? TUnion\n : TUnion extends object\n ? never\n : TUnion\n\nexport type PartialMergeAll<TUnion> =\n | ExtractPrimitives<TUnion>\n | PartialMergeAllObject<TUnion>\n\n/**\n * To be added to router types\n */\nexport type UnionToIntersection<T> = (\n T extends any ? (arg: T) => any : never\n) extends (arg: infer T) => any\n ? T\n : never\n\n/**\n * Merges everything in a union into one object.\n * This mapped type is homomorphic which means it preserves stuff! :)\n */\nexport type MergeAllObjects<\n TUnion,\n TIntersected = UnionToIntersection<ExtractObjects<TUnion>>,\n> = [keyof TIntersected] extends [never]\n ? never\n : {\n [TKey in keyof TIntersected]: TUnion extends any\n ? TUnion[TKey & keyof TUnion]\n : never\n }\n\nexport type MergeAll<TUnion> =\n | MergeAllObjects<TUnion>\n | ExtractPrimitives<TUnion>\n\nexport type Constrain<T, TConstraint, TDefault = TConstraint> =\n | (T extends TConstraint ? T : never)\n | TDefault\n\nexport type ValidateJSON<T> = ((...args: Array<any>) => any) extends T\n ? unknown extends T\n ? never\n : 'Function is not serializable'\n : { [K in keyof T]: ValidateJSON<T[K]> }\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] as any)\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): value is Array<unknown> {\n return Array.isArray(value) && value.length === Object.keys(value).length\n}\n\nfunction getObjectKeys(obj: any, ignoreUndefined: boolean) {\n let keys = Object.keys(obj)\n if (ignoreUndefined) {\n keys = keys.filter((key) => obj[key] !== undefined)\n }\n return keys\n}\n\nexport function deepEqual(\n a: any,\n b: any,\n opts?: { partial?: boolean; ignoreUndefined?: boolean },\n): 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 ignoreUndefined = opts?.ignoreUndefined ?? true\n const aKeys = getObjectKeys(a, ignoreUndefined)\n const bKeys = getObjectKeys(b, ignoreUndefined)\n\n if (!opts?.partial && aKeys.length !== bKeys.length) {\n return false\n }\n\n return bKeys.every((key) => deepEqual(a[key], b[key], opts))\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return false\n }\n return !a.some((item, index) => !deepEqual(item, b[index], opts))\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 TRouter extends AnyRouter,\n TFrom,\n TStrict extends boolean = true,\n> = TStrict extends false\n ? {\n from?: never\n strict: TStrict\n }\n : {\n from: StringLiteral<Constrain<TFrom, RouteIds<TRouter['routeTree']>>>\n strict?: TStrict\n }\n\nexport type ThrowOrOptional<T, TThrow extends boolean> = TThrow extends true\n ? T\n : T | undefined\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 type ControlledPromise<T> = Promise<T> & {\n resolve: (value: T) => void\n reject: (value: any) => void\n status: 'pending' | 'resolved' | 'rejected'\n value?: T\n}\n\nexport function createControlledPromise<T>(onResolve?: (value: T) => void) {\n let resolveLoadPromise!: (value: T) => void\n let rejectLoadPromise!: (value: any) => void\n\n const controlledPromise = new Promise<T>((resolve, reject) => {\n resolveLoadPromise = resolve\n rejectLoadPromise = reject\n }) as ControlledPromise<T>\n\n controlledPromise.status = 'pending'\n\n controlledPromise.resolve = (value: T) => {\n controlledPromise.status = 'resolved'\n controlledPromise.value = value\n resolveLoadPromise(value)\n onResolve?.(value)\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\n/**\n * React hook to wrap `IntersectionObserver`.\n *\n * This hook will create an `IntersectionObserver` and observe the ref passed to it.\n *\n * When the intersection changes, the callback will be called with the `IntersectionObserverEntry`.\n *\n * @param ref - The ref to observe\n * @param intersectionObserverOptions - The options to pass to the IntersectionObserver\n * @param options - The options to pass to the hook\n * @param callback - The callback to call when the intersection changes\n * @returns The IntersectionObserver instance\n * @example\n * ```tsx\n * const MyComponent = () => {\n * const ref = React.useRef<HTMLDivElement>(null)\n * useIntersectionObserver(\n * ref,\n * (entry) => { doSomething(entry) },\n * { rootMargin: '10px' },\n * { disabled: false }\n * )\n * return <div ref={ref} />\n * ```\n */\nexport function useIntersectionObserver<T extends Element>(\n ref: React.RefObject<T>,\n callback: (entry: IntersectionObserverEntry | undefined) => void,\n intersectionObserverOptions: IntersectionObserverInit = {},\n options: { disabled?: boolean } = {},\n): IntersectionObserver | null {\n const isIntersectionObserverAvailable = React.useRef(\n typeof IntersectionObserver === 'function',\n )\n\n const observerRef = React.useRef<IntersectionObserver | null>(null)\n\n React.useEffect(() => {\n if (\n !ref.current ||\n !isIntersectionObserverAvailable.current ||\n options.disabled\n ) {\n return\n }\n\n observerRef.current = new IntersectionObserver(([entry]) => {\n callback(entry)\n }, intersectionObserverOptions)\n\n observerRef.current.observe(ref.current)\n\n return () => {\n observerRef.current?.disconnect()\n }\n }, [callback, intersectionObserverOptions, options.disabled, ref])\n\n return observerRef.current\n}\n\n/**\n * React hook to take a `React.ForwardedRef` and returns a `ref` that can be used on a DOM element.\n *\n * @param ref - The forwarded ref\n * @returns The inner ref returned by `useRef`\n * @example\n * ```tsx\n * const MyComponent = React.forwardRef((props, ref) => {\n * const innerRef = useForwardedRef(ref)\n * return <div ref={innerRef} />\n * })\n * ```\n */\nexport function useForwardedRef<T>(ref?: React.ForwardedRef<T>) {\n const innerRef = React.useRef<T>(null)\n\n React.useEffect(() => {\n if (!ref) return\n if (typeof ref === 'function') {\n ref(innerRef.current)\n } else {\n ref.current = innerRef.current\n }\n })\n\n return innerRef\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["import * as React from 'react'\nimport type { RouteIds } from './routeInfo'\nimport type { AnyRouter } from './router'\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\n\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\nexport type PickOptional<T> = {\n [K in keyof T as undefined extends T[K] ? K : never]: 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> = TLeft extends any\n ? TRight extends any\n ? keyof TLeft extends never\n ? TRight\n : keyof TRight extends never\n ? TLeft\n : keyof TLeft & keyof TRight extends never\n ? TLeft & TRight\n : Omit<TLeft, keyof TRight> & TRight\n : never\n : never\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 ExtractObjects<TUnion> = TUnion extends MergeAllPrimitive\n ? never\n : TUnion\n\nexport type PartialMergeAllObject<TUnion> =\n ExtractObjects<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 MergeAllPrimitive =\n | ReadonlyArray<any>\n | number\n | string\n | bigint\n | boolean\n | symbol\n | undefined\n | null\n\nexport type ExtractPrimitives<TUnion> = TUnion extends MergeAllPrimitive\n ? TUnion\n : TUnion extends object\n ? never\n : TUnion\n\nexport type PartialMergeAll<TUnion> =\n | ExtractPrimitives<TUnion>\n | PartialMergeAllObject<TUnion>\n\nexport type Constrain<T, TConstraint, TDefault = TConstraint> =\n | (T extends TConstraint ? T : never)\n | TDefault\n\nexport type ConstrainLiteral<T, TConstraint, TDefault = TConstraint> =\n | (T & TConstraint)\n | TDefault\n\n/**\n * To be added to router types\n */\nexport type UnionToIntersection<T> = (\n T extends any ? (arg: T) => any : never\n) extends (arg: infer T) => any\n ? T\n : never\n\n/**\n * Merges everything in a union into one object.\n * This mapped type is homomorphic which means it preserves stuff! :)\n */\nexport type MergeAllObjects<\n TUnion,\n TIntersected = UnionToIntersection<ExtractObjects<TUnion>>,\n> = [keyof TIntersected] extends [never]\n ? never\n : {\n [TKey in keyof TIntersected]: TUnion extends any\n ? TUnion[TKey & keyof TUnion]\n : never\n }\n\nexport type MergeAll<TUnion> =\n | MergeAllObjects<TUnion>\n | ExtractPrimitives<TUnion>\n\nexport type ValidateJSON<T> = ((...args: Array<any>) => any) extends T\n ? unknown extends T\n ? never\n : 'Function is not serializable'\n : { [K in keyof T]: ValidateJSON<T[K]> }\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] as any)\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): value is Array<unknown> {\n return Array.isArray(value) && value.length === Object.keys(value).length\n}\n\nfunction getObjectKeys(obj: any, ignoreUndefined: boolean) {\n let keys = Object.keys(obj)\n if (ignoreUndefined) {\n keys = keys.filter((key) => obj[key] !== undefined)\n }\n return keys\n}\n\nexport function deepEqual(\n a: any,\n b: any,\n opts?: { partial?: boolean; ignoreUndefined?: boolean },\n): 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 ignoreUndefined = opts?.ignoreUndefined ?? true\n const aKeys = getObjectKeys(a, ignoreUndefined)\n const bKeys = getObjectKeys(b, ignoreUndefined)\n\n if (!opts?.partial && aKeys.length !== bKeys.length) {\n return false\n }\n\n return bKeys.every((key) => deepEqual(a[key], b[key], opts))\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return false\n }\n return !a.some((item, index) => !deepEqual(item, b[index], opts))\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 TRouter extends AnyRouter,\n TFrom,\n TStrict extends boolean = true,\n> = TStrict extends false\n ? {\n from?: never\n strict: TStrict\n }\n : {\n from: ConstrainLiteral<TFrom, RouteIds<TRouter['routeTree']>>\n strict?: TStrict\n }\n\nexport type ThrowOrOptional<T, TThrow extends boolean> = TThrow extends true\n ? T\n : T | undefined\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 type ControlledPromise<T> = Promise<T> & {\n resolve: (value: T) => void\n reject: (value: any) => void\n status: 'pending' | 'resolved' | 'rejected'\n value?: T\n}\n\nexport function createControlledPromise<T>(onResolve?: (value: T) => void) {\n let resolveLoadPromise!: (value: T) => void\n let rejectLoadPromise!: (value: any) => void\n\n const controlledPromise = new Promise<T>((resolve, reject) => {\n resolveLoadPromise = resolve\n rejectLoadPromise = reject\n }) as ControlledPromise<T>\n\n controlledPromise.status = 'pending'\n\n controlledPromise.resolve = (value: T) => {\n controlledPromise.status = 'resolved'\n controlledPromise.value = value\n resolveLoadPromise(value)\n onResolve?.(value)\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\n/**\n * React hook to wrap `IntersectionObserver`.\n *\n * This hook will create an `IntersectionObserver` and observe the ref passed to it.\n *\n * When the intersection changes, the callback will be called with the `IntersectionObserverEntry`.\n *\n * @param ref - The ref to observe\n * @param intersectionObserverOptions - The options to pass to the IntersectionObserver\n * @param options - The options to pass to the hook\n * @param callback - The callback to call when the intersection changes\n * @returns The IntersectionObserver instance\n * @example\n * ```tsx\n * const MyComponent = () => {\n * const ref = React.useRef<HTMLDivElement>(null)\n * useIntersectionObserver(\n * ref,\n * (entry) => { doSomething(entry) },\n * { rootMargin: '10px' },\n * { disabled: false }\n * )\n * return <div ref={ref} />\n * ```\n */\nexport function useIntersectionObserver<T extends Element>(\n ref: React.RefObject<T>,\n callback: (entry: IntersectionObserverEntry | undefined) => void,\n intersectionObserverOptions: IntersectionObserverInit = {},\n options: { disabled?: boolean } = {},\n): IntersectionObserver | null {\n const isIntersectionObserverAvailable = React.useRef(\n typeof IntersectionObserver === 'function',\n )\n\n const observerRef = React.useRef<IntersectionObserver | null>(null)\n\n React.useEffect(() => {\n if (\n !ref.current ||\n !isIntersectionObserverAvailable.current ||\n options.disabled\n ) {\n return\n }\n\n observerRef.current = new IntersectionObserver(([entry]) => {\n callback(entry)\n }, intersectionObserverOptions)\n\n observerRef.current.observe(ref.current)\n\n return () => {\n observerRef.current?.disconnect()\n }\n }, [callback, intersectionObserverOptions, options.disabled, ref])\n\n return observerRef.current\n}\n\n/**\n * React hook to take a `React.ForwardedRef` and returns a `ref` that can be used on a DOM element.\n *\n * @param ref - The forwarded ref\n * @returns The inner ref returned by `useRef`\n * @example\n * ```tsx\n * const MyComponent = React.forwardRef((props, ref) => {\n * const innerRef = useForwardedRef(ref)\n * return <div ref={innerRef} />\n * })\n * ```\n */\nexport function useForwardedRef<T>(ref?: React.ForwardedRef<T>) {\n const innerRef = React.useRef<T>(null)\n\n React.useEffect(() => {\n if (!ref) return\n if (typeof ref === 'function') {\n ref(innerRef.current)\n } else {\n ref.current = innerRef.current\n }\n })\n\n return innerRef\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/react-router",
3
- "version": "1.90.0",
3
+ "version": "1.91.0",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
package/src/index.tsx CHANGED
@@ -44,11 +44,7 @@ export { lazyRouteComponent } from './lazyRouteComponent'
44
44
 
45
45
  export { useLinkProps, createLink, Link, linkOptions } from './link'
46
46
  export type {
47
- CleanPath,
48
- Split,
49
47
  ParsePathParams,
50
- Join,
51
- Last,
52
48
  RemoveTrailingSlashes,
53
49
  RemoveLeadingSlashes,
54
50
  SearchPaths,
@@ -67,7 +63,6 @@ export type {
67
63
  ToPathOption,
68
64
  ActiveOptions,
69
65
  LinkOptions,
70
- CheckPath,
71
66
  ResolveRelativePath,
72
67
  UseLinkPropsOptions,
73
68
  ActiveLinkOptions,
@@ -76,7 +71,6 @@ export type {
76
71
  LinkComponentProps,
77
72
  CreateLinkProps,
78
73
  MakeOptionalPathParams,
79
- CheckFromPath,
80
74
  } from './link'
81
75
 
82
76
  export type { ParsedLocation } from './location'
@@ -375,3 +369,5 @@ export type {
375
369
  } from './validators'
376
370
 
377
371
  export { retainSearchParams, stripSearchParams } from './searchMiddleware'
372
+
373
+ export * from './typePrimitives'
package/src/link.tsx CHANGED
@@ -35,6 +35,7 @@ import type {
35
35
  } from './router'
36
36
  import type {
37
37
  Constrain,
38
+ ConstrainLiteral,
38
39
  Expand,
39
40
  MakeDifferenceOptional,
40
41
  NoInfer,
@@ -45,96 +46,55 @@ import type {
45
46
  } from './utils'
46
47
  import type { ReactNode } from 'react'
47
48
 
48
- export type CleanPath<T extends string> = T extends `${infer L}//${infer R}`
49
- ? CleanPath<`${CleanPath<L>}/${CleanPath<R>}`>
50
- : T extends `${infer L}//`
51
- ? `${CleanPath<L>}/`
52
- : T extends `//${infer L}`
53
- ? `/${CleanPath<L>}`
54
- : T
55
-
56
- export type Split<TValue, TIncludeTrailingSlash = true> = TValue extends unknown
57
- ? string extends TValue
58
- ? Array<string>
59
- : TValue extends string
60
- ? CleanPath<TValue> extends ''
61
- ? []
62
- : TIncludeTrailingSlash extends true
63
- ? CleanPath<TValue> extends `${infer T}/`
64
- ? [...Split<T>, '/']
65
- : CleanPath<TValue> extends `/${infer U}`
66
- ? Split<U>
67
- : CleanPath<TValue> extends `${infer T}/${infer U}`
68
- ? [...Split<T>, ...Split<U>]
69
- : [TValue]
70
- : CleanPath<TValue> extends `${infer T}/${infer U}`
71
- ? [...Split<T>, ...Split<U>]
72
- : TValue extends string
73
- ? [TValue]
74
- : never
75
- : never
76
- : never
77
-
78
- export type ParsePathParams<
79
- T extends string,
80
- TAcc = never,
81
- > = T extends `${string}$${string}`
82
- ? T extends `${string}$${infer TPossiblyParam}`
83
- ? TPossiblyParam extends `${string}/${string}`
84
- ? TPossiblyParam extends `${infer TParam}/${infer TRest}`
85
- ? ParsePathParams<TRest, TParam extends '' ? TAcc : TParam | TAcc>
86
- : never
87
- : TPossiblyParam extends ''
88
- ? TAcc
89
- : TPossiblyParam | TAcc
49
+ export type ParsePathParams<T extends string, TAcc = never> = T &
50
+ `${string}$${string}` extends never
51
+ ? TAcc
52
+ : T extends `${string}$${infer TPossiblyParam}`
53
+ ? TPossiblyParam extends ''
54
+ ? TAcc
55
+ : TPossiblyParam & `${string}/${string}` extends never
56
+ ? TPossiblyParam | TAcc
57
+ : TPossiblyParam extends `${infer TParam}/${infer TRest}`
58
+ ? ParsePathParams<TRest, TParam extends '' ? TAcc : TParam | TAcc>
59
+ : never
90
60
  : TAcc
91
- : TAcc
92
-
93
- export type Join<T, TDelimiter extends string = '/'> = T extends []
94
- ? ''
95
- : T extends [infer L extends string]
96
- ? L
97
- : T extends [
98
- infer L extends string,
99
- ...infer Tail extends [...Array<string>],
100
- ]
101
- ? CleanPath<`${L}${TDelimiter}${Join<Tail>}`>
102
- : never
103
61
 
104
- export type Last<T extends Array<any>> = T extends [...infer _, infer L]
105
- ? L
106
- : never
62
+ export type AddTrailingSlash<T> = T & `${string}/` extends never
63
+ ? `${T & string}/`
64
+ : T
107
65
 
108
- export type AddTrailingSlash<T> = T extends `${string}/` ? T : `${T & string}/`
66
+ export type RemoveTrailingSlashes<T> = T & `${string}/` extends never
67
+ ? T
68
+ : T extends `${infer R}/`
69
+ ? R
70
+ : T
109
71
 
110
- export type RemoveTrailingSlashes<T> = T extends `${infer R}/` ? R : T
72
+ export type AddLeadingSlash<T> = T & `/${string}` extends never
73
+ ? `/${T & string}`
74
+ : T
111
75
 
112
- export type RemoveLeadingSlashes<T> = T extends `/${infer R}` ? R : T
76
+ export type RemoveLeadingSlashes<T> = T & `/${string}` extends never
77
+ ? T
78
+ : T extends `/${infer R}`
79
+ ? R
80
+ : T
113
81
 
114
- export type ResolvePaths<TRouter extends AnyRouter, TSearchPath> =
115
- RouteByPath<
116
- TRouter['routeTree'],
117
- RemoveTrailingSlashes<TSearchPath>
118
- > extends never
119
- ? RouteToPath<TRouter, TRouter['routeTree']>
120
- : RouteToPath<
121
- TRouter,
122
- RouteByPath<TRouter['routeTree'], RemoveTrailingSlashes<TSearchPath>>
123
- >
82
+ export type FindDescendantPaths<
83
+ TRouter extends AnyRouter,
84
+ TPrefix extends string,
85
+ > = `${TPrefix}${string}` & RouteToPath<TRouter>
124
86
 
125
87
  export type SearchPaths<
126
88
  TRouter extends AnyRouter,
127
- TSearchPath extends string,
128
- TPaths = ResolvePaths<TRouter, TSearchPath>,
129
- TPrefix extends string = `${RemoveTrailingSlashes<TSearchPath>}/`,
130
- TFilteredPaths = TPaths & `${TPrefix}${string}`,
131
- > = TFilteredPaths extends `${TPrefix}${infer TRest}` ? TRest : never
89
+ TPrefix extends string,
90
+ TPaths = FindDescendantPaths<TRouter, TPrefix>,
91
+ > = TPaths extends `${TPrefix}${infer TRest}` ? TRest : never
132
92
 
133
93
  export type SearchRelativePathAutoComplete<
134
94
  TRouter extends AnyRouter,
135
95
  TTo extends string,
136
96
  TSearchPath extends string,
137
- > = `${TTo}/${SearchPaths<TRouter, TSearchPath>}`
97
+ > = `${TTo}${SearchPaths<TRouter, TSearchPath>}`
138
98
 
139
99
  export type RelativeToParentPathAutoComplete<
140
100
  TRouter extends AnyRouter,
@@ -153,7 +113,9 @@ export type RelativeToCurrentPathAutoComplete<
153
113
  TRouter extends AnyRouter,
154
114
  TFrom extends string,
155
115
  TTo extends string,
156
- TResolvedPath extends string = ResolveRelativePath<TFrom, TTo>,
116
+ TResolvedPath extends string = RemoveTrailingSlashes<
117
+ ResolveRelativePath<TFrom, TTo>
118
+ >,
157
119
  > =
158
120
  | SearchRelativePathAutoComplete<TRouter, TTo, TResolvedPath>
159
121
  | CurrentPath<TrailingSlashOptionByRouter<TRouter>>
@@ -166,7 +128,7 @@ export type AbsolutePathAutoComplete<
166
128
  ? CurrentPath<TrailingSlashOptionByRouter<TRouter>>
167
129
  : TFrom extends `/`
168
130
  ? never
169
- : SearchPaths<TRouter, TFrom> extends ''
131
+ : FindDescendantPaths<TRouter, TFrom> extends never
170
132
  ? never
171
133
  : CurrentPath<TrailingSlashOptionByRouter<TRouter>>)
172
134
  | (string extends TFrom
@@ -174,7 +136,7 @@ export type AbsolutePathAutoComplete<
174
136
  : TFrom extends `/`
175
137
  ? never
176
138
  : ParentPath<TrailingSlashOptionByRouter<TRouter>>)
177
- | RouteToPath<TRouter, TRouter['routeTree']>
139
+ | RouteToPath<TRouter>
178
140
  | (TFrom extends '/'
179
141
  ? never
180
142
  : string extends TFrom
@@ -185,21 +147,23 @@ export type RelativeToPathAutoComplete<
185
147
  TRouter extends AnyRouter,
186
148
  TFrom extends string,
187
149
  TTo extends string,
188
- > = string extends TFrom
189
- ? AbsolutePathAutoComplete<TRouter, TFrom>
190
- : TTo extends `..${string}`
191
- ? RelativeToParentPathAutoComplete<
192
- TRouter,
193
- TFrom,
194
- RemoveTrailingSlashes<TTo>
195
- >
196
- : TTo extends `.${string}`
197
- ? RelativeToCurrentPathAutoComplete<
150
+ > = string extends TTo
151
+ ? string
152
+ : string extends TFrom
153
+ ? AbsolutePathAutoComplete<TRouter, TFrom>
154
+ : TTo & `..${string}` extends never
155
+ ? TTo & `.${string}` extends never
156
+ ? AbsolutePathAutoComplete<TRouter, TFrom>
157
+ : RelativeToCurrentPathAutoComplete<
158
+ TRouter,
159
+ TFrom,
160
+ RemoveTrailingSlashes<TTo>
161
+ >
162
+ : RelativeToParentPathAutoComplete<
198
163
  TRouter,
199
164
  TFrom,
200
165
  RemoveTrailingSlashes<TTo>
201
166
  >
202
- : AbsolutePathAutoComplete<TRouter, TFrom>
203
167
 
204
168
  export type NavigateOptions<
205
169
  TRouter extends AnyRouter = RegisteredRouter,
@@ -451,33 +415,19 @@ export type ToPathOption<
451
415
  TRouter extends AnyRouter = AnyRouter,
452
416
  TFrom extends string = string,
453
417
  TTo extends string | undefined = string,
454
- > =
455
- | CheckPath<TRouter, TTo, never, TFrom, TTo>
456
- | RelativeToPathAutoComplete<
457
- TRouter,
458
- NoInfer<TFrom> extends string ? NoInfer<TFrom> : '',
459
- NoInfer<TTo> & string
460
- >
461
-
462
- export type CheckFromPath<
463
- TRouter extends AnyRouter,
464
- TPass,
465
- TFail,
418
+ > = ConstrainLiteral<
419
+ TTo,
420
+ RelativeToPathAutoComplete<
421
+ TRouter,
422
+ NoInfer<TFrom> extends string ? NoInfer<TFrom> : '',
423
+ NoInfer<TTo> & string
424
+ >
425
+ >
426
+
427
+ export type FromPathOption<TRouter extends AnyRouter, TFrom> = ConstrainLiteral<
466
428
  TFrom,
467
- > = string extends TFrom
468
- ? TPass
469
- : RouteByPath<TRouter['routeTree'], TFrom> extends never
470
- ? TFail
471
- : TPass
472
-
473
- export type FromPathOption<TRouter extends AnyRouter, TFrom> =
474
- | CheckFromPath<
475
- TRouter,
476
- string extends TFrom ? TFrom & {} : TFrom,
477
- never,
478
- TFrom
479
- >
480
- | RoutePaths<TRouter['routeTree']>
429
+ RoutePaths<TRouter['routeTree']>
430
+ >
481
431
 
482
432
  export interface ActiveOptions {
483
433
  exact?: boolean
@@ -524,16 +474,41 @@ export interface LinkOptionsProps {
524
474
  disabled?: boolean
525
475
  }
526
476
 
527
- export type CheckPath<TRouter extends AnyRouter, TPass, TFail, TFrom, TTo> =
528
- string extends ResolveRelativePath<TFrom, TTo>
529
- ? TPass
530
- : ResolveRelativePath<TFrom, TTo> extends CatchAllPaths<
531
- TrailingSlashOptionByRouter<TRouter>
477
+ type JoinPath<TLeft extends string, TRight extends string> = TRight extends ''
478
+ ? TLeft
479
+ : TLeft extends ''
480
+ ? TRight
481
+ : `${RemoveTrailingSlashes<TLeft>}/${RemoveLeadingSlashes<TRight>}`
482
+
483
+ type RemoveLastSegment<
484
+ T extends string,
485
+ TAcc extends string = '',
486
+ > = T extends `${infer TSegment}/${infer TRest}`
487
+ ? TRest & `${string}/${string}` extends never
488
+ ? `${TAcc}${TSegment}`
489
+ : RemoveLastSegment<TRest, `${TAcc}${TSegment}/`>
490
+ : TAcc
491
+
492
+ export type ResolveCurrentPath<TFrom, TTo> = TTo extends '.'
493
+ ? TFrom
494
+ : TTo extends './'
495
+ ? AddTrailingSlash<TFrom>
496
+ : TTo & `./${string}` extends never
497
+ ? never
498
+ : TTo extends `./${infer TRest}`
499
+ ? ResolveRelativePath<TFrom, TRest>
500
+ : never
501
+
502
+ export type ResolveParentPath<TFrom extends string, TTo> = TTo extends '../'
503
+ ? RemoveLastSegment<TFrom>
504
+ : TTo & `..${string}` extends never
505
+ ? never
506
+ : TTo extends `..${infer ToRest}`
507
+ ? ResolveRelativePath<
508
+ RemoveLastSegment<TFrom>,
509
+ RemoveLeadingSlashes<ToRest>
532
510
  >
533
- ? TPass
534
- : ResolveRoute<TRouter, TFrom, TTo> extends never
535
- ? TFail
536
- : TPass
511
+ : never
537
512
 
538
513
  export type ResolveRelativePath<TFrom, TTo = '.'> = string extends TFrom
539
514
  ? TTo
@@ -543,25 +518,13 @@ export type ResolveRelativePath<TFrom, TTo = '.'> = string extends TFrom
543
518
  ? TFrom
544
519
  : TFrom extends string
545
520
  ? TTo extends string
546
- ? TTo extends '.'
547
- ? TFrom
548
- : TTo extends `./`
549
- ? Join<[TFrom, '/']>
550
- : TTo extends `./${infer TRest}`
551
- ? ResolveRelativePath<TFrom, TRest>
552
- : TTo extends `/${infer TRest}`
553
- ? TTo
554
- : Split<TTo> extends ['..', ...infer ToRest]
555
- ? Split<TFrom> extends [...infer FromRest, infer FromTail]
556
- ? ToRest extends ['/']
557
- ? Join<['/', ...FromRest, '/']>
558
- : ResolveRelativePath<Join<FromRest>, Join<ToRest>>
559
- : never
560
- : Split<TTo> extends ['.', ...infer ToRest]
561
- ? ToRest extends ['/']
562
- ? Join<[TFrom, '/']>
563
- : ResolveRelativePath<TFrom, Join<ToRest>>
564
- : CleanPath<Join<['/', ...Split<TFrom>, ...Split<TTo>]>>
521
+ ? TTo & `..${string}` extends never
522
+ ? TTo & `.${string}` extends never
523
+ ? TTo & `/${string}` extends never
524
+ ? AddLeadingSlash<JoinPath<TFrom, TTo>>
525
+ : TTo
526
+ : ResolveCurrentPath<TFrom, TTo>
527
+ : ResolveParentPath<TFrom, TTo>
565
528
  : never
566
529
  : never
567
530
 
package/src/route.ts CHANGED
@@ -26,7 +26,13 @@ import type { NavigateOptions, ParsePathParams, ToMaskOptions } from './link'
26
26
  import type { ParsedLocation } from './location'
27
27
  import type { RouteById, RouteIds, RoutePaths } from './routeInfo'
28
28
  import type { AnyRouter, RegisteredRouter, Router } from './router'
29
- import type { Assign, Constrain, Expand, NoInfer } from './utils'
29
+ import type {
30
+ Assign,
31
+ Constrain,
32
+ ConstrainLiteral,
33
+ Expand,
34
+ NoInfer,
35
+ } from './utils'
30
36
  import type { BuildLocationFn, NavigateFn } from './RouterProvider'
31
37
  import type { NotFoundError } from './not-found'
32
38
  import type { LazyRoute } from './fileRoute'
@@ -112,11 +118,12 @@ export type RouteOptions<
112
118
  NoInfer<TBeforeLoadFn>
113
119
  >
114
120
 
115
- export type ParseSplatParams<TPath extends string> = TPath extends `${string}$`
116
- ? '_splat'
117
- : TPath extends `${string}$/${string}`
118
- ? '_splat'
119
- : never
121
+ export type ParseSplatParams<TPath extends string> = TPath &
122
+ `${string}$` extends never
123
+ ? TPath & `${string}$/${string}` extends never
124
+ ? never
125
+ : '_splat'
126
+ : '_splat'
120
127
 
121
128
  export interface SplatParams {
122
129
  _splat?: string
@@ -794,7 +801,7 @@ export type RouteTypesById<TRouter extends AnyRouter, TId> = RouteById<
794
801
  >['types']
795
802
 
796
803
  export function getRouteApi<TId, TRouter extends AnyRouter = RegisteredRouter>(
797
- id: Constrain<TId, RouteIds<TRouter['routeTree']>>,
804
+ id: ConstrainLiteral<TId, RouteIds<TRouter['routeTree']>>,
798
805
  ) {
799
806
  return new RouteApi<TId, TRouter>({ id })
800
807
  }
package/src/routeInfo.ts CHANGED
@@ -114,9 +114,7 @@ export type RouteToPathNeverTrailingSlash<TRoute extends AnyRoute> =
114
114
  TRoute['path'] extends '/'
115
115
  ? TRoute['fullPath'] extends '/'
116
116
  ? TRoute['fullPath']
117
- : TRoute['fullPath'] extends `${infer TRest}/`
118
- ? TRest
119
- : TRoute['fullPath']
117
+ : RemoveTrailingSlashes<TRoute['fullPath']>
120
118
  : TRoute['fullPath']
121
119
 
122
120
  export type RouteToPathPreserveTrailingSlash<TRoute extends AnyRoute> =
@@ -139,11 +137,9 @@ export type RouteToByRouter<
139
137
  TRoute extends AnyRoute,
140
138
  > = RouteToPathByTrailingSlashOption<TRoute>[TrailingSlashOptionByRouter<TRouter>]
141
139
 
142
- export type CodeRouteToPath<
143
- TRouter extends AnyRouter,
144
- TRouteTree extends AnyRoute,
145
- > =
146
- ParseRouteWithoutBranches<TRouteTree> extends infer TRoute extends AnyRoute
140
+ export type CodeRouteToPath<TRouter extends AnyRouter> =
141
+ ParseRouteWithoutBranches<TRouter['routeTree']> extends infer TRoute extends
142
+ AnyRoute
147
143
  ? TRoute extends any
148
144
  ? RouteToByRouter<TRouter, TRoute>
149
145
  : never
@@ -159,13 +155,10 @@ export type FileRouteToPath<
159
155
  ? AddTrailingSlash<TTo>
160
156
  : TTo | AddTrailingSlash<TTo>
161
157
 
162
- export type RouteToPath<
163
- TRouter extends AnyRouter,
164
- TRouteTree extends AnyRoute,
165
- > = unknown extends TRouter
158
+ export type RouteToPath<TRouter extends AnyRouter> = unknown extends TRouter
166
159
  ? string
167
160
  : InferFileRouteTypes<TRouter['routeTree']> extends never
168
- ? CodeRouteToPath<TRouter, TRouteTree>
161
+ ? CodeRouteToPath<TRouter>
169
162
  : FileRouteToPath<TRouter>
170
163
 
171
164
  export type CodeRoutesByToPath<TRouter extends AnyRouter> =