UNPKG

7.59 kBTypeScriptView Raw
1
2import { Location } from "../../router/history.js";
3import { ActionFunction, ActionFunctionArgs, DataRouteMatch, DataStrategyResult, LoaderFunction, LoaderFunctionArgs, MiddlewareFunction, Params, ShouldRevalidateFunction } from "../../router/utils.js";
4import { LinkDescriptor } from "../../router/links.js";
5import { SerializeFrom } from "../../types/route-data.js";
6import { ComponentType, ReactElement } from "react";
7
8//#region lib/dom/ssr/routeModules.d.ts
9interface RouteModules {
10 [routeId: string]: RouteModule | undefined;
11}
12/**
13 * The shape of a route module shipped to the client
14 */
15interface RouteModule {
16 clientAction?: ClientActionFunction;
17 clientLoader?: ClientLoaderFunction;
18 clientMiddleware?: MiddlewareFunction<Record<string, DataStrategyResult>>[];
19 ErrorBoundary?: ErrorBoundaryComponent;
20 HydrateFallback?: HydrateFallbackComponent;
21 Layout?: LayoutComponent;
22 default: RouteComponent;
23 handle?: RouteHandle;
24 links?: LinksFunction;
25 meta?: MetaFunction;
26 shouldRevalidate?: ShouldRevalidateFunction;
27}
28/**
29 * The shape of a route module on the server
30 */
31interface ServerRouteModule extends RouteModule {
32 action?: ActionFunction;
33 headers?: HeadersFunction | {
34 [name: string]: string;
35 };
36 loader?: LoaderFunction;
37 middleware?: MiddlewareFunction<Response>[];
38}
39/**
40 * A function that handles data mutations for a route on the client
41 */
42type ClientActionFunction = (args: ClientActionFunctionArgs) => ReturnType<ActionFunction>;
43/**
44 * Arguments passed to a route `clientAction` function
45 */
46type ClientActionFunctionArgs = ActionFunctionArgs & {
47 serverAction: <T = unknown>() => Promise<SerializeFrom<T>>;
48};
49/**
50 * A function that loads data for a route on the client
51 */
52type ClientLoaderFunction = ((args: ClientLoaderFunctionArgs) => ReturnType<LoaderFunction>) & {
53 hydrate?: boolean;
54};
55/**
56 * Arguments passed to a route `clientLoader` function
57 */
58type ClientLoaderFunctionArgs = LoaderFunctionArgs & {
59 serverLoader: <T = unknown>() => Promise<SerializeFrom<T>>;
60};
61/**
62 * ErrorBoundary to display for this route
63 */
64type ErrorBoundaryComponent = ComponentType;
65type HeadersArgs = {
66 loaderHeaders: Headers;
67 parentHeaders: Headers;
68 actionHeaders: Headers;
69 errorHeaders: Headers | undefined;
70};
71/**
72 * A function that returns HTTP headers to be used for a route. These headers
73 * will be merged with (and take precedence over) headers from parent routes.
74 */
75interface HeadersFunction {
76 (args: HeadersArgs): Headers | HeadersInit;
77}
78/**
79 * `<Route HydrateFallback>` component to render on initial loads
80 * when client loaders are present
81 */
82type HydrateFallbackComponent = ComponentType;
83/**
84 * Optional, root-only `<Route Layout>` component to wrap the root content in.
85 * Useful for defining the <html>/<head>/<body> document shell shared by the
86 * Component, HydrateFallback, and ErrorBoundary
87 */
88type LayoutComponent = ComponentType<{
89 children: ReactElement<unknown, ErrorBoundaryComponent | HydrateFallbackComponent | RouteComponent>;
90}>;
91/**
92 * A function that defines `<link>` tags to be inserted into the `<head>` of
93 * the document on route transitions.
94 *
95 * @see https://reactrouter.com/start/framework/route-module#meta
96 */
97interface LinksFunction {
98 (): LinkDescriptor[];
99}
100interface MetaMatch<RouteId extends string = string, Loader extends LoaderFunction | ClientLoaderFunction | unknown = unknown> {
101 id: RouteId;
102 pathname: DataRouteMatch["pathname"];
103 loaderData: Loader extends LoaderFunction | ClientLoaderFunction ? SerializeFrom<Loader> : unknown;
104 handle?: RouteHandle;
105 params: DataRouteMatch["params"];
106 meta: MetaDescriptor[];
107 error?: unknown;
108}
109type MetaMatches<MatchLoaders extends Record<string, LoaderFunction | ClientLoaderFunction | unknown> = Record<string, unknown>> = Array<{ [K in keyof MatchLoaders]: MetaMatch<Exclude<K, number | symbol>, MatchLoaders[K]> }[keyof MatchLoaders]>;
110interface MetaArgs<Loader extends LoaderFunction | ClientLoaderFunction | unknown = unknown, MatchLoaders extends Record<string, LoaderFunction | ClientLoaderFunction | unknown> = Record<string, unknown>> {
111 loaderData: (Loader extends LoaderFunction | ClientLoaderFunction ? SerializeFrom<Loader> : unknown) | undefined;
112 params: Params;
113 location: Location;
114 matches: MetaMatches<MatchLoaders>;
115 error?: unknown;
116}
117/**
118 * A function that returns an array of data objects to use for rendering
119 * metadata HTML tags in a route. These tags are not rendered on descendant
120 * routes in the route hierarchy. In other words, they will only be rendered on
121 * the route in which they are exported.
122 *
123 * @param Loader - The type of the current route's loader function
124 * @param MatchLoaders - Mapping from a parent route's filepath to its loader
125 * function type
126 *
127 * Note that parent route filepaths are relative to the `app/` directory.
128 *
129 * For example, if this meta function is for `/sales/customers/$customerId`:
130 *
131 * ```ts
132 * // app/root.tsx
133 * const loader = () => ({ hello: "world" })
134 * export type Loader = typeof loader
135 *
136 * // app/routes/sales.tsx
137 * const loader = () => ({ salesCount: 1074 })
138 * export type Loader = typeof loader
139 *
140 * // app/routes/sales/customers.tsx
141 * const loader = () => ({ customerCount: 74 })
142 * export type Loader = typeof loader
143 *
144 * // app/routes/sales/customers/$customersId.tsx
145 * import type { Loader as RootLoader } from "../../../root"
146 * import type { Loader as SalesLoader } from "../../sales"
147 * import type { Loader as CustomersLoader } from "../../sales/customers"
148 *
149 * const loader = () => ({ name: "Customer name" })
150 *
151 * const meta: MetaFunction<typeof loader, {
152 * "root": RootLoader,
153 * "routes/sales": SalesLoader,
154 * "routes/sales/customers": CustomersLoader,
155 * }> = ({ loaderData, matches }) => {
156 * const { name } = loaderData
157 * // ^? string
158 * const { customerCount } = matches.find((match) => match.id === "routes/sales/customers").loaderData
159 * // ^? number
160 * const { salesCount } = matches.find((match) => match.id === "routes/sales").loaderData
161 * // ^? number
162 * const { hello } = matches.find((match) => match.id === "root").loaderData
163 * // ^? "world"
164 * }
165 * ```
166 */
167interface MetaFunction<Loader extends LoaderFunction | ClientLoaderFunction | unknown = unknown, MatchLoaders extends Record<string, LoaderFunction | ClientLoaderFunction | unknown> = Record<string, unknown>> {
168 (args: MetaArgs<Loader, MatchLoaders>): MetaDescriptor[] | undefined;
169}
170type MetaDescriptor = {
171 charSet: "utf-8";
172} | {
173 title: string;
174} | {
175 name: string;
176 content: string;
177} | {
178 property: string;
179 content: string;
180} | {
181 httpEquiv: string;
182 content: string;
183} | {
184 "script:ld+json": LdJsonObject | LdJsonObject[];
185} | {
186 tagName: "meta" | "link";
187 [name: string]: string;
188} | {
189 [name: string]: unknown;
190};
191type LdJsonObject = { [Key in string]: LdJsonValue } & { [Key in string]?: LdJsonValue | undefined };
192type LdJsonArray = LdJsonValue[] | readonly LdJsonValue[];
193type LdJsonPrimitive = string | number | boolean | null;
194type LdJsonValue = LdJsonPrimitive | LdJsonObject | LdJsonArray;
195/**
196 * A React component that is rendered for a route.
197 */
198type RouteComponent = ComponentType<{}>;
199/**
200 * An arbitrary object that is associated with a route.
201 *
202 * @see https://reactrouter.com/how-to/using-handle
203 */
204type RouteHandle = unknown;
205//#endregion
206export { ClientActionFunction, ClientActionFunctionArgs, ClientLoaderFunction, ClientLoaderFunctionArgs, HeadersArgs, HeadersFunction, LinksFunction, MetaArgs, MetaDescriptor, MetaFunction, RouteModules, ServerRouteModule };
\No newline at end of file