@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.
- package/dist/cjs/index.d.cts +2 -1
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/link.d.cts +19 -23
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +3 -3
- package/dist/cjs/routeInfo.d.cts +3 -3
- package/dist/cjs/router.cjs +26 -22
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +1 -0
- package/dist/cjs/typePrimitives.d.cts +62 -0
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +3 -2
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/link.d.ts +19 -23
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/route.d.ts +3 -3
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/routeInfo.d.ts +3 -3
- package/dist/esm/router.d.ts +1 -0
- package/dist/esm/router.js +26 -22
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/typePrimitives.d.ts +62 -0
- package/dist/esm/utils.d.ts +3 -2
- package/dist/esm/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/index.tsx +2 -6
- package/src/link.tsx +107 -144
- package/src/route.ts +14 -7
- package/src/routeInfo.ts +6 -13
- package/src/router.ts +32 -31
- package/src/typePrimitives.ts +168 -0
- package/src/utils.ts +9 -5
|
@@ -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>>>;
|
package/dist/esm/utils.d.ts
CHANGED
|
@@ -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:
|
|
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;
|
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'\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":";AA2JO,SAAS,KAAQ,KAAe;AAC9B,SAAA,IAAI,IAAI,SAAS,CAAC;AAC3B;AAEA,SAAS,WAAW,GAAuB;AACzC,SAAO,OAAO,MAAM;AACtB;AAEgB,SAAA,iBACd,SACA,UACS;AACL,MAAA,WAAW,OAAO,GAAG;AACvB,WAAO,QAAQ,QAAQ;AAAA,EAAA;AAGlB,SAAA;AACT;AAEgB,SAAA,KACd,QACA,MACoB;AACpB,SAAO,KAAK,OAAO,CAAC,KAAU,QAAc;AACtC,QAAA,GAAG,IAAI,OAAO,GAAG;AACd,WAAA;AAAA,EACT,GAAG,EAAS;AACd;AAQgB,SAAA,iBAAoB,MAAW,OAAa;AAC1D,MAAI,SAAS,OAAO;AACX,WAAA;AAAA,EAAA;AAGT,QAAM,OAAO;AAEb,QAAM,QAAQ,aAAa,IAAI,KAAK,aAAa,IAAI;AAErD,MAAI,SAAU,cAAc,IAAI,KAAK,cAAc,IAAI,GAAI;AACzD,UAAM,YAAY,QAAQ,OAAO,OAAO,KAAK,IAAI;AACjD,UAAM,WAAW,UAAU;AAC3B,UAAM,YAAY,QAAQ,OAAO,OAAO,KAAK,IAAI;AACjD,UAAM,WAAW,UAAU;AAC3B,UAAM,OAAY,QAAQ,CAAA,IAAK,CAAC;AAEhC,QAAI,aAAa;AAEjB,aAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,YAAM,MAAM,QAAQ,IAAK,UAAU,CAAC;AACpC,WACI,CAAC,SAAS,UAAU,SAAS,GAAG,KAAM,UACxC,KAAK,GAAG,MAAM,UACd,KAAK,GAAG,MAAM,QACd;AACA,aAAK,GAAG,IAAI;AACZ;AAAA,MAAA,OACK;AACA,aAAA,GAAG,IAAI,iBAAiB,KAAK,GAAG,GAAG,KAAK,GAAG,CAAC;AAC7C,YAAA,KAAK,GAAG,MAAM,KAAK,GAAG,KAAK,KAAK,GAAG,MAAM,QAAW;AACtD;AAAA,QAAA;AAAA,MACF;AAAA,IACF;AAGF,WAAO,aAAa,YAAY,eAAe,WAAW,OAAO;AAAA,EAAA;AAG5D,SAAA;AACT;AAGO,SAAS,cAAc,GAAQ;AAChC,MAAA,CAAC,mBAAmB,CAAC,GAAG;AACnB,WAAA;AAAA,EAAA;AAIT,QAAM,OAAO,EAAE;AACX,MAAA,OAAO,SAAS,aAAa;AACxB,WAAA;AAAA,EAAA;AAIT,QAAM,OAAO,KAAK;AACd,MAAA,CAAC,mBAAmB,IAAI,GAAG;AACtB,WAAA;AAAA,EAAA;AAIT,MAAI,CAAC,KAAK,eAAe,eAAe,GAAG;AAClC,WAAA;AAAA,EAAA;AAIF,SAAA;AACT;AAEA,SAAS,mBAAmB,GAAQ;AAClC,SAAO,OAAO,UAAU,SAAS,KAAK,CAAC,MAAM;AAC/C;AAEO,SAAS,aAAa,OAAyC;AAC7D,SAAA,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,OAAO,KAAK,KAAK,EAAE;AACrE;AAEA,SAAS,cAAc,KAAU,iBAA0B;AACrD,MAAA,OAAO,OAAO,KAAK,GAAG;AAC1B,MAAI,iBAAiB;AACnB,WAAO,KAAK,OAAO,CAAC,QAAQ,IAAI,GAAG,MAAM,MAAS;AAAA,EAAA;AAE7C,SAAA;AACT;AAEgB,SAAA,UACd,GACA,GACA,MACS;AACT,MAAI,MAAM,GAAG;AACJ,WAAA;AAAA,EAAA;AAGL,MAAA,OAAO,MAAM,OAAO,GAAG;AAClB,WAAA;AAAA,EAAA;AAGT,MAAI,cAAc,CAAC,KAAK,cAAc,CAAC,GAAG;AAClC,UAAA,mBAAkB,6BAAM,oBAAmB;AAC3C,UAAA,QAAQ,cAAc,GAAG,eAAe;AACxC,UAAA,QAAQ,cAAc,GAAG,eAAe;AAE9C,QAAI,EAAC,6BAAM,YAAW,MAAM,WAAW,MAAM,QAAQ;AAC5C,aAAA;AAAA,IAAA;AAGT,WAAO,MAAM,MAAM,CAAC,QAAQ,UAAU,EAAE,GAAG,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC;AAAA,EAAA;AAG7D,MAAI,MAAM,QAAQ,CAAC,KAAK,MAAM,QAAQ,CAAC,GAAG;AACpC,QAAA,EAAE,WAAW,EAAE,QAAQ;AAClB,aAAA;AAAA,IAAA;AAET,WAAO,CAAC,EAAE,KAAK,CAAC,MAAM,UAAU,CAAC,UAAU,MAAM,EAAE,KAAK,GAAG,IAAI,CAAC;AAAA,EAAA;AAG3D,SAAA;AACT;AAEO,SAAS,kBACd,IACG;AACG,QAAA,QAAQ,MAAM,OAAO,EAAE;AAC7B,QAAM,UAAU;AAEV,QAAA,MAAM,MAAM,OAAO,IAAI,SAAqB,MAAM,QAAQ,GAAG,IAAI,CAAC;AACxE,SAAO,IAAI;AACb;AAEgB,SAAA,QAAW,MAAS,MAAS;AAC3C,MAAI,OAAO,GAAG,MAAM,IAAI,GAAG;AAClB,WAAA;AAAA,EAAA;AAIP,MAAA,OAAO,SAAS,YAChB,SAAS,QACT,OAAO,SAAS,YAChB,SAAS,MACT;AACO,WAAA;AAAA,EAAA;AAGH,QAAA,QAAQ,OAAO,KAAK,IAAI;AAC9B,MAAI,MAAM,WAAW,OAAO,KAAK,IAAI,EAAE,QAAQ;AACtC,WAAA;AAAA,EAAA;AAGT,aAAW,QAAQ,OAAO;AACxB,QACE,CAAC,OAAO,UAAU,eAAe,KAAK,MAAM,IAAI,KAChD,CAAC,OAAO,GAAG,KAAK,IAAe,GAAG,KAAK,IAAe,CAAC,GACvD;AACO,aAAA;AAAA,IAAA;AAAA,EACT;AAEK,SAAA;AACT;AA0BO,MAAM,kBACX,OAAO,WAAW,cAAc,MAAM,kBAAkB,MAAM;AAMzD,SAAS,WAAW,YAAoB;AACtC,SAAA,WACJ,QAAQ,OAAO,MAAM,EACrB,QAAQ,MAAM,KAAK,EACnB,QAAQ,MAAM,KAAK;AACxB;AASO,SAAS,wBAA2B,WAAgC;AACrE,MAAA;AACA,MAAA;AAEJ,QAAM,oBAAoB,IAAI,QAAW,CAAC,SAAS,WAAW;AACvC,yBAAA;AACD,wBAAA;AAAA,EAAA,CACrB;AAED,oBAAkB,SAAS;AAET,oBAAA,UAAU,CAAC,UAAa;AACxC,sBAAkB,SAAS;AAC3B,sBAAkB,QAAQ;AAC1B,uBAAmB,KAAK;AACxB,2CAAY;AAAA,EACd;AAEkB,oBAAA,SAAS,CAAC,MAAM;AAChC,sBAAkB,SAAS;AAC3B,sBAAkB,CAAC;AAAA,EACrB;AAEO,SAAA;AACT;AAKO,SAAS,YAAe,OAAoB;AAE3C,QAAA,MAAM,MAAM,OAAqC;AAAA,IACrD;AAAA,IACA,MAAM;AAAA,EAAA,CACP;AAEK,QAAA,UAAU,IAAI,QAAQ;AAK5B,MAAI,UAAU,SAAS;AACrB,QAAI,UAAU;AAAA,MACZ;AAAA,MACA,MAAM;AAAA,IACR;AAAA,EAAA;AAIF,SAAO,IAAI,QAAQ;AACrB;AA2BgB,SAAA,wBACd,KACA,UACA,8BAAwD,CACxD,GAAA,UAAkC,IACL;AAC7B,QAAM,kCAAkC,MAAM;AAAA,IAC5C,OAAO,yBAAyB;AAAA,EAClC;AAEM,QAAA,cAAc,MAAM,OAAoC,IAAI;AAElE,QAAM,UAAU,MAAM;AACpB,QACE,CAAC,IAAI,WACL,CAAC,gCAAgC,WACjC,QAAQ,UACR;AACA;AAAA,IAAA;AAGF,gBAAY,UAAU,IAAI,qBAAqB,CAAC,CAAC,KAAK,MAAM;AAC1D,eAAS,KAAK;AAAA,OACb,2BAA2B;AAElB,gBAAA,QAAQ,QAAQ,IAAI,OAAO;AAEvC,WAAO,MAAM;;AACX,wBAAY,YAAZ,mBAAqB;AAAA,IACvB;AAAA,EAAA,GACC,CAAC,UAAU,6BAA6B,QAAQ,UAAU,GAAG,CAAC;AAEjE,SAAO,YAAY;AACrB;AAeO,SAAS,gBAAmB,KAA6B;AACxD,QAAA,WAAW,MAAM,OAAU,IAAI;AAErC,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,IAAK;AACN,QAAA,OAAO,QAAQ,YAAY;AAC7B,UAAI,SAAS,OAAO;AAAA,IAAA,OACf;AACL,UAAI,UAAU,SAAS;AAAA,IAAA;AAAA,EACzB,CACD;AAEM,SAAA;AACT;"}
|
package/package.json
CHANGED
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
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
?
|
|
54
|
-
:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
|
105
|
-
?
|
|
106
|
-
:
|
|
62
|
+
export type AddTrailingSlash<T> = T & `${string}/` extends never
|
|
63
|
+
? `${T & string}/`
|
|
64
|
+
: T
|
|
107
65
|
|
|
108
|
-
export type
|
|
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
|
|
72
|
+
export type AddLeadingSlash<T> = T & `/${string}` extends never
|
|
73
|
+
? `/${T & string}`
|
|
74
|
+
: T
|
|
111
75
|
|
|
112
|
-
export type RemoveLeadingSlashes<T> = 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
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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
|
-
|
|
128
|
-
TPaths =
|
|
129
|
-
|
|
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}
|
|
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 =
|
|
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
|
-
:
|
|
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
|
|
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
|
|
189
|
-
?
|
|
190
|
-
:
|
|
191
|
-
?
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
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
|
-
>
|
|
468
|
-
|
|
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
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
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
|
-
|
|
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
|
-
?
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
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 {
|
|
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
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
?
|
|
119
|
-
:
|
|
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:
|
|
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']
|
|
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
|
|
144
|
-
|
|
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
|
|
161
|
+
? CodeRouteToPath<TRouter>
|
|
169
162
|
: FileRouteToPath<TRouter>
|
|
170
163
|
|
|
171
164
|
export type CodeRoutesByToPath<TRouter extends AnyRouter> =
|