UNPKG

6.71 kBTypeScriptView Raw
1
2import { DataWithResponseInit, RouterContextProvider } from "../router/utils.js";
3import { Equal, Func, IsAny } from "./utils.js";
4import { RouteModule } from "./route-module.js";
5import { unstable_SerializesTo } from "./serializes-to.js";
6import { Serializable } from "../server-runtime/single-fetch.js";
7import { ClientActionFunctionArgs, ClientLoaderFunctionArgs } from "../dom/ssr/routeModules.js";
8
9//#region lib/types/route-data.d.ts
10type Serialize<T> = T extends unstable_SerializesTo<infer To> ? To : T extends Serializable ? T : T extends ((...args: any[]) => unknown) ? undefined : T extends Promise<infer U> ? Promise<Serialize<U>> : T extends Map<infer K, infer V> ? Map<Serialize<K>, Serialize<V>> : T extends ReadonlyMap<infer K, infer V> ? ReadonlyMap<Serialize<K>, Serialize<V>> : T extends Set<infer U> ? Set<Serialize<U>> : T extends ReadonlySet<infer U> ? ReadonlySet<Serialize<U>> : T extends [] ? [] : T extends readonly [infer F, ...infer R] ? [Serialize<F>, ...Serialize<R>] : T extends Array<infer U> ? Array<Serialize<U>> : T extends readonly unknown[] ? readonly Serialize<T[number]>[] : T extends Record<any, any> ? { [K in keyof T]: Serialize<T[K]> } : undefined;
11type VoidToUndefined<T> = Equal<T, void> extends true ? undefined : T;
12type DataFrom<T> = IsAny<T> extends true ? undefined : T extends Func ? VoidToUndefined<Awaited<ReturnType<T>>> : undefined;
13type ClientData<T> = T extends Response ? never : T extends DataWithResponseInit<infer U> ? U : T;
14type ServerData<T> = T extends Response ? never : T extends DataWithResponseInit<infer U> ? Serialize<U> : Serialize<T>;
15type ServerDataFrom<T> = ServerData<DataFrom<T>>;
16type ClientDataFrom<T> = ClientData<DataFrom<T>>;
17type ClientDataFunctionArgs<Params> = {
18 /**
19 * A {@link https://developer.mozilla.org/en-US/docs/Web/API/Request Fetch Request instance} which you can use to read the URL, the method, the "content-type" header, and the request body from the request.
20 *
21 * @note Because client data functions are called before a network request is made, the Request object does not include the headers which the browser automatically adds. React Router infers the "content-type" header from the enc-type of the form that performed the submission.
22 **/
23 request: Request;
24 /**
25 * A URL instance representing the application location being navigated to or
26 * fetched.
27 *
28 * In Framework mode, this is a normalized URL with React-Router-specific
29 * implementation details removed (`.data` suffixes, `index`/`_routes` search
30 * params). For the raw incoming URL, use `request.url`.
31 */
32 url: URL;
33 /**
34 * {@link https://reactrouter.com/start/framework/routing#dynamic-segments Dynamic route params} for the current route.
35 * @example
36 * // app/routes.ts
37 * route("teams/:teamId", "./team.tsx"),
38 *
39 * // app/team.tsx
40 * export function clientLoader({
41 * params,
42 * }: Route.ClientLoaderArgs) {
43 * params.teamId;
44 * // ^ string
45 * }
46 **/
47 params: Params;
48 /**
49 * Matched un-interpolated route pattern for the current path (i.e., /blog/:slug).
50 * Mostly useful as a identifier to aggregate on for logging/tracing/etc.
51 */
52 pattern: string;
53 /**
54 * An instance of `RouterContextProvider` that can be used to access context
55 * values from your route middlewares. You may pass in initial context values
56 * in your `<HydratedRouter getContext>` prop.
57 */
58 context: Readonly<RouterContextProvider>;
59};
60type ServerDataFunctionArgs<Params> = {
61 /** A {@link https://developer.mozilla.org/en-US/docs/Web/API/Request Fetch Request instance} which you can use to read the url, method, headers (such as cookies), and request body from the request. */request: Request;
62 /**
63 * A URL instance representing the application location being navigated to or
64 * fetched.
65 *
66 * In Framework mode, this is a normalized URL with React-Router-specific
67 * implementation details removed (`.data` suffixes, `index`/`_routes` search
68 * params). For the raw incoming URL, use `request.url`.
69 */
70 url: URL;
71 /**
72 * {@link https://reactrouter.com/start/framework/routing#dynamic-segments Dynamic route params} for the current route.
73 * @example
74 * // app/routes.ts
75 * route("teams/:teamId", "./team.tsx"),
76 *
77 * // app/team.tsx
78 * export function loader({
79 * params,
80 * }: Route.LoaderArgs) {
81 * params.teamId;
82 * // ^ string
83 * }
84 **/
85 params: Params;
86 /**
87 * Matched un-interpolated route pattern for the current path (i.e., /blog/:slug).
88 * Mostly useful as a identifier to aggregate on for logging/tracing/etc.
89 */
90 pattern: string;
91 /**
92 * An instance of `RouterContextProvider` that can be used for type-safe
93 * access to context values set in your route middlewares. If you are using
94 * a custom server adapter, you may provide an initial set of context values
95 * from your `getLoadContext` function.
96 */
97 context: Readonly<RouterContextProvider>;
98};
99type SerializeFrom<T> = T extends ((...args: infer Args) => unknown) ? Args extends [ClientLoaderFunctionArgs | ClientActionFunctionArgs | ClientDataFunctionArgs<unknown>] ? ClientDataFrom<T> : ServerDataFrom<T> : T;
100type IsDefined<T> = Equal<T, undefined> extends true ? false : true;
101type IsHydrate<ClientLoader> = ClientLoader extends {
102 hydrate: true;
103} ? true : ClientLoader extends {
104 hydrate: false;
105} ? false : false;
106type GetLoaderData<T extends RouteModule> = _DataLoaderData<ServerDataFrom<T["loader"]>, ClientDataFrom<T["clientLoader"]>, IsHydrate<T["clientLoader"]>, T extends {
107 HydrateFallback: Func;
108} ? true : false>;
109type _DataLoaderData<ServerLoaderData, ClientLoaderData, ClientLoaderHydrate extends boolean, HasHydrateFallback> = [HasHydrateFallback, ClientLoaderHydrate] extends [true, true] ? IsDefined<ClientLoaderData> extends true ? ClientLoaderData : undefined : [IsDefined<ClientLoaderData>, IsDefined<ServerLoaderData>] extends [true, true] ? ServerLoaderData | ClientLoaderData : IsDefined<ClientLoaderData> extends true ? ClientLoaderData : IsDefined<ServerLoaderData> extends true ? ServerLoaderData : undefined;
110type GetActionData<T extends RouteModule> = _DataActionData<ServerDataFrom<T["action"]>, ClientDataFrom<T["clientAction"]>>;
111type _DataActionData<ServerActionData, ClientActionData> = Awaited<[IsDefined<ServerActionData>, IsDefined<ClientActionData>] extends [true, true] ? ServerActionData | ClientActionData : IsDefined<ClientActionData> extends true ? ClientActionData : IsDefined<ServerActionData> extends true ? ServerActionData : undefined>;
112//#endregion
113export { ClientDataFunctionArgs, GetActionData, GetLoaderData, SerializeFrom, ServerDataFrom, ServerDataFunctionArgs };
\No newline at end of file