import { ComponentType } from "react"; import { CacheConfig, ConcreteRequest, DisposeFn, FetchPolicy, GraphQLResponse, IEnvironment, Observable, OperationType, PreloadableConcreteRequest, VariablesOf, } from "relay-runtime"; import { GetEntryPointComponentFromEntryPoint, GetEntryPointParamsFromEntryPoint } from "./helpers"; export { VariablesOf } from "relay-runtime"; export interface JSResourceReference { getModuleId(): string; getModuleIfRequired(): TModule | null; load(): Promise; } export type PreloadFetchPolicy = "store-or-network" | "store-and-network" | "network-only"; export type PreloadOptions = Readonly<{ fetchKey?: string | number | undefined; fetchPolicy?: PreloadFetchPolicy | null | undefined; networkCacheConfig?: CacheConfig | null | undefined; }>; export type LoadQueryOptions = Readonly<{ fetchPolicy?: FetchPolicy | null | undefined; networkCacheConfig?: CacheConfig | null | undefined; onQueryAstLoadTimeout?: (() => void) | null | undefined; }>; export type EnvironmentProviderOptions = Record> = T; export interface PreloadedQuery< TQuery extends OperationType, TEnvironmentProviderOptions = EnvironmentProviderOptions, > extends Readonly<{ kind: "PreloadedQuery"; environment: IEnvironment; environmentProviderOptions?: TEnvironmentProviderOptions | null | undefined; fetchKey: string | number; fetchPolicy: PreloadFetchPolicy; networkCacheConfig?: CacheConfig | null | undefined; id?: string | null | undefined; name: string; source?: Observable | null | undefined; variables: VariablesOf; dispose: DisposeFn; isDisposed: boolean; }> {} export type PreloadQueryStatus = Readonly<{ cacheConfig?: CacheConfig | null | undefined; source: "cache" | "network"; fetchTime?: number | null | undefined; }>; /** * The Interface of the EntryPoints .entrypoint files * * Every .entrypoint file it's an object that must have two required fields: * - getPreloadProps(...) function that will return the description of preloaded * queries and preloaded (nested) entry points for the current entry point * - root - JSResource of the module that will render those preloaded queries * * TEntryPointParams - object that contains all necessary information to execute * the preloaders (routeParams, query variables) * * TPreloadedQueries - queries, defined in the root components * * TNestedEntryPoints - nested entry points, defined in the root components * * TRuntimeProps - the type of additional props that you may pass to the * component (like `onClick` handler, etc) during runtime. Values for them * defined during component runtime * * TExtraProps - a bag of extra props that you may define in `entrypoint` file * and they will be passed to the EntryPointComponent as `extraProps` */ interface InternalEntryPointRepresentation< /** * object that contains all necessary information to execute the preloaders (routeParams, query variables) */ TEntryPointParams extends {}, /** * queries, defined in the root components */ TPreloadedQueries extends Record, /** * nested entry points, defined in the root components */ TNestedEntryPoints extends {}, /** * the type of additional props that you may pass to the component (like `onClick` handler, etc) during runtime. * Values for them defined during component runtime */ TRuntimeProps extends {}, /** * a bag of extra props that you may define in `entrypoint` file and they will be passed to the EntryPointComponent * as `extraProps` */ TExtraProps extends {} | null, > extends Readonly<{ root: JSResourceReference< EntryPointComponent >; getPreloadProps: ( entryPointParams: TEntryPointParams, ) => PreloadProps; }> {} type ThinQueryParamsObject = {}> = { [K in keyof TPreloadedQueries]: ThinQueryParams; }; type ThinNestedEntryPointParamsObject< TEntryPoints extends Record | undefined> = {}, > = { [K in keyof TEntryPoints]: ThinNestedEntryPointParams; }; type PreloadedQueries = TPreloadedQueries extends Record ? { [T in keyof TPreloadedQueries]: PreloadedQuery; } : never; type PreloadedEntryPoints = TEntryPoints extends Record< string, InternalEntryPointRepresentation | undefined > ? { [T in keyof TEntryPoints]: PreloadedEntryPoint< GetEntryPointComponentFromEntryPoint >; } : never; // Return type of the `getPreloadProps(...)` of the entry point export interface PreloadProps< TPreloadParams extends {}, TPreloadedQueries extends Record, TNestedEntryPoints extends Record | undefined>, TExtraProps extends {} | null, > extends Readonly<{ entryPoints?: ThinNestedEntryPointParamsObject | undefined; extraProps?: TExtraProps | undefined; queries?: ThinQueryParamsObject | undefined; }> {} // The shape of the props of the entry point `root` component export interface EntryPointProps extends Readonly<{ entryPoints: PreloadedEntryPoints; extraProps: TExtraProps; props: TRuntimeProps; queries: PreloadedQueries; }> {} // Type of the entry point `root` component export type EntryPointComponent< TPreloadedQueries extends Record, TNestedEntryPoints extends Record | undefined>, TRuntimeProps extends {} = {}, TExtraProps extends {} | null = {}, > = ComponentType>; // Return type of `loadEntryPoint(...)` export type PreloadedEntryPoint = TEntryPointComponent extends EntryPointComponent< infer TPreloadedQueries, infer TNestedEntryPoints, infer TRuntimeProps, infer TExtraProps > ? Readonly<{ dispose: DisposeFn; entryPoints: PreloadedEntryPoints; extraProps: TExtraProps; getComponent: () => TEntryPointComponent; isDisposed: boolean; queries: PreloadedQueries; rootModuleID: string; }> : never; export interface ThinQueryParams< TQuery extends OperationType, TEnvironmentProviderOptions extends EnvironmentProviderOptions = EnvironmentProviderOptions, > extends Readonly<{ /** * A reference to the $Parameters file that matches the type param provided to preloadQuery type. * * NOTE: For now, since OSS relay-compiler doesnt support generating the $Parameters file, you must give the query * wou would have given to usePreloadedQuery */ parameters: ConcreteRequest | PreloadableConcreteRequest; /** * Variables to give to the query */ variables: VariablesOf; /** * Any execution options to apply during network */ options?: PreloadOptions | null | undefined; environmentProviderOptions?: TEnvironmentProviderOptions | null | undefined; }> {} export interface ThinNestedEntryPointParams extends Readonly<{ entryPoint: TEntryPoint; entryPointParams: GetEntryPointParamsFromEntryPoint; }> {} export type EntryPoint = InternalEntryPointRepresentation< TEntryPointParams, TEntryPointComponent extends EntryPointComponent ? TPreloadedQueries : never, TEntryPointComponent extends EntryPointComponent ? TNestedEntryPoints : never, TEntryPointComponent extends EntryPointComponent ? TRuntimeProps : never, TEntryPointComponent extends EntryPointComponent ? TExtraProps : never >; // eslint-disable-next-line @typescript-eslint/naming-convention export interface IEnvironmentProvider { getEnvironment(options: TOptions | null): IEnvironment; }