UNPKG

@remix-run/server-runtime

Version:
238 lines (237 loc) • 8.52 kB
import type { AgnosticRouteMatch, Location, Params, RouterState } from "@remix-run/router"; import type { AppLoadContext, AppData } from "./data"; import type { LinkDescriptor } from "./links"; import type { SerializeFrom } from "./serialize"; type RouteData = RouterState["loaderData"]; export interface RouteModules<RouteModule> { [routeId: string]: RouteModule; } /** * The arguments passed to ActionFunction and LoaderFunction. * * Note this is almost identical to React Router's version but over there the * context is optional since it's only there during static handler invocations. * Keeping Remix's own definition for now so it can differentiate between * client/server */ export interface DataFunctionArgs { request: Request; context: AppLoadContext; params: Params; } export type LoaderArgs = DataFunctionArgs; export type ActionArgs = DataFunctionArgs; /** * A function that handles data mutations for a route. */ export interface ActionFunction { (args: DataFunctionArgs): Promise<Response> | Response | Promise<AppData> | AppData; } /** * A React component that is rendered when the server throws a Response. * * @deprecated Please enable the v2_errorBoundary flag to eliminate the need * for this type. If you are still using this, please use `@remix-run/react`'s * `CatchBoundaryComponent` type */ export type CatchBoundaryComponent = any; /** * A React component that is rendered when there is an error on a route. * * @deprecated Please enable the v2_errorBoundary flag to eliminate the need * for this type. If you are still using this, please use `@remix-run/react`'s * `ErrorBoundaryComponent` type */ export type ErrorBoundaryComponent = any; /** * V2 version of the ErrorBoundary that eliminates the distinction between * Error and Catch Boundaries and behaves like RR 6.4 errorElement and captures * errors with useRouteError() * * @deprecated Please enable the v2_errorBoundary flag to eliminate the need * for this type. If you are still using this, please use `@remix-run/react`'s * `V2_ErrorBoundaryComponent` type */ export type V2_ErrorBoundaryComponent = any; export type HeadersArgs = { loaderHeaders: Headers; parentHeaders: Headers; actionHeaders: Headers; errorHeaders: Headers | undefined; }; /** * A function that returns HTTP headers to be used for a route. These headers * will be merged with (and take precedence over) headers from parent routes. */ export interface HeadersFunction { (args: HeadersArgs): Headers | HeadersInit; } /** * A function that defines `<link>` tags to be inserted into the `<head>` of * the document on route transitions. */ export interface LinksFunction { (): LinkDescriptor[]; } /** * A function that loads data for a route. */ export interface LoaderFunction { (args: DataFunctionArgs): Promise<Response> | Response | Promise<AppData> | AppData; } /** * A function that returns an object of name + content pairs to use for * `<meta>` tags for a route. These tags will be merged with (and take * precedence over) tags from parent routes. * * @param Loader - Loader for this meta function's route * @param ParentsLoaders - Mapping from a parent's route filepath to that route's loader * * Note that parent route filepaths are relative to the `app/` directory. * * For example, if this meta function is for `/sales/customers/$customerId`: * * ```ts * // app/root.tsx * const loader = () => { * return json({ hello: "world" } as const) * } * export type Loader = typeof loader * * // app/routes/sales.tsx * const loader = () => { * return json({ salesCount: 1074 }) * } * export type Loader = typeof loader * * // app/routes/sales/customers.tsx * const loader = () => { * return json({ customerCount: 74 }) * } * export type Loader = typeof loader * * // app/routes/sales/customers/$customersId.tsx * import type { Loader as RootLoader } from "../../../root" * import type { Loader as SalesLoader } from "../../sales" * import type { Loader as CustomersLoader } from "../../sales/customers" * * const loader = () => { * return json({ name: "Customer name" }) * } * * const meta: MetaFunction<typeof loader, { * "root": RootLoader, * "routes/sales": SalesLoader, * "routes/sales/customers": CustomersLoader, * }> = ({ data, parentsData }) => { * const { name } = data * // ^? string * const { customerCount } = parentsData["routes/sales/customers"] * // ^? number * const { salesCount } = parentsData["routes/sales"] * // ^? number * const { hello } = parentsData["root"] * // ^? "world" * } * ``` */ export interface V1_MetaFunction<Loader extends LoaderFunction | unknown = unknown, ParentsLoaders extends Record<string, LoaderFunction> = {}> { (args: { data: Loader extends LoaderFunction ? SerializeFrom<Loader> : AppData; parentsData: { [k in keyof ParentsLoaders]: SerializeFrom<ParentsLoaders[k]>; } & RouteData; params: Params; location: Location; }): HtmlMetaDescriptor; } export type MetaFunction<Loader extends LoaderFunction | unknown = unknown, ParentsLoaders extends Record<string, LoaderFunction> = {}> = V1_MetaFunction<Loader, ParentsLoaders>; interface V2_ServerRuntimeMetaMatch<RouteId extends string = string, Loader extends LoaderFunction | unknown = unknown> { id: RouteId; pathname: AgnosticRouteMatch["pathname"]; data: Loader extends LoaderFunction ? SerializeFrom<Loader> : unknown; handle?: unknown; params: AgnosticRouteMatch["params"]; meta: V2_ServerRuntimeMetaDescriptor[]; } type V2_ServerRuntimeMetaMatches<MatchLoaders extends Record<string, unknown> = Record<string, unknown>> = Array<{ [K in keyof MatchLoaders]: V2_ServerRuntimeMetaMatch<Exclude<K, number | symbol>, MatchLoaders[K]>; }[keyof MatchLoaders]>; export interface V2_ServerRuntimeMetaArgs<Loader extends LoaderFunction | unknown = unknown, MatchLoaders extends Record<string, unknown> = Record<string, unknown>> { data: (Loader extends LoaderFunction ? SerializeFrom<Loader> : AppData) | undefined; params: Params; location: Location; matches: V2_ServerRuntimeMetaMatches<MatchLoaders>; } export interface V2_ServerRuntimeMetaFunction<Loader extends LoaderFunction | unknown = unknown, ParentsLoaders extends Record<string, LoaderFunction> = {}> { (args: V2_ServerRuntimeMetaArgs<Loader, ParentsLoaders>): V2_ServerRuntimeMetaDescriptor[]; } /** * A name/content pair used to render `<meta>` tags in a meta function for a * route. The value can be either a string, which will render a single `<meta>` * tag, or an array of strings that will render multiple tags with the same * `name` attribute. */ export interface V1_HtmlMetaDescriptor { charset?: "utf-8"; charSet?: "utf-8"; title?: string; [name: string]: null | string | undefined | Record<string, string> | Array<Record<string, string> | string>; } export type HtmlMetaDescriptor = V1_HtmlMetaDescriptor; export type MetaDescriptor = HtmlMetaDescriptor; export type V2_ServerRuntimeMetaDescriptor = { 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; } | { [name: string]: unknown; }; type LdJsonObject = { [Key in string]: LdJsonValue; } & { [Key in string]?: LdJsonValue | undefined; }; type LdJsonArray = LdJsonValue[] | readonly LdJsonValue[]; type LdJsonPrimitive = string | number | boolean | null; type LdJsonValue = LdJsonPrimitive | LdJsonObject | LdJsonArray; /** * A React component that is rendered for a route. * * @deprecated Please use `@remix-run/react`'s `RouteComponent` type instead */ export type RouteComponent = any; /** * An arbitrary object that is associated with a route. */ export type RouteHandle = any; export interface EntryRouteModule { CatchBoundary?: CatchBoundaryComponent; ErrorBoundary?: ErrorBoundaryComponent | V2_ErrorBoundaryComponent; default: RouteComponent; handle?: RouteHandle; links?: LinksFunction; meta?: MetaFunction | HtmlMetaDescriptor; } export interface ServerRouteModule extends EntryRouteModule { action?: ActionFunction; headers?: HeadersFunction | { [name: string]: string; }; loader?: LoaderFunction; } export {};