UNPKG

39.3 kB TypeScript View Raw
1
2import { Action, Location, Path, To } from "./history.js";
3import * as React$1 from "react";
4
5//#region lib/router/utils.d.ts
6type MaybePromise<T> = T | Promise<T>;
7/**
8 * Map of routeId -> data returned from a loader/action/error
9 */
10interface RouteData {
11 [routeId: string]: any;
12}
13type LowerCaseFormMethod = "get" | "post" | "put" | "patch" | "delete";
14type UpperCaseFormMethod = Uppercase<LowerCaseFormMethod>;
15/**
16 * Users can specify either lowercase or uppercase form methods on `<Form>`,
17 * useSubmit(), `<fetcher.Form>`, etc.
18 */
19type HTMLFormMethod = LowerCaseFormMethod | UpperCaseFormMethod;
20/**
21 * Active navigation/fetcher form methods are exposed in uppercase on the
22 * RouterState. This is to align with the normalization done via fetch().
23 */
24type FormMethod = UpperCaseFormMethod;
25type FormEncType = "application/x-www-form-urlencoded" | "multipart/form-data" | "application/json" | "text/plain";
26type JsonObject = { [Key in string]: JsonValue } & { [Key in string]?: JsonValue | undefined };
27type JsonArray = JsonValue[] | readonly JsonValue[];
28type JsonPrimitive = string | number | boolean | null;
29type JsonValue = JsonPrimitive | JsonObject | JsonArray;
30/**
31 * @private
32 * Internal interface to pass around for action submissions, not intended for
33 * external consumption
34 */
35type Submission = {
36 formMethod: FormMethod;
37 formAction: string;
38 formEncType: FormEncType;
39 formData: FormData;
40 json: undefined;
41 text: undefined;
42} | {
43 formMethod: FormMethod;
44 formAction: string;
45 formEncType: FormEncType;
46 formData: undefined;
47 json: JsonValue;
48 text: undefined;
49} | {
50 formMethod: FormMethod;
51 formAction: string;
52 formEncType: FormEncType;
53 formData: undefined;
54 json: undefined;
55 text: string;
56};
57/**
58 * A context instance used as the key for the `get`/`set` methods of a
59 * {@link RouterContextProvider}. Accepts an optional default
60 * value to be returned if no value has been set.
61 */
62interface RouterContext<T = unknown> {
63 defaultValue?: T;
64}
65/**
66 * Creates a type-safe {@link RouterContext} object that can be used to
67 * store and retrieve arbitrary values in [`action`](../../start/framework/route-module#action)s,
68 * [`loader`](../../start/framework/route-module#loader)s, and [middleware](../../how-to/middleware).
69 * Similar to React's [`createContext`](https://react.dev/reference/react/createContext),
70 * but specifically designed for React Router's request/response lifecycle.
71 *
72 * If a `defaultValue` is provided, it will be returned from `context.get()`
73 * when no value has been set for the context. Otherwise, reading this context
74 * when no value has been set will throw an error.
75 *
76 * ```tsx filename=app/context.ts
77 * import { createContext } from "react-router";
78 *
79 * // Create a context for user data
80 * export const userContext =
81 * createContext<User | null>(null);
82 * ```
83 *
84 * ```tsx filename=app/middleware/auth.ts
85 * import { getUserFromSession } from "~/auth.server";
86 * import { userContext } from "~/context";
87 *
88 * export const authMiddleware = async ({
89 * context,
90 * request,
91 * }) => {
92 * const user = await getUserFromSession(request);
93 * context.set(userContext, user);
94 * };
95 * ```
96 *
97 * ```tsx filename=app/routes/profile.tsx
98 * import { userContext } from "~/context";
99 *
100 * export async function loader({
101 * context,
102 * }: Route.LoaderArgs) {
103 * const user = context.get(userContext);
104 *
105 * if (!user) {
106 * throw new Response("Unauthorized", { status: 401 });
107 * }
108 *
109 * return { user };
110 * }
111 * ```
112 *
113 * @public
114 * @category Utils
115 * @mode framework
116 * @mode data
117 * @param defaultValue An optional default value for the context. This value
118 * will be returned if no value has been set for this context.
119 * @returns A {@link RouterContext} object that can be used with
120 * `context.get()` and `context.set()` in [`action`](../../start/framework/route-module#action)s,
121 * [`loader`](../../start/framework/route-module#loader)s, and [middleware](../../how-to/middleware).
122 */
123declare function createContext<T>(defaultValue?: T): RouterContext<T>;
124/**
125 * Provides methods for writing/reading values in application context in a
126 * type-safe way. Primarily for usage with [middleware](../../how-to/middleware).
127 *
128 * @example
129 * import {
130 * createContext,
131 * RouterContextProvider
132 * } from "react-router";
133 *
134 * const userContext = createContext<User | null>(null);
135 * const contextProvider = new RouterContextProvider();
136 * contextProvider.set(userContext, getUser());
137 * // ^ Type-safe
138 * const user = contextProvider.get(userContext);
139 * // ^ User
140 *
141 * @public
142 * @category Utils
143 * @mode framework
144 * @mode data
145 */
146declare class RouterContextProvider {
147 #private;
148 /**
149 * Create a new `RouterContextProvider` instance
150 * @param init An optional initial context map to populate the provider with
151 */
152 constructor(init?: Map<RouterContext, unknown>);
153 /**
154 * Access a value from the context. If no value has been set for the context,
155 * it will return the context's `defaultValue` if provided, or throw an error
156 * if no `defaultValue` was set.
157 * @param context The context to get the value for
158 * @returns The value for the context, or the context's `defaultValue` if no
159 * value was set
160 */
161 get<T>(context: RouterContext<T>): T;
162 /**
163 * Set a value for the context. If the context already has a value set, this
164 * will overwrite it.
165 *
166 * @param context The context to set the value for
167 * @param value The value to set for the context
168 * @returns {void}
169 */
170 set<C extends RouterContext>(context: C, value: C extends RouterContext<infer T> ? T : never): void;
171}
172type DefaultContext = Readonly<RouterContextProvider>;
173/**
174 * @private
175 * Arguments passed to route loader/action functions. Same for now but we keep
176 * this as a private implementation detail in case they diverge in the future.
177 */
178interface DataFunctionArgs<Context> {
179 /** A {@link https://developer.mozilla.org/en-US/docs/Web/API/Request Fetch Request instance} which you can use to read headers (like cookies, and {@link https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams URLSearchParams} from the request. */
180 request: Request;
181 /**
182 * A URL instance representing the application location being navigated to or
183 * fetched.
184 *
185 * In Framework mode, this is a normalized URL with React-Router-specific
186 * implementation details removed (`.data` suffixes, `index`/`_routes` search
187 * params). For the raw incoming URL, use `request.url`.
188 *
189 * This normalization preserves standard URL pathname encoding and casing.
190 * For example, a request to `/%61dmin.data` produces a `url.pathname` of
191 * `/%61dmin`. This is not a canonical representation of the matched route.
192 * For authorization, attach {@link https://reactrouter.com/how-to/middleware#authentication server middleware}
193 * to the protected route or a common ancestor instead of relying on literal
194 * pathname-prefix comparisons.
195 */
196 url: URL;
197 /**
198 * Matched un-interpolated route pattern for the current path (i.e., /blog/:slug).
199 * Mostly useful as a identifier to aggregate on for logging/tracing/etc.
200 */
201 pattern: string;
202 /**
203 * {@link https://reactrouter.com/start/framework/routing#dynamic-segments Dynamic route params} for the current route.
204 * @example
205 * // app/routes.ts
206 * route("teams/:teamId", "./team.tsx"),
207 *
208 * // app/team.tsx
209 * export function loader({
210 * params,
211 * }: Route.LoaderArgs) {
212 * params.teamId;
213 * // ^ string
214 * }
215 */
216 params: Params;
217 /**
218 * This is the context passed in to your server adapter's getLoadContext() function.
219 * It's a way to bridge the gap between the adapter's request/response API with your React Router app.
220 * It is only applicable if you are using a custom server adapter.
221 */
222 context: Context;
223}
224/**
225 * Route middleware `next` function to call downstream handlers and then complete
226 * middlewares from the bottom-up
227 */
228interface MiddlewareNextFunction<Result = unknown> {
229 (): Promise<Result>;
230}
231/**
232 * Route middleware function signature. Receives the same "data" arguments as a
233 * `loader`/`action` (`request`, `params`, `context`) as the first parameter and
234 * a `next` function as the second parameter which will call downstream handlers
235 * and then complete middlewares from the bottom-up
236 */
237type MiddlewareFunction<Result = unknown> = (args: DataFunctionArgs<Readonly<RouterContextProvider>>, next: MiddlewareNextFunction<Result>) => MaybePromise<Result | void>;
238/**
239 * Arguments passed to loader functions
240 */
241interface LoaderFunctionArgs<Context = DefaultContext> extends DataFunctionArgs<Context> {}
242/**
243 * Arguments passed to action functions
244 */
245interface ActionFunctionArgs<Context = DefaultContext> extends DataFunctionArgs<Context> {}
246/**
247 * Loaders and actions can return anything
248 */
249type DataFunctionValue = unknown;
250type DataFunctionReturnValue = MaybePromise<DataFunctionValue>;
251/**
252 * Route loader function signature
253 */
254type LoaderFunction<Context = DefaultContext> = {
255 (args: LoaderFunctionArgs<Context>, handlerCtx?: unknown): DataFunctionReturnValue;
256} & {
257 hydrate?: boolean;
258};
259/**
260 * Route action function signature
261 */
262interface ActionFunction<Context = DefaultContext> {
263 (args: ActionFunctionArgs<Context>, handlerCtx?: unknown): DataFunctionReturnValue;
264}
265/**
266 * Arguments passed to shouldRevalidate function
267 */
268interface ShouldRevalidateFunctionArgs {
269 /** This is the url the navigation started from. You can compare it with `nextUrl` to decide if you need to revalidate this route's data. */
270 currentUrl: URL;
271 /** These are the {@link https://reactrouter.com/start/framework/routing#dynamic-segments dynamic route params} from the URL that can be compared to the `nextParams` to decide if you need to reload or not. Perhaps you're using only a partial piece of the param for data loading, you don't need to revalidate if a superfluous part of the param changed. */
272 currentParams: DataRouteMatch["params"];
273 /** In the case of navigation, this the URL the user is requesting. Some revalidations are not navigation, so it will simply be the same as currentUrl. */
274 nextUrl: URL;
275 /** In the case of navigation, these are the {@link https://reactrouter.com/start/framework/routing#dynamic-segments dynamic route params} from the next location the user is requesting. Some revalidations are not navigation, so it will simply be the same as currentParams. */
276 nextParams: DataRouteMatch["params"];
277 /** The method (probably `"GET"` or `"POST"`) used in the form submission that triggered the revalidation. */
278 formMethod?: Submission["formMethod"];
279 /** The form action (`<Form action="/somewhere">`) that triggered the revalidation. */
280 formAction?: Submission["formAction"];
281 /** The form encType (`<Form encType="application/x-www-form-urlencoded">) used in the form submission that triggered the revalidation*/
282 formEncType?: Submission["formEncType"];
283 /** The form submission data when the form's encType is `text/plain` */
284 text?: Submission["text"];
285 /** The form submission data when the form's encType is `application/x-www-form-urlencoded` or `multipart/form-data` */
286 formData?: Submission["formData"];
287 /** The form submission data when the form's encType is `application/json` */
288 json?: Submission["json"];
289 /** The status code of the action response */
290 actionStatus?: number;
291 /**
292 * When a submission causes the revalidation this will be the result of the action—either action data or an error if the action failed. It's common to include some information in the action result to instruct shouldRevalidate to revalidate or not.
293 *
294 * @example
295 * export async function action() {
296 * await saveSomeStuff();
297 * return { ok: true };
298 * }
299 *
300 * export function shouldRevalidate({
301 * actionResult,
302 * }) {
303 * if (actionResult?.ok) {
304 * return false;
305 * }
306 * return true;
307 * }
308 */
309 actionResult?: any;
310 /**
311 * By default, React Router doesn't call every loader all the time. There are reliable optimizations it can make by default. For example, only loaders with changing params are called. Consider navigating from the following URL to the one below it:
312 *
313 * /projects/123/tasks/abc
314 * /projects/123/tasks/def
315 * React Router will only call the loader for tasks/def because the param for projects/123 didn't change.
316 *
317 * It's safest to always return defaultShouldRevalidate after you've done your specific optimizations that return false, otherwise your UI might get out of sync with your data on the server.
318 */
319 defaultShouldRevalidate: boolean;
320}
321/**
322 * Route shouldRevalidate function signature. This runs after any submission
323 * (navigation or fetcher), so we flatten the navigation/fetcher submission
324 * onto the arguments. It shouldn't matter whether it came from a navigation
325 * or a fetcher, what really matters is the URLs and the formData since loaders
326 * have to re-run based on the data models that were potentially mutated.
327 */
328interface ShouldRevalidateFunction {
329 (args: ShouldRevalidateFunctionArgs): boolean;
330}
331interface DataStrategyMatch extends RouteMatch<string, DataRouteObject> {
332 /**
333 * @private
334 */
335 _lazyPromises?: {
336 middleware: Promise<void> | undefined;
337 handler: Promise<void> | undefined;
338 route: Promise<void> | undefined;
339 };
340 /**
341 * @deprecated Deprecated in favor of `shouldCallHandler`
342 *
343 * A boolean value indicating whether this route handler should be called in
344 * this pass.
345 *
346 * The `matches` array always includes _all_ matched routes even when only
347 * _some_ route handlers need to be called so that things like middleware can
348 * be implemented.
349 *
350 * `shouldLoad` is usually only interesting if you are skipping the route
351 * handler entirely and implementing custom handler logic - since it lets you
352 * determine if that custom logic should run for this route or not.
353 *
354 * For example:
355 * - If you are on `/parent/child/a` and you navigate to `/parent/child/b` -
356 * you'll get an array of three matches (`[parent, child, b]`), but only `b`
357 * will have `shouldLoad=true` because the data for `parent` and `child` is
358 * already loaded
359 * - If you are on `/parent/child/a` and you submit to `a`'s [`action`](https://reactrouter.com/docs/start/data/route-object#action),
360 * then only `a` will have `shouldLoad=true` for the action execution of
361 * `dataStrategy`
362 * - After the [`action`](https://reactrouter.com/docs/start/data/route-object#action),
363 * `dataStrategy` will be called again for the [`loader`](https://reactrouter.com/docs/start/data/route-object#loader)
364 * revalidation, and all matches will have `shouldLoad=true` (assuming no
365 * custom `shouldRevalidate` implementations)
366 */
367 shouldLoad: boolean;
368 /**
369 * Arguments passed to the `shouldRevalidate` function for this `loader` execution.
370 * Will be `null` if this is not a revalidating loader {@link DataStrategyMatch}.
371 */
372 shouldRevalidateArgs: ShouldRevalidateFunctionArgs | null;
373 /**
374 * Determine if this route's handler should be called during this `dataStrategy`
375 * execution. Calling it with no arguments will leverage the default revalidation
376 * behavior. You can pass your own `defaultShouldRevalidate` value if you wish
377 * to change the default revalidation behavior with your `dataStrategy`.
378 *
379 * @param defaultShouldRevalidate `defaultShouldRevalidate` override value (optional)
380 */
381 shouldCallHandler(defaultShouldRevalidate?: boolean): boolean;
382 /**
383 * An async function that will resolve any `route.lazy` implementations and
384 * execute the route's handler (if necessary), returning a {@link DataStrategyResult}
385 *
386 * - Calling `match.resolve` does not mean you're calling the
387 * [`action`](https://reactrouter.com/docs/start/data/route-object#action)/[`loader`](https://reactrouter.com/docs/start/data/route-object#loader)
388 * (the "handler") - `resolve` will only call the `handler` internally if
389 * needed _and_ if you don't pass your own `handlerOverride` function parameter
390 * - It is safe to call `match.resolve` for all matches, even if they have
391 * `shouldLoad=false`, and it will no-op if no loading is required
392 * - You should generally always call `match.resolve()` for `shouldLoad:true`
393 * routes to ensure that any `route.lazy` implementations are processed
394 * - See the examples below for how to implement custom handler execution via
395 * `match.resolve`
396 */
397 resolve: (handlerOverride?: (handler: (ctx?: unknown) => DataFunctionReturnValue) => DataFunctionReturnValue) => Promise<DataStrategyResult>;
398}
399/**
400 * The operation that initiated a data strategy execution. Static handler
401 * executions use `"static"`.
402 */
403type DataStrategyInitiator = "initialization" | "navigation" | "fetcher" | "revalidation" | "static";
404interface DataStrategyFunctionArgs<Context = DefaultContext> extends DataFunctionArgs<Context> {
405 /**
406 * Matches for this route extended with Data strategy APIs
407 */
408 matches: DataStrategyMatch[];
409 runClientMiddleware: (cb: DataStrategyFunction<Context>) => Promise<Record<string, DataStrategyResult>>;
410 /**
411 * The operation that initiated this data strategy execution
412 *
413 * This field is experimental and subject to breaking changes.
414 */
415 unstable_initiator: DataStrategyInitiator;
416 /**
417 * The history action (`"PUSH"`, `"REPLACE"`, or `"POP"`) for a navigation-
418 * initiated execution, including fetchers reloaded by that navigation.
419 * `null` for initialization, fetcher, revalidation, and static executions.
420 *
421 * This field is experimental and subject to breaking changes.
422 */
423 unstable_navigationType: Action | null;
424 /**
425 * The key of the fetcher targeted by this data strategy execution, otherwise
426 * `null`. Fetchers reloaded during a navigation or revalidation retain that
427 * `unstable_initiator` while providing their key here.
428 */
429 fetcherKey: string | null;
430}
431/**
432 * Result from a loader or action called via dataStrategy
433 */
434interface DataStrategyResult {
435 type: "data" | "error";
436 result: unknown;
437}
438interface DataStrategyFunction<Context = DefaultContext> {
439 (args: DataStrategyFunctionArgs<Context>): Promise<Record<string, DataStrategyResult>>;
440}
441type PatchRoutesOnNavigationFunctionArgs = {
442 signal: AbortSignal;
443 path: string;
444 matches: RouteMatch[];
445 fetcherKey: string | undefined;
446 patch: (routeId: string | null, children: RouteObject[]) => void;
447};
448type PatchRoutesOnNavigationFunction = (opts: PatchRoutesOnNavigationFunctionArgs) => MaybePromise<void>;
449/**
450 * Function provided to set route-specific properties from route objects
451 */
452interface MapRoutePropertiesFunction {
453 (route: DataRouteObject): Partial<DataRouteObject>;
454}
455/**
456 * Keys we cannot change from within a lazy object. We spread all other keys
457 * onto the route. Either they're meaningful to the router, or they'll get
458 * ignored.
459 */
460type UnsupportedLazyRouteObjectKey = "lazy" | "caseSensitive" | "path" | "id" | "index" | "children" | "unstable_validateParams";
461/**
462 * Keys we cannot change from within a lazy() function. We spread all other keys
463 * onto the route. Either they're meaningful to the router, or they'll get
464 * ignored.
465 */
466type UnsupportedLazyRouteFunctionKey = UnsupportedLazyRouteObjectKey | "middleware";
467/**
468 * lazy object to load route properties, which can add non-matching
469 * related properties to a route
470 */
471type LazyRouteObject<R extends RouteObject> = { [K in keyof R as K extends UnsupportedLazyRouteObjectKey ? never : K]?: () => Promise<R[K] | null | undefined> };
472/**
473 * lazy() function to load a route definition, which can add non-matching
474 * related properties to a route
475 */
476interface LazyRouteFunction<R extends RouteObject> {
477 (): Promise<Omit<R, UnsupportedLazyRouteFunctionKey> & Partial<Record<UnsupportedLazyRouteFunctionKey, never>>>;
478}
479type LazyRouteDefinition<R extends RouteObject> = LazyRouteObject<R> | LazyRouteFunction<R>;
480/**
481 * Base RouteObject with common props shared by all types of routes
482 * @internal
483 */
484type BaseRouteObject = {
485 /**
486 * Whether the path should be case-sensitive. Defaults to `false`.
487 */
488 caseSensitive?: boolean;
489 /**
490 * The path pattern to match. If unspecified or empty, then this becomes a
491 * layout route.
492 */
493 path?: string;
494 /**
495 * The unique identifier for this route (for use with {@link DataRouter}s)
496 */
497 id?: string;
498 /**
499 * The route middleware.
500 * See [`middleware`](../../start/data/route-object#middleware).
501 */
502 middleware?: MiddlewareFunction[];
503 /**
504 * The route loader.
505 * See [`loader`](../../start/data/route-object#loader).
506 */
507 loader?: LoaderFunction | boolean;
508 /**
509 * The route action.
510 * See [`action`](../../start/data/route-object#action).
511 */
512 action?: ActionFunction | boolean;
513 /**
514 * The route shouldRevalidate function.
515 * See [`shouldRevalidate`](../../start/data/route-object#shouldRevalidate).
516 */
517 shouldRevalidate?: ShouldRevalidateFunction;
518 /**
519 * A map of route param names to regular expressions used to validate params
520 * after a route-pattern match.
521 */
522 unstable_validateParams?: Record<string, RegExp>;
523 /**
524 * The route handle.
525 */
526 handle?: any;
527 /**
528 * A function that returns a promise that resolves to the route object.
529 * Used for code-splitting routes.
530 * See [`lazy`](../../start/data/route-object#lazy).
531 */
532 lazy?: LazyRouteDefinition<BaseRouteObject>;
533 /**
534 * The React Component to render when this route matches.
535 * Mutually exclusive with `element`.
536 */
537 Component?: React$1.ComponentType | null;
538 /**
539 * The React element to render when this Route matches.
540 * Mutually exclusive with `Component`.
541 */
542 element?: React$1.ReactNode | null;
543 /**
544 * The React Component to render at this route if an error occurs.
545 * Mutually exclusive with `errorElement`.
546 */
547 ErrorBoundary?: React$1.ComponentType | null;
548 /**
549 * The React element to render at this route if an error occurs.
550 * Mutually exclusive with `ErrorBoundary`.
551 */
552 errorElement?: React$1.ReactNode | null;
553 /**
554 * The React Component to render while this router is loading data.
555 * Mutually exclusive with `hydrateFallbackElement`.
556 */
557 HydrateFallback?: React$1.ComponentType | null;
558 /**
559 * The React element to render while this router is loading data.
560 * Mutually exclusive with `HydrateFallback`.
561 */
562 hydrateFallbackElement?: React$1.ReactNode | null;
563};
564/**
565 * Index routes must not have children
566 */
567type IndexRouteObject = BaseRouteObject & {
568 /**
569 * Child Route objects - not valid on index routes.
570 */
571 children?: undefined;
572 /**
573 * Whether this is an index route.
574 */
575 index: true;
576};
577/**
578 * Non-index routes may have children, but cannot have `index` set to `true`.
579 */
580type NonIndexRouteObject = BaseRouteObject & {
581 /**
582 * Child Route objects.
583 */
584 children?: RouteObject[];
585 /**
586 * Whether this is an index route - must be `false` or undefined on non-index routes.
587 */
588 index?: false;
589};
590/**
591 * A route object represents a logical route, with (optionally) its child
592 * routes organized in a tree-like structure.
593 */
594type RouteObject = IndexRouteObject | NonIndexRouteObject;
595type DataIndexRouteObject = IndexRouteObject & {
596 id: string;
597};
598type DataNonIndexRouteObject = NonIndexRouteObject & {
599 children?: DataRouteObject[];
600 id: string;
601};
602/**
603 * A data route object, which is just a RouteObject with a required unique ID
604 */
605type DataRouteObject = DataIndexRouteObject | DataNonIndexRouteObject;
606type RouteManifest<R = DataRouteObject> = Record<string, R | undefined>;
607type Regex_az = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z";
608type Regex_AZ = Uppercase<Regex_az>;
609type Regex_09 = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
610type Regex_w = Regex_az | Regex_AZ | Regex_09 | "_";
611/** Emulates Regex `+` operator */
612type RegexMatchPlus<char extends string, T extends string> = _RegexMatchPlus<char, T> extends infer result extends string ? result extends '' ? never : result : never;
613type _RegexMatchPlus<char extends string, T extends string> = T extends `${infer head extends char}${infer rest}` ? `${head}${_RegexMatchPlus<char, rest>}` : '';
614type ParamNameChar = Regex_w | "-";
615type Simplify<T> = { [K in keyof T]: T[K] } & {};
616type GeneratePathParams<path extends string> = Simplify<ParseParams<path> & { [key in string]: string | null | undefined }>;
617type ParseParams<path extends string> = path extends '*' ? {
618 '*': string;
619} : path extends `${infer rest}/*` ? {
620 '*': string;
621} & ParseParams<rest> : _ParseParams<path>;
622type _ParseParams<path extends string> = path extends `${infer left}/${infer right}` ? _ParseParams<left> & _ParseParams<right> : path extends `:${infer param}?${string}` ? { [key in RegexMatchPlus<ParamNameChar, param>]?: string | null | undefined } : path extends `:${infer param}` ? { [key in RegexMatchPlus<ParamNameChar, param>]: string } : {};
623type PathParam<path extends string> = (keyof ParseParams<path>) & string;
624type ParamParseKey<Segment extends string> = [PathParam<Segment>] extends [never] ? string : PathParam<Segment>;
625/**
626 * The parameters that were parsed from the URL path.
627 */
628type Params<Key extends string = string> = { readonly [key in Key]: string | undefined };
629/**
630 * A RouteMatch contains info about how a route matched a URL.
631 */
632interface RouteMatch<ParamKey extends string = string, RouteObjectType extends RouteObject = RouteObject> {
633 /**
634 * The names and values of dynamic parameters in the URL.
635 */
636 params: Params<ParamKey>;
637 /**
638 * The portion of the URL pathname that was matched.
639 */
640 pathname: string;
641 /**
642 * The portion of the URL pathname that was matched before child routes.
643 */
644 pathnameBase: string;
645 /**
646 * The route object that was used to match.
647 */
648 route: RouteObjectType;
649}
650interface DataRouteMatch extends RouteMatch<string, DataRouteObject> {}
651declare function defaultMapRouteProperties(route: DataRouteObject): Partial<DataRouteObject>;
652/**
653 * Matches the given routes to a location and returns the match data.
654 *
655 * @example
656 * import { matchRoutes } from "react-router";
657 *
658 * let routes = [{
659 * path: "/",
660 * Component: Root,
661 * children: [{
662 * path: "dashboard",
663 * Component: Dashboard,
664 * }]
665 * }];
666 *
667 * matchRoutes(routes, "/dashboard"); // [rootMatch, dashboardMatch]
668 *
669 * @public
670 * @category Utils
671 * @param routes The array of route objects to match against.
672 * @param locationArg The location to match against, either a string path or a
673 * partial {@link Location} object
674 * @param basename Optional base path to strip from the location before matching.
675 * Defaults to `/`.
676 * @returns An array of matched routes, or `null` if no matches were found.
677 */
678declare function matchRoutes<RouteObjectType extends RouteObject = RouteObject>(routes: RouteObjectType[], locationArg: Partial<Location> | string, basename?: string): RouteMatch<string, RouteObjectType>[] | null;
679interface UIMatch<Data = unknown, Handle = unknown> {
680 id: string;
681 pathname: string;
682 /**
683 * {@link https://reactrouter.com/start/framework/routing#dynamic-segments Dynamic route params} for the matched route.
684 */
685 params: RouteMatch["params"];
686 /**
687 * The return value from the matched route's loader or clientLoader. This might
688 * be `undefined` if this route's `loader` (or a deeper route's `loader`) threw
689 * an error and we're currently displaying an `ErrorBoundary`.
690 */
691 loaderData: Data | undefined;
692 /**
693 * The {@link https://reactrouter.com/start/framework/route-module#handle handle object}
694 * exported from the matched route module
695 */
696 handle: Handle;
697}
698interface RouteMeta<RouteObjectType extends RouteObject = RouteObject> {
699 relativePath: string;
700 caseSensitive: boolean;
701 childrenIndex: number;
702 route: RouteObjectType;
703 matcher?: RegExp;
704 compiledParams?: CompiledPathParam[];
705}
706/**
707 * @private
708 * PRIVATE - DO NOT USE
709 *
710 * A "branch" of routes that match a given route pattern.
711 * This is an internal interface not intended for direct external usage.
712 */
713interface RouteBranch<RouteObjectType extends RouteObject = RouteObject> {
714 path: string;
715 score: number;
716 routesMeta: RouteMeta<RouteObjectType>[];
717}
718/**
719 * Returns a path with params interpolated.
720 *
721 * Param values are percent-encoded for use in a path segment: characters that
722 * would change the URL structure (`/`, `?`, `#`, `%`, whitespace, non-ASCII)
723 * are escaped, while characters that RFC 3986 allows literally in a path
724 * segment (`$ & + , ; = : @`) are kept as-is. Note this differs from query-string
725 * encoding (`encodeURIComponent`/`URLSearchParams`), where those characters are
726 * delimiters and must be escaped. Splat (`*`) values are encoded per segment,
727 * preserving `/` separators.
728 *
729 * See [RFC 3986 §3.3](https://datatracker.ietf.org/doc/html/rfc3986#section-3.3)
730 *
731 * @example
732 * import { generatePath } from "react-router";
733 *
734 * generatePath("/users/:id", { id: "123" }); // "/users/123"
735 * generatePath("/files/:name", { name: "a b" }); // "/files/a%20b"
736 * generatePath("/releases/:v", { v: "1.0.0+1" }); // "/releases/1.0.0+1"
737 *
738 * @public
739 * @category Utils
740 * @param originalPath The original path to generate.
741 * @param params The parameters to interpolate into the path.
742 * @returns The generated path with parameters interpolated.
743 */
744declare function generatePath<Path extends string>(originalPath: Path, params?: GeneratePathParams<Path>): string;
745/**
746 * Used to match on some portion of a URL pathname.
747 */
748interface PathPattern<Path extends string = string> {
749 /**
750 * A string to match against a URL pathname. May contain `:id`-style segments
751 * to indicate placeholders for dynamic parameters. It May also end with `/*`
752 * to indicate matching the rest of the URL pathname.
753 */
754 path: Path;
755 /**
756 * Should be `true` if the static portions of the `path` should be matched in
757 * the same case.
758 */
759 caseSensitive?: boolean;
760 /**
761 * Should be `true` if this pattern should match the entire URL pathname.
762 */
763 end?: boolean;
764}
765/**
766 * Contains info about how a {@link PathPattern} matched on a URL pathname.
767 */
768interface PathMatch<ParamKey extends string = string> {
769 /**
770 * The names and values of dynamic parameters in the URL.
771 */
772 params: Params<ParamKey>;
773 /**
774 * The portion of the URL pathname that was matched.
775 */
776 pathname: string;
777 /**
778 * The portion of the URL pathname that was matched before child routes.
779 */
780 pathnameBase: string;
781 /**
782 * The pattern that was used to match.
783 */
784 pattern: PathPattern;
785}
786/**
787 * Performs pattern matching on a URL pathname and returns information about
788 * the match.
789 *
790 * @public
791 * @category Utils
792 * @param pattern The pattern to match against the URL pathname. This can be a
793 * string or a {@link PathPattern} object. If a string is provided, it will be
794 * treated as a pattern with `caseSensitive` set to `false` and `end` set to
795 * `true`.
796 * @param pathname The URL pathname to match against the pattern.
797 * @returns A path match object if the pattern matches the pathname,
798 * or `null` if it does not match.
799 */
800declare function matchPath<Path extends string>(pattern: PathPattern<Path> | Path, pathname: string): PathMatch<ParamParseKey<Path>> | null;
801type CompiledPathParam = {
802 paramName: string;
803 isOptional?: boolean;
804};
805/**
806 * Returns a resolved {@link Path} object relative to the given pathname.
807 *
808 * @public
809 * @category Utils
810 * @param to The path to resolve, either a string or a partial {@link Path}
811 * object.
812 * @param fromPathname The pathname to resolve the path from. Defaults to `/`.
813 * @returns A {@link Path} object with the resolved pathname, search, and hash.
814 */
815declare function resolvePath(to: To, fromPathname?: string): Path;
816declare class DataWithResponseInit<D> {
817 type: string;
818 data: D;
819 init: ResponseInit | null;
820 constructor(data: D, init?: ResponseInit);
821}
822/**
823 * Create "responses" that contain `headers`/`status` without forcing
824 * serialization into an actual [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)
825 *
826 * @example
827 * import { data } from "react-router";
828 *
829 * export async function action({ request }: Route.ActionArgs) {
830 * let formData = await request.formData();
831 * let item = await createItem(formData);
832 * return data(item, {
833 * headers: { "X-Custom-Header": "value" }
834 * status: 201,
835 * });
836 * }
837 *
838 * @public
839 * @category Utils
840 * @mode framework
841 * @mode data
842 * @param data The data to be included in the response.
843 * @param init The status code or a `ResponseInit` object to be included in the
844 * response.
845 * @returns A {@link DataWithResponseInit} instance containing the data and
846 * response init.
847 */
848declare function data<D>(data: D, init?: number | ResponseInit): DataWithResponseInit<D>;
849interface TrackedPromise extends Promise<any> {
850 _tracked?: boolean;
851 _data?: any;
852 _error?: any;
853}
854type RedirectFunction = (url: string, init?: number | ResponseInit) => Response;
855/**
856 * A redirect [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response).
857 * Sets the status code and the [`Location`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location)
858 * header. Defaults to [`302 Found`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302).
859 *
860 * This utility accepts absolute URLs and can navigate to external domains, so
861 * the application should validate any user-supplied inputs to redirects.
862 *
863 * @example
864 * import { redirect } from "react-router";
865 *
866 * export async function loader({ request }: Route.LoaderArgs) {
867 * if (!isLoggedIn(request))
868 * throw redirect("/login");
869 * }
870 *
871 * // ...
872 * }
873 *
874 * @public
875 * @category Utils
876 * @mode framework
877 * @mode data
878 * @param url The URL to redirect to.
879 * @param init The status code or a `ResponseInit` object to be included in the
880 * response.
881 * @returns A [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)
882 * object with the redirect status and [`Location`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location)
883 * header.
884 */
885declare const redirect: RedirectFunction;
886/**
887 * A redirect [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)
888 * that will force a document reload to the new location. Sets the status code
889 * and the [`Location`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location)
890 * header. Defaults to [`302 Found`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302).
891 *
892 * This utility accepts absolute URLs and can navigate to external domains, so
893 * the application should validate any user-supplied inputs to redirects.
894 *
895 * ```tsx filename=routes/logout.tsx
896 * import { redirectDocument } from "react-router";
897 *
898 * import { destroySession } from "../sessions.server";
899 *
900 * export async function action({ request }: Route.ActionArgs) {
901 * let session = await getSession(request.headers.get("Cookie"));
902 * return redirectDocument("/", {
903 * headers: { "Set-Cookie": await destroySession(session) }
904 * });
905 * }
906 * ```
907 *
908 * @public
909 * @category Utils
910 * @mode framework
911 * @mode data
912 * @param url The URL to redirect to.
913 * @param init The status code or a `ResponseInit` object to be included in the
914 * response.
915 * @returns A [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)
916 * object with the redirect status and [`Location`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location)
917 * header.
918 */
919declare const redirectDocument: RedirectFunction;
920/**
921 * A redirect [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)
922 * that will perform a [`history.replaceState`](https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState)
923 * instead of a [`history.pushState`](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState)
924 * for client-side navigation redirects. Sets the status code and the [`Location`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location)
925 * header. Defaults to [`302 Found`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302).
926 *
927 * @example
928 * import { replace } from "react-router";
929 *
930 * export async function loader() {
931 * return replace("/new-location");
932 * }
933 *
934 * @public
935 * @category Utils
936 * @mode framework
937 * @mode data
938 * @param url The URL to redirect to.
939 * @param init The status code or a `ResponseInit` object to be included in the
940 * response.
941 * @returns A [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)
942 * object with the redirect status and [`Location`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location)
943 * header.
944 */
945declare const replace: RedirectFunction;
946type ErrorResponse = {
947 status: number;
948 statusText: string;
949 data: any;
950};
951declare class ErrorResponseImpl implements ErrorResponse {
952 status: number;
953 statusText: string;
954 data: any;
955 private error?;
956 private internal;
957 constructor(status: number, statusText: string | undefined, data: any, internal?: boolean);
958}
959/**
960 * Check if the given error is an {@link ErrorResponse} generated from a 4xx/5xx
961 * [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)
962 * thrown from an [`action`](../../start/framework/route-module#action) or
963 * [`loader`](../../start/framework/route-module#loader) function.
964 *
965 * @example
966 * import { isRouteErrorResponse } from "react-router";
967 *
968 * export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
969 * if (isRouteErrorResponse(error)) {
970 * return (
971 * <>
972 * <p>Error: `${error.status}: ${error.statusText}`</p>
973 * <p>{error.data}</p>
974 * </>
975 * );
976 * }
977 *
978 * return (
979 * <p>Error: {error instanceof Error ? error.message : "Unknown Error"}</p>
980 * );
981 * }
982 *
983 * @public
984 * @category Utils
985 * @mode framework
986 * @mode data
987 * @param error The error to check.
988 * @returns `true` if the error is an {@link ErrorResponse}, `false` otherwise.
989 */
990declare function isRouteErrorResponse(error: any): error is ErrorResponse;
991//#endregion
992export { ActionFunction, ActionFunctionArgs, BaseRouteObject, DataRouteMatch, DataRouteObject, DataStrategyFunction, DataStrategyFunctionArgs, DataStrategyInitiator, DataStrategyMatch, DataStrategyResult, DataWithResponseInit, ErrorResponse, ErrorResponseImpl, FormEncType, FormMethod, HTMLFormMethod, IndexRouteObject, LazyRouteFunction, LoaderFunction, LoaderFunctionArgs, MapRoutePropertiesFunction, MaybePromise, MiddlewareFunction, MiddlewareNextFunction, NonIndexRouteObject, ParamParseKey, Params, PatchRoutesOnNavigationFunction, PatchRoutesOnNavigationFunctionArgs, PathMatch, PathParam, PathPattern, RedirectFunction, RouteBranch, RouteData, RouteManifest, RouteMatch, RouteObject, RouterContext, RouterContextProvider, ShouldRevalidateFunction, ShouldRevalidateFunctionArgs, Submission, TrackedPromise, UIMatch, createContext, data, defaultMapRouteProperties, generatePath, isRouteErrorResponse, matchPath, matchRoutes, redirect, redirectDocument, replace, resolvePath };
\No newline at end of file