med-notes/.pnpm-store/v10/files/02/460ae59f7c40f9822c1dd61b9bcda9b2907b5edabacad6812467b259a698ec57ae1c7249d71888fe9d011557d28e29634c2399bc42e4035f796c0248e6474b
2025-05-09 05:30:08 +02:00

1622 lines
37 KiB
Plaintext

import { joinPaths, trimPathLeft } from './path'
import { notFound } from './not-found'
import { rootRouteId } from './root'
import type { LazyRoute } from './fileRoute'
import type { NotFoundError } from './not-found'
import type { NavigateOptions, ParsePathParams } from './link'
import type { ParsedLocation } from './location'
import type {
AnyRouteMatch,
MakeRouteMatchFromRoute,
MakeRouteMatchUnion,
RouteMatch,
} from './Matches'
import type { RootRouteId } from './root'
import type { ParseRoute, RouteById, RoutePaths } from './routeInfo'
import type { AnyRouter, RegisteredRouter } from './router'
import type { BuildLocationFn, NavigateFn } from './RouterProvider'
import type {
Assign,
Constrain,
Expand,
IntersectAssign,
NoInfer,
} from './utils'
import type {
AnySchema,
AnyStandardSchemaValidator,
AnyValidator,
AnyValidatorAdapter,
AnyValidatorObj,
DefaultValidator,
ResolveSearchValidatorInput,
ResolveValidatorOutput,
StandardSchemaValidator,
ValidatorAdapter,
ValidatorFn,
ValidatorObj,
} from './validators'
export type AnyPathParams = {}
export type SearchSchemaInput = {
__TSearchSchemaInput__: 'TSearchSchemaInput'
}
export type AnyContext = {}
export interface RouteContext {}
export type PreloadableObj = { preload?: () => Promise<void> }
export type RoutePathOptions<TCustomId, TPath> =
| {
path: TPath
}
| {
id: TCustomId
}
export interface StaticDataRouteOption {}
export type RoutePathOptionsIntersection<TCustomId, TPath> = {
path: TPath
id: TCustomId
}
export type SearchFilter<TInput, TResult = TInput> = (prev: TInput) => TResult
export type SearchMiddlewareContext<TSearchSchema> = {
search: TSearchSchema
next: (newSearch: TSearchSchema) => TSearchSchema
}
export type SearchMiddleware<TSearchSchema> = (
ctx: SearchMiddlewareContext<TSearchSchema>,
) => TSearchSchema
export type ResolveId<
TParentRoute,
TCustomId extends string,
TPath extends string,
> = TParentRoute extends { id: infer TParentId extends string }
? RoutePrefix<TParentId, string extends TCustomId ? TPath : TCustomId>
: RootRouteId
export type InferFullSearchSchema<TRoute> = TRoute extends {
types: {
fullSearchSchema: infer TFullSearchSchema
}
}
? TFullSearchSchema
: {}
export type InferFullSearchSchemaInput<TRoute> = TRoute extends {
types: {
fullSearchSchemaInput: infer TFullSearchSchemaInput
}
}
? TFullSearchSchemaInput
: {}
export type InferAllParams<TRoute> = TRoute extends {
types: {
allParams: infer TAllParams
}
}
? TAllParams
: {}
export type InferAllContext<TRoute> = unknown extends TRoute
? TRoute
: TRoute extends {
types: {
allContext: infer TAllContext
}
}
? TAllContext
: {}
export type ResolveSearchSchemaFnInput<TSearchValidator> =
TSearchValidator extends (input: infer TSearchSchemaInput) => any
? TSearchSchemaInput extends SearchSchemaInput
? Omit<TSearchSchemaInput, keyof SearchSchemaInput>
: ResolveSearchSchemaFn<TSearchValidator>
: AnySchema
export type ResolveSearchSchemaInput<TSearchValidator> =
TSearchValidator extends AnyStandardSchemaValidator
? NonNullable<TSearchValidator['~standard']['types']>['input']
: TSearchValidator extends AnyValidatorAdapter
? TSearchValidator['types']['input']
: TSearchValidator extends AnyValidatorObj
? ResolveSearchSchemaFnInput<TSearchValidator['parse']>
: ResolveSearchSchemaFnInput<TSearchValidator>
export type ResolveSearchSchemaFn<TSearchValidator> = TSearchValidator extends (
...args: any
) => infer TSearchSchema
? TSearchSchema
: AnySchema
export type ResolveSearchSchema<TSearchValidator> =
unknown extends TSearchValidator
? TSearchValidator
: TSearchValidator extends AnyStandardSchemaValidator
? NonNullable<TSearchValidator['~standard']['types']>['output']
: TSearchValidator extends AnyValidatorAdapter
? TSearchValidator['types']['output']
: TSearchValidator extends AnyValidatorObj
? ResolveSearchSchemaFn<TSearchValidator['parse']>
: ResolveSearchSchemaFn<TSearchValidator>
export type ParseSplatParams<TPath extends string> = TPath &
`${string}$` extends never
? TPath & `${string}$/${string}` extends never
? never
: '_splat'
: '_splat'
export interface SplatParams {
_splat?: string
}
export type ResolveParams<TPath extends string> =
ParseSplatParams<TPath> extends never
? Record<ParsePathParams<TPath>, string>
: Record<ParsePathParams<TPath>, string> & SplatParams
export type ParseParamsFn<in out TPath extends string, in out TParams> = (
rawParams: ResolveParams<TPath>,
) => TParams extends Record<ParsePathParams<TPath>, any>
? TParams
: Record<ParsePathParams<TPath>, any>
export type StringifyParamsFn<in out TPath extends string, in out TParams> = (
params: TParams,
) => ResolveParams<TPath>
export type ParamsOptions<in out TPath extends string, in out TParams> = {
params?: {
parse?: ParseParamsFn<TPath, TParams>
stringify?: StringifyParamsFn<TPath, TParams>
}
/**
@deprecated Use params.parse instead
*/
parseParams?: ParseParamsFn<TPath, TParams>
/**
@deprecated Use params.stringify instead
*/
stringifyParams?: StringifyParamsFn<TPath, TParams>
}
interface RequiredStaticDataRouteOption {
staticData: StaticDataRouteOption
}
interface OptionalStaticDataRouteOption {
staticData?: StaticDataRouteOption
}
export type UpdatableStaticRouteOption = {} extends StaticDataRouteOption
? OptionalStaticDataRouteOption
: RequiredStaticDataRouteOption
export type MetaDescriptor =
| { charSet: 'utf-8' }
| { title: string }
| { name: string; content: string }
| { property: string; content: string }
| { httpEquiv: string; content: string }
| { 'script:ld+json': LdJsonObject }
| { tagName: 'meta' | 'link'; [name: string]: string }
| Record<string, unknown>
type LdJsonObject = { [Key in string]: LdJsonValue } & {
[Key in string]?: LdJsonValue | undefined
}
type LdJsonArray = Array<LdJsonValue> | ReadonlyArray<LdJsonValue>
type LdJsonPrimitive = string | number | boolean | null
type LdJsonValue = LdJsonPrimitive | LdJsonObject | LdJsonArray
export type RouteLinkEntry = {}
export type SearchValidator<TInput, TOutput> =
| ValidatorObj<TInput, TOutput>
| ValidatorFn<TInput, TOutput>
| ValidatorAdapter<TInput, TOutput>
| StandardSchemaValidator<TInput, TOutput>
| undefined
export type AnySearchValidator = SearchValidator<any, any>
export type DefaultSearchValidator = SearchValidator<
Record<string, unknown>,
AnySchema
>
export type RoutePrefix<
TPrefix extends string,
TPath extends string,
> = string extends TPath
? RootRouteId
: TPath extends string
? TPrefix extends RootRouteId
? TPath extends '/'
? '/'
: `/${TrimPath<TPath>}`
: `${TPrefix}/${TPath}` extends '/'
? '/'
: `/${TrimPathLeft<`${TrimPathRight<TPrefix>}/${TrimPath<TPath>}`>}`
: never
export type TrimPath<T extends string> = '' extends T
? ''
: TrimPathRight<TrimPathLeft<T>>
export type TrimPathLeft<T extends string> =
T extends `${RootRouteId}/${infer U}`
? TrimPathLeft<U>
: T extends `/${infer U}`
? TrimPathLeft<U>
: T
export type TrimPathRight<T extends string> = T extends '/'
? '/'
: T extends `${infer U}/`
? TrimPathRight<U>
: T
export type LooseReturnType<T> = T extends (
...args: Array<any>
) => infer TReturn
? TReturn
: never
export type LooseAsyncReturnType<T> = T extends (
...args: Array<any>
) => infer TReturn
? TReturn extends Promise<infer TReturn>
? TReturn
: TReturn
: never
export type ContextReturnType<TContextFn> = unknown extends TContextFn
? TContextFn
: LooseReturnType<TContextFn> extends never
? AnyContext
: LooseReturnType<TContextFn>
export type ContextAsyncReturnType<TContextFn> = unknown extends TContextFn
? TContextFn
: LooseAsyncReturnType<TContextFn> extends never
? AnyContext
: LooseAsyncReturnType<TContextFn>
export type ResolveRouteContext<TRouteContextFn, TBeforeLoadFn> = Assign<
ContextReturnType<TRouteContextFn>,
ContextAsyncReturnType<TBeforeLoadFn>
>
export type ResolveLoaderData<TLoaderFn> = unknown extends TLoaderFn
? TLoaderFn
: LooseAsyncReturnType<TLoaderFn> extends never
? undefined
: LooseAsyncReturnType<TLoaderFn>
export type ResolveFullSearchSchema<
TParentRoute extends AnyRoute,
TSearchValidator,
> = unknown extends TParentRoute
? ResolveValidatorOutput<TSearchValidator>
: IntersectAssign<
InferFullSearchSchema<TParentRoute>,
ResolveValidatorOutput<TSearchValidator>
>
export type ResolveFullSearchSchemaInput<
TParentRoute extends AnyRoute,
TSearchValidator,
> = IntersectAssign<
InferFullSearchSchemaInput<TParentRoute>,
ResolveSearchValidatorInput<TSearchValidator>
>
export type ResolveAllParamsFromParent<
TParentRoute extends AnyRoute,
TParams,
> = Assign<InferAllParams<TParentRoute>, TParams>
export type RouteContextParameter<
TParentRoute extends AnyRoute,
TRouterContext,
> = unknown extends TParentRoute
? TRouterContext
: Assign<TRouterContext, InferAllContext<TParentRoute>>
export type BeforeLoadContextParameter<
TParentRoute extends AnyRoute,
TRouterContext,
TRouteContextFn,
> = Assign<
RouteContextParameter<TParentRoute, TRouterContext>,
ContextReturnType<TRouteContextFn>
>
export type ResolveAllContext<
TParentRoute extends AnyRoute,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
> = Assign<
BeforeLoadContextParameter<TParentRoute, TRouterContext, TRouteContextFn>,
ContextAsyncReturnType<TBeforeLoadFn>
>
export interface FullSearchSchemaOption<
in out TParentRoute extends AnyRoute,
in out TSearchValidator,
> {
search: Expand<ResolveFullSearchSchema<TParentRoute, TSearchValidator>>
}
export interface RemountDepsOptions<
in out TRouteId,
in out TFullSearchSchema,
in out TAllParams,
in out TLoaderDeps,
> {
routeId: TRouteId
search: TFullSearchSchema
params: TAllParams
loaderDeps: TLoaderDeps
}
export type MakeRemountDepsOptionsUnion<
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
> =
ParseRoute<TRouteTree> extends infer TRoute extends AnyRoute
? TRoute extends any
? RemountDepsOptions<
TRoute['id'],
TRoute['types']['fullSearchSchema'],
TRoute['types']['allParams'],
TRoute['types']['loaderDeps']
>
: never
: never
export interface RouteTypes<
in out TParentRoute extends AnyRoute,
in out TPath extends string,
in out TFullPath extends string,
in out TCustomId extends string,
in out TId extends string,
in out TSearchValidator,
in out TParams,
in out TRouterContext,
in out TRouteContextFn,
in out TBeforeLoadFn,
in out TLoaderDeps,
in out TLoaderFn,
in out TChildren,
in out TFileRouteTypes,
> {
parentRoute: TParentRoute
path: TPath
to: TrimPathRight<TFullPath>
fullPath: TFullPath
customId: TCustomId
id: TId
searchSchema: ResolveValidatorOutput<TSearchValidator>
searchSchemaInput: ResolveSearchValidatorInput<TSearchValidator>
searchValidator: TSearchValidator
fullSearchSchema: ResolveFullSearchSchema<TParentRoute, TSearchValidator>
fullSearchSchemaInput: ResolveFullSearchSchemaInput<
TParentRoute,
TSearchValidator
>
params: TParams
allParams: ResolveAllParamsFromParent<TParentRoute, TParams>
routerContext: TRouterContext
routeContext: ResolveRouteContext<TRouteContextFn, TBeforeLoadFn>
routeContextFn: TRouteContextFn
beforeLoadFn: TBeforeLoadFn
allContext: ResolveAllContext<
TParentRoute,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
>
children: TChildren
loaderData: ResolveLoaderData<TLoaderFn>
loaderDeps: TLoaderDeps
fileRouteTypes: TFileRouteTypes
}
export type ResolveFullPath<
TParentRoute extends AnyRoute,
TPath extends string,
TPrefixed = RoutePrefix<TParentRoute['fullPath'], TPath>,
> = TPrefixed extends RootRouteId ? '/' : TPrefixed
export interface RouteExtensions<TId, TFullPath> {}
export type RouteLazyFn<TRoute extends AnyRoute> = (
lazyFn: () => Promise<LazyRoute>,
) => TRoute
export type RouteAddChildrenFn<
in out TParentRoute extends AnyRoute,
in out TPath extends string,
in out TFullPath extends string,
in out TCustomId extends string,
in out TId extends string,
in out TSearchValidator,
in out TParams,
in out TRouterContext,
in out TRouteContextFn,
in out TBeforeLoadFn,
in out TLoaderDeps extends Record<string, any>,
in out TLoaderFn,
in out TFileRouteTypes,
> = <const TNewChildren>(
children: Constrain<
TNewChildren,
ReadonlyArray<AnyRoute> | Record<string, AnyRoute>
>,
) => Route<
TParentRoute,
TPath,
TFullPath,
TCustomId,
TId,
TSearchValidator,
TParams,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps,
TLoaderFn,
TNewChildren,
TFileRouteTypes
>
export type RouteAddFileChildrenFn<
in out TParentRoute extends AnyRoute,
in out TPath extends string,
in out TFullPath extends string,
in out TCustomId extends string,
in out TId extends string,
in out TSearchValidator,
in out TParams,
in out TRouterContext,
in out TRouteContextFn,
in out TBeforeLoadFn,
in out TLoaderDeps extends Record<string, any>,
in out TLoaderFn,
in out TFileRouteTypes,
> = <const TNewChildren>(
children: TNewChildren,
) => Route<
TParentRoute,
TPath,
TFullPath,
TCustomId,
TId,
TSearchValidator,
TParams,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps,
TLoaderFn,
TNewChildren,
TFileRouteTypes
>
export type RouteAddFileTypesFn<
TParentRoute extends AnyRoute,
TPath extends string,
TFullPath extends string,
TCustomId extends string,
TId extends string,
TSearchValidator,
TParams,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps extends Record<string, any>,
TLoaderFn,
TChildren,
> = <TNewFileRouteTypes>() => Route<
TParentRoute,
TPath,
TFullPath,
TCustomId,
TId,
TSearchValidator,
TParams,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps,
TLoaderFn,
TChildren,
TNewFileRouteTypes
>
export interface Route<
in out TParentRoute extends AnyRoute,
in out TPath extends string,
in out TFullPath extends string,
in out TCustomId extends string,
in out TId extends string,
in out TSearchValidator,
in out TParams,
in out TRouterContext,
in out TRouteContextFn,
in out TBeforeLoadFn,
in out TLoaderDeps extends Record<string, any>,
in out TLoaderFn,
in out TChildren,
in out TFileRouteTypes,
> extends RouteExtensions<TId, TFullPath> {
fullPath: TFullPath
path: TPath
id: TId
parentRoute: TParentRoute
children?: TChildren
types: RouteTypes<
TParentRoute,
TPath,
TFullPath,
TCustomId,
TId,
TSearchValidator,
TParams,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps,
TLoaderFn,
TChildren,
TFileRouteTypes
>
options: RouteOptions<
TParentRoute,
TId,
TCustomId,
TFullPath,
TPath,
TSearchValidator,
TParams,
TLoaderDeps,
TLoaderFn,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
>
isRoot: TParentRoute extends AnyRoute ? true : false
_componentsPromise?: Promise<Array<void>>
lazyFn?: () => Promise<LazyRoute>
_lazyPromise?: Promise<void>
rank: number
to: TrimPathRight<TFullPath>
init: (opts: { originalIndex: number; defaultSsr?: boolean }) => void
update: (
options: UpdatableRouteOptions<
TParentRoute,
TCustomId,
TFullPath,
TParams,
TSearchValidator,
TLoaderFn,
TLoaderDeps,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
>,
) => this
lazy: RouteLazyFn<this>
addChildren: RouteAddChildrenFn<
TParentRoute,
TPath,
TFullPath,
TCustomId,
TId,
TSearchValidator,
TParams,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps,
TLoaderFn,
TFileRouteTypes
>
_addFileChildren: RouteAddFileChildrenFn<
TParentRoute,
TPath,
TFullPath,
TCustomId,
TId,
TSearchValidator,
TParams,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps,
TLoaderFn,
TFileRouteTypes
>
_addFileTypes: RouteAddFileTypesFn<
TParentRoute,
TPath,
TFullPath,
TCustomId,
TId,
TSearchValidator,
TParams,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps,
TLoaderFn,
TChildren
>
}
export type AnyRoute = Route<
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any,
any
>
export type AnyRouteWithContext<TContext> = AnyRoute & {
types: { allContext: TContext }
}
export type RouteOptions<
TParentRoute extends AnyRoute = AnyRoute,
TId extends string = string,
TCustomId extends string = string,
TFullPath extends string = string,
TPath extends string = string,
TSearchValidator = undefined,
TParams = AnyPathParams,
TLoaderDeps extends Record<string, any> = {},
TLoaderFn = undefined,
TRouterContext = {},
TRouteContextFn = AnyContext,
TBeforeLoadFn = AnyContext,
> = BaseRouteOptions<
TParentRoute,
TId,
TCustomId,
TPath,
TSearchValidator,
TParams,
TLoaderDeps,
TLoaderFn,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
> &
UpdatableRouteOptions<
NoInfer<TParentRoute>,
NoInfer<TCustomId>,
NoInfer<TFullPath>,
NoInfer<TParams>,
NoInfer<TSearchValidator>,
NoInfer<TLoaderFn>,
NoInfer<TLoaderDeps>,
NoInfer<TRouterContext>,
NoInfer<TRouteContextFn>,
NoInfer<TBeforeLoadFn>
>
export type RouteContextFn<
in out TParentRoute extends AnyRoute,
in out TSearchValidator,
in out TParams,
in out TRouterContext,
> = (
ctx: RouteContextOptions<
TParentRoute,
TSearchValidator,
TParams,
TRouterContext
>,
) => any
export type BeforeLoadFn<
in out TParentRoute extends AnyRoute,
in out TSearchValidator,
in out TParams,
in out TRouterContext,
in out TRouteContextFn,
> = (
ctx: BeforeLoadContextOptions<
TParentRoute,
TSearchValidator,
TParams,
TRouterContext,
TRouteContextFn
>,
) => any
export type FileBaseRouteOptions<
TParentRoute extends AnyRoute = AnyRoute,
TId extends string = string,
TPath extends string = string,
TSearchValidator = undefined,
TParams = {},
TLoaderDeps extends Record<string, any> = {},
TLoaderFn = undefined,
TRouterContext = {},
TRouteContextFn = AnyContext,
TBeforeLoadFn = AnyContext,
TRemountDepsFn = AnyContext,
> = ParamsOptions<TPath, TParams> & {
validateSearch?: Constrain<TSearchValidator, AnyValidator, DefaultValidator>
shouldReload?:
| boolean
| ((
match: LoaderFnContext<
TParentRoute,
TId,
TParams,
TLoaderDeps,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
>,
) => any)
context?: Constrain<
TRouteContextFn,
(
ctx: RouteContextOptions<
TParentRoute,
TParams,
TRouterContext,
TLoaderDeps
>,
) => any
>
// This async function is called before a route is loaded.
// If an error is thrown here, the route's loader will not be called.
// If thrown during a navigation, the navigation will be cancelled and the error will be passed to the `onError` function.
// If thrown during a preload event, the error will be logged to the console.
beforeLoad?: Constrain<
TBeforeLoadFn,
(
ctx: BeforeLoadContextOptions<
TParentRoute,
TSearchValidator,
TParams,
TRouterContext,
TRouteContextFn
>,
) => any
>
loaderDeps?: (
opts: FullSearchSchemaOption<TParentRoute, TSearchValidator>,
) => TLoaderDeps
remountDeps?: Constrain<
TRemountDepsFn,
(
opt: RemountDepsOptions<
TId,
FullSearchSchemaOption<TParentRoute, TSearchValidator>,
Expand<ResolveAllParamsFromParent<TParentRoute, TParams>>,
TLoaderDeps
>,
) => any
>
loader?: Constrain<
TLoaderFn,
(
ctx: LoaderFnContext<
TParentRoute,
TId,
TParams,
TLoaderDeps,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
>,
) => any
>
}
export type BaseRouteOptions<
TParentRoute extends AnyRoute = AnyRoute,
TId extends string = string,
TCustomId extends string = string,
TPath extends string = string,
TSearchValidator = undefined,
TParams = {},
TLoaderDeps extends Record<string, any> = {},
TLoaderFn = undefined,
TRouterContext = {},
TRouteContextFn = AnyContext,
TBeforeLoadFn = AnyContext,
> = RoutePathOptions<TCustomId, TPath> &
FileBaseRouteOptions<
TParentRoute,
TId,
TPath,
TSearchValidator,
TParams,
TLoaderDeps,
TLoaderFn,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
> & {
getParentRoute: () => TParentRoute
}
export interface ContextOptions<
in out TParentRoute extends AnyRoute,
in out TParams,
> {
abortController: AbortController
preload: boolean
params: Expand<ResolveAllParamsFromParent<TParentRoute, TParams>>
location: ParsedLocation
/**
* @deprecated Use `throw redirect({ to: '/somewhere' })` instead
**/
navigate: NavigateFn
buildLocation: BuildLocationFn
cause: 'preload' | 'enter' | 'stay'
matches: Array<MakeRouteMatchUnion>
}
export interface RouteContextOptions<
in out TParentRoute extends AnyRoute,
in out TParams,
in out TRouterContext,
in out TLoaderDeps,
> extends ContextOptions<TParentRoute, TParams> {
deps: TLoaderDeps
context: Expand<RouteContextParameter<TParentRoute, TRouterContext>>
}
export interface BeforeLoadContextOptions<
in out TParentRoute extends AnyRoute,
in out TSearchValidator,
in out TParams,
in out TRouterContext,
in out TRouteContextFn,
> extends ContextOptions<TParentRoute, TParams>,
FullSearchSchemaOption<TParentRoute, TSearchValidator> {
context: Expand<
BeforeLoadContextParameter<TParentRoute, TRouterContext, TRouteContextFn>
>
}
type AssetFnContextOptions<
in out TRouteId,
in out TFullPath,
in out TParentRoute extends AnyRoute,
in out TParams,
in out TSearchValidator,
in out TLoaderFn,
in out TRouterContext,
in out TRouteContextFn,
in out TBeforeLoadFn,
in out TLoaderDeps,
> = {
matches: Array<
RouteMatch<
TRouteId,
TFullPath,
ResolveAllParamsFromParent<TParentRoute, TParams>,
ResolveFullSearchSchema<TParentRoute, TSearchValidator>,
ResolveLoaderData<TLoaderFn>,
ResolveAllContext<
TParentRoute,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
>,
TLoaderDeps
>
>
match: RouteMatch<
TRouteId,
TFullPath,
ResolveAllParamsFromParent<TParentRoute, TParams>,
ResolveFullSearchSchema<TParentRoute, TSearchValidator>,
ResolveLoaderData<TLoaderFn>,
ResolveAllContext<
TParentRoute,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
>,
TLoaderDeps
>
params: ResolveAllParamsFromParent<TParentRoute, TParams>
loaderData: ResolveLoaderData<TLoaderFn>
}
export interface DefaultUpdatableRouteOptionsExtensions {
component?: unknown
errorComponent?: unknown
notFoundComponent?: unknown
pendingComponent?: unknown
}
export interface UpdatableRouteOptionsExtensions
extends DefaultUpdatableRouteOptionsExtensions {}
export interface UpdatableRouteOptions<
in out TParentRoute extends AnyRoute,
in out TRouteId,
in out TFullPath,
in out TParams,
in out TSearchValidator,
in out TLoaderFn,
in out TLoaderDeps,
in out TRouterContext,
in out TRouteContextFn,
in out TBeforeLoadFn,
> extends UpdatableStaticRouteOption,
UpdatableRouteOptionsExtensions {
// If true, this route will be matched as case-sensitive
caseSensitive?: boolean
// If true, this route will be forcefully wrapped in a suspense boundary
wrapInSuspense?: boolean
// The content to be rendered when the route is matched. If no component is provided, defaults to `<Outlet />`
pendingMs?: number
pendingMinMs?: number
staleTime?: number
gcTime?: number
preload?: boolean
preloadStaleTime?: number
preloadGcTime?: number
search?: {
middlewares?: Array<
SearchMiddleware<
ResolveFullSearchSchemaInput<TParentRoute, TSearchValidator>
>
>
}
/**
@deprecated Use search.middlewares instead
*/
preSearchFilters?: Array<
SearchFilter<ResolveFullSearchSchema<TParentRoute, TSearchValidator>>
>
/**
@deprecated Use search.middlewares instead
*/
postSearchFilters?: Array<
SearchFilter<ResolveFullSearchSchema<TParentRoute, TSearchValidator>>
>
onCatch?: (error: Error) => void
onError?: (err: any) => void
// These functions are called as route matches are loaded, stick around and leave the active
// matches
onEnter?: (
match: RouteMatch<
TRouteId,
TFullPath,
ResolveAllParamsFromParent<TParentRoute, TParams>,
ResolveFullSearchSchema<TParentRoute, TSearchValidator>,
ResolveLoaderData<TLoaderFn>,
ResolveAllContext<
TParentRoute,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
>,
TLoaderDeps
>,
) => void
onStay?: (
match: RouteMatch<
TRouteId,
TFullPath,
ResolveAllParamsFromParent<TParentRoute, TParams>,
ResolveFullSearchSchema<TParentRoute, TSearchValidator>,
ResolveLoaderData<TLoaderFn>,
ResolveAllContext<
TParentRoute,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
>,
TLoaderDeps
>,
) => void
onLeave?: (
match: RouteMatch<
TRouteId,
TFullPath,
ResolveAllParamsFromParent<TParentRoute, TParams>,
ResolveFullSearchSchema<TParentRoute, TSearchValidator>,
ResolveLoaderData<TLoaderFn>,
ResolveAllContext<
TParentRoute,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
>,
TLoaderDeps
>,
) => void
headers?: (ctx: {
loaderData: ResolveLoaderData<TLoaderFn>
}) => Record<string, string>
head?: (
ctx: AssetFnContextOptions<
TRouteId,
TFullPath,
TParentRoute,
TParams,
TSearchValidator,
TLoaderFn,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps
>,
) => {
links?: AnyRouteMatch['links']
scripts?: AnyRouteMatch['headScripts']
meta?: AnyRouteMatch['meta']
}
scripts?: (
ctx: AssetFnContextOptions<
TRouteId,
TFullPath,
TParentRoute,
TParams,
TSearchValidator,
TLoaderFn,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps
>,
) => AnyRouteMatch['scripts']
ssr?: boolean
codeSplitGroupings?: Array<
Array<
| 'loader'
| 'component'
| 'pendingComponent'
| 'notFoundComponent'
| 'errorComponent'
>
>
}
export type RouteLoaderFn<
in out TParentRoute extends AnyRoute = AnyRoute,
in out TId extends string = string,
in out TParams = {},
in out TLoaderDeps = {},
in out TRouterContext = {},
in out TRouteContextFn = AnyContext,
in out TBeforeLoadFn = AnyContext,
> = (
match: LoaderFnContext<
TParentRoute,
TId,
TParams,
TLoaderDeps,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
>,
) => any
export interface LoaderFnContext<
in out TParentRoute extends AnyRoute = AnyRoute,
in out TId extends string = string,
in out TParams = {},
in out TLoaderDeps = {},
in out TRouterContext = {},
in out TRouteContextFn = AnyContext,
in out TBeforeLoadFn = AnyContext,
> {
abortController: AbortController
preload: boolean
params: Expand<ResolveAllParamsFromParent<TParentRoute, TParams>>
deps: TLoaderDeps
context: Expand<
ResolveAllContext<
TParentRoute,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
>
>
location: ParsedLocation // Do not supply search schema here so as to demotivate people from trying to shortcut loaderDeps
/**
* @deprecated Use `throw redirect({ to: '/somewhere' })` instead
**/
navigate: (opts: NavigateOptions<AnyRouter>) => Promise<void> | void
// root route does not have a parent match
parentMatchPromise: TId extends RootRouteId
? never
: Promise<MakeRouteMatchFromRoute<TParentRoute>>
cause: 'preload' | 'enter' | 'stay'
route: AnyRoute
}
export type RootRouteOptions<
TSearchValidator = undefined,
TRouterContext = {},
TRouteContextFn = AnyContext,
TBeforeLoadFn = AnyContext,
TLoaderDeps extends Record<string, any> = {},
TLoaderFn = undefined,
> = Omit<
RouteOptions<
any, // TParentRoute
RootRouteId, // TId
RootRouteId, // TCustomId
'', // TFullPath
'', // TPath
TSearchValidator,
{}, // TParams
TLoaderDeps,
TLoaderFn,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
>,
| 'path'
| 'id'
| 'getParentRoute'
| 'caseSensitive'
| 'parseParams'
| 'stringifyParams'
| 'params'
>
export type RouteConstraints = {
TParentRoute: AnyRoute
TPath: string
TFullPath: string
TCustomId: string
TId: string
TSearchSchema: AnySchema
TFullSearchSchema: AnySchema
TParams: Record<string, any>
TAllParams: Record<string, any>
TParentContext: AnyContext
TRouteContext: RouteContext
TAllContext: AnyContext
TRouterContext: AnyContext
TChildren: unknown
TRouteTree: AnyRoute
}
export type RouteTypesById<TRouter extends AnyRouter, TId> = RouteById<
TRouter['routeTree'],
TId
>['types']
export type RouteMask<TRouteTree extends AnyRoute> = {
routeTree: TRouteTree
from: RoutePaths<TRouteTree>
to?: any
params?: any
search?: any
hash?: any
state?: any
unmaskOnReload?: boolean
}
/**
* @deprecated Use `ErrorComponentProps` instead.
*/
export type ErrorRouteProps = {
error: unknown
info?: { componentStack: string }
reset: () => void
}
export type ErrorComponentProps = {
error: Error
info?: { componentStack: string }
reset: () => void
}
export type NotFoundRouteProps = {
// TODO: Make sure this is `| null | undefined` (this is for global not-founds)
data: unknown
}
export class BaseRoute<
in out TParentRoute extends AnyRoute = AnyRoute,
in out TPath extends string = '/',
in out TFullPath extends string = ResolveFullPath<TParentRoute, TPath>,
in out TCustomId extends string = string,
in out TId extends string = ResolveId<TParentRoute, TCustomId, TPath>,
in out TSearchValidator = undefined,
in out TParams = ResolveParams<TPath>,
in out TRouterContext = AnyContext,
in out TRouteContextFn = AnyContext,
in out TBeforeLoadFn = AnyContext,
in out TLoaderDeps extends Record<string, any> = {},
in out TLoaderFn = undefined,
in out TChildren = unknown,
in out TFileRouteTypes = unknown,
> implements
Route<
TParentRoute,
TPath,
TFullPath,
TCustomId,
TId,
TSearchValidator,
TParams,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps,
TLoaderFn,
TChildren,
TFileRouteTypes
>
{
isRoot: TParentRoute extends AnyRoute ? true : false
options: RouteOptions<
TParentRoute,
TId,
TCustomId,
TFullPath,
TPath,
TSearchValidator,
TParams,
TLoaderDeps,
TLoaderFn,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
>
// The following properties are set up in this.init()
parentRoute!: TParentRoute
private _id!: TId
private _path!: TPath
private _fullPath!: TFullPath
private _to!: TrimPathRight<TFullPath>
private _ssr!: boolean
public get to() {
return this._to
}
public get id() {
return this._id
}
public get path() {
return this._path
}
public get fullPath() {
return this._fullPath
}
public get ssr() {
return this._ssr
}
// Optional
children?: TChildren
originalIndex?: number
rank!: number
lazyFn?: () => Promise<LazyRoute>
_lazyPromise?: Promise<void>
_componentsPromise?: Promise<Array<void>>
constructor(
options?: RouteOptions<
TParentRoute,
TId,
TCustomId,
TFullPath,
TPath,
TSearchValidator,
TParams,
TLoaderDeps,
TLoaderFn,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
>,
) {
this.options = (options as any) || {}
this.isRoot = !options?.getParentRoute as any
if ((options as any)?.id && (options as any)?.path) {
throw new Error(`Route cannot have both an 'id' and a 'path' option.`)
}
}
types!: RouteTypes<
TParentRoute,
TPath,
TFullPath,
TCustomId,
TId,
TSearchValidator,
TParams,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps,
TLoaderFn,
TChildren,
TFileRouteTypes
>
init = (opts: { originalIndex: number; defaultSsr?: boolean }): void => {
this.originalIndex = opts.originalIndex
const options = this.options as
| (RouteOptions<
TParentRoute,
TId,
TCustomId,
TFullPath,
TPath,
TSearchValidator,
TParams,
TLoaderDeps,
TLoaderFn,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
> &
RoutePathOptionsIntersection<TCustomId, TPath>)
| undefined
const isRoot = !options?.path && !options?.id
this.parentRoute = this.options.getParentRoute?.()
if (isRoot) {
this._path = rootRouteId as TPath
} else if (!this.parentRoute) {
throw new Error(
`Child Route instances must pass a 'getParentRoute: () => ParentRoute' option that returns a Route instance.`,
)
}
let path: undefined | string = isRoot ? rootRouteId : options?.path
// If the path is anything other than an index path, trim it up
if (path && path !== '/') {
path = trimPathLeft(path)
}
const customId = options?.id || path
// Strip the parentId prefix from the first level of children
let id = isRoot
? rootRouteId
: joinPaths([
this.parentRoute.id === rootRouteId ? '' : this.parentRoute.id,
customId,
])
if (path === rootRouteId) {
path = '/'
}
if (id !== rootRouteId) {
id = joinPaths(['/', id])
}
const fullPath =
id === rootRouteId ? '/' : joinPaths([this.parentRoute.fullPath, path])
this._path = path as TPath
this._id = id as TId
this._fullPath = fullPath as TFullPath
this._to = fullPath as TrimPathRight<TFullPath>
this._ssr = options?.ssr ?? opts.defaultSsr ?? true
}
addChildren: RouteAddChildrenFn<
TParentRoute,
TPath,
TFullPath,
TCustomId,
TId,
TSearchValidator,
TParams,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps,
TLoaderFn,
TFileRouteTypes
> = (children) => {
return this._addFileChildren(children) as any
}
_addFileChildren: RouteAddFileChildrenFn<
TParentRoute,
TPath,
TFullPath,
TCustomId,
TId,
TSearchValidator,
TParams,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps,
TLoaderFn,
TFileRouteTypes
> = (children) => {
if (Array.isArray(children)) {
this.children = children as TChildren
}
if (typeof children === 'object' && children !== null) {
this.children = Object.values(children) as TChildren
}
return this as any
}
_addFileTypes: RouteAddFileTypesFn<
TParentRoute,
TPath,
TFullPath,
TCustomId,
TId,
TSearchValidator,
TParams,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps,
TLoaderFn,
TChildren
> = () => {
return this as any
}
updateLoader = <TNewLoaderFn>(options: {
loader: Constrain<
TNewLoaderFn,
RouteLoaderFn<
TParentRoute,
TCustomId,
TParams,
TLoaderDeps,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
>
>
}) => {
Object.assign(this.options, options)
return this as unknown as BaseRoute<
TParentRoute,
TPath,
TFullPath,
TCustomId,
TId,
TSearchValidator,
TParams,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps,
TNewLoaderFn,
TChildren,
TFileRouteTypes
>
}
update = (
options: UpdatableRouteOptions<
TParentRoute,
TCustomId,
TFullPath,
TParams,
TSearchValidator,
TLoaderFn,
TLoaderDeps,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn
>,
): this => {
Object.assign(this.options, options)
return this
}
lazy: RouteLazyFn<this> = (lazyFn) => {
this.lazyFn = lazyFn
return this
}
}
export class BaseRouteApi<TId, TRouter extends AnyRouter = RegisteredRouter> {
id: TId
constructor({ id }: { id: TId }) {
this.id = id as any
}
notFound = (opts?: NotFoundError) => {
return notFound({ routeId: this.id as string, ...opts })
}
}
export class BaseRootRoute<
in out TSearchValidator = undefined,
in out TRouterContext = {},
in out TRouteContextFn = AnyContext,
in out TBeforeLoadFn = AnyContext,
in out TLoaderDeps extends Record<string, any> = {},
in out TLoaderFn = undefined,
in out TChildren = unknown,
in out TFileRouteTypes = unknown,
> extends BaseRoute<
any, // TParentRoute
'/', // TPath
'/', // TFullPath
string, // TCustomId
RootRouteId, // TId
TSearchValidator, // TSearchValidator
{}, // TParams
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps,
TLoaderFn,
TChildren, // TChildren
TFileRouteTypes
> {
constructor(
options?: RootRouteOptions<
TSearchValidator,
TRouterContext,
TRouteContextFn,
TBeforeLoadFn,
TLoaderDeps,
TLoaderFn
>,
) {
super(options as any)
}
}
//