/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import * as React from 'react'; import { _FragmentRefs, _RefType, CacheConfig, ConcreteRequest, Disposable, DisposeFn, Environment, FetchPolicy, FragmentType, GraphQLResponse, IEnvironment, Observable, Observer, OperationType, PreloadableConcreteRequest, RenderPolicy, Variables, VariablesOf, } from 'relay-runtime'; export { FragmentRef } from 'relay-runtime'; export { VariablesOf } from 'relay-runtime'; // --- Legacy container types --- export interface RelayProp { environment: Environment; refetch: undefined; // ensures no RelayRefetchProp is used with a fragment container hasMore: undefined; // ensures no RelayPaginationProp is used with a fragment container } export interface RelayRefetchProp { environment: Environment; refetch: ( refetchVariables: Variables | ((fragmentVariables: Variables) => Variables), renderVariables?: Variables | null, observerOrCallback?: ObserverOrCallback | null, options?: RefetchOptions, ) => Disposable; hasMore: undefined; // ensures no RelayPaginationProp is used with a refetch container } export interface RefetchOptions { force?: boolean | undefined; fetchPolicy?: 'store-or-network' | 'network-only' | undefined; } type ObserverOrCallback = Observer | ((error: Error | null | undefined) => void); export interface RelayPaginationProp { readonly environment: Environment; readonly hasMore: () => boolean; readonly isLoading: () => boolean; readonly loadMore: ( pageSize: number, observerOrCallback?: ObserverOrCallback | null, options?: RefetchOptions | null, ) => Disposable | null | undefined; readonly refetchConnection: ( totalCount: number, observerOrCallback?: ObserverOrCallback | null, refetchVariables?: Variables | null, ) => Disposable | null | undefined; refetch: undefined; // ensures no RelayRefetchProp is used with a pagination container } export type FragmentOrRegularProp = T extends _RefType ? _FragmentRefs : T extends ReadonlyArray<_RefType> ? ReadonlyArray<_FragmentRefs> : T; export type MappedFragmentProps = { [K in keyof T]: FragmentOrRegularProp; }; // --- Fragment key types (from helpers) --- export type KeyType = Readonly<{ ' $data'?: TData | undefined; ' $fragmentSpreads': FragmentType; }>; export type KeyTypeData, TData = unknown> = Required[' $data']; export type ArrayKeyType = ReadonlyArray | null | undefined>; export type ArrayKeyTypeData, TData = unknown> = KeyTypeData< NonNullable >; export type GetEntryPointParamsFromEntryPoint = TEntryPoint extends EntryPoint< infer _TEntryPointComponent, infer TEntryPointParams > ? TEntryPointParams : never; export type GetEntryPointComponentFromEntryPoint = TEntryPoint extends EntryPoint< infer TEntryPointComponent, infer _TEntryPointParams > ? TEntryPointComponent : never; // --- EntryPoint types --- 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 type PreloadedQuery< TQuery extends OperationType, TEnvironmentProviderOptions = EnvironmentProviderOptions, > = 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` */ type InternalEntryPointRepresentation< TEntryPointParams extends Record, TPreloadedQueries extends Record, TNestedEntryPoints extends Record, TRuntimeProps extends Record, TExtraProps extends Record | null, > = Readonly<{ root: JSResourceReference< EntryPointComponent >; getPreloadProps: ( entryPointParams: TEntryPointParams, ) => PreloadProps; }>; type ThinQueryParamsObject = Record> = { [K in keyof TPreloadedQueries]: ThinQueryParams; }; type ThinNestedEntryPointParamsObject< TEntryPoints extends Record | undefined> = Record, > = { [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; export type PreloadProps< _TPreloadParams extends Record, TPreloadedQueries extends Record, TNestedEntryPoints extends Record | undefined>, TExtraProps extends Record | null, > = Readonly<{ entryPoints?: ThinNestedEntryPointParamsObject | undefined; extraProps?: TExtraProps | undefined; queries?: ThinQueryParamsObject | undefined; }>; export type EntryPointProps = Readonly<{ entryPoints: PreloadedEntryPoints; extraProps: TExtraProps; props: TRuntimeProps; queries: PreloadedQueries; }>; export type EntryPointComponent< TPreloadedQueries extends Record, TNestedEntryPoints extends Record | undefined>, TRuntimeProps extends Record = Record, TExtraProps extends Record | null = Record, > = React.ComponentType>; 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 type ThinQueryParams< TQuery extends OperationType, TEnvironmentProviderOptions extends EnvironmentProviderOptions = EnvironmentProviderOptions, > = Readonly<{ parameters: ConcreteRequest | PreloadableConcreteRequest; variables: VariablesOf; options?: PreloadOptions | null | undefined; environmentProviderOptions?: TEnvironmentProviderOptions | null | undefined; }>; export type ThinNestedEntryPointParams = Readonly<{ entryPoint: TEntryPoint; entryPointParams: GetEntryPointParamsFromEntryPoint; }>; export type EntryPoint = Record> = InternalEntryPointRepresentation< TEntryPointParams, TEntryPointComponent extends EntryPointComponent ? TPreloadedQueries : never, TEntryPointComponent extends EntryPointComponent ? TNestedEntryPoints : never, TEntryPointComponent extends EntryPointComponent ? TRuntimeProps : never, TEntryPointComponent extends EntryPointComponent ? TExtraProps : never >; export interface IEnvironmentProvider { getEnvironment(options: TOptions | null): IEnvironment; } // --- Refetchable fragment types (from useRefetchableFragmentNode) --- export type RefetchFn = RefetchFnExact; export type RefetchFnDynamic< TQuery extends OperationType, _TKey extends KeyType | null | undefined, TOptions = RefetchableOptions, > = RefetchInexactDynamicResponse & RefetchExactDynamicResponse; export type RefetchInexact = ( data?: unknown, ) => RefetchFnInexact; export type RefetchInexactDynamicResponse = ReturnType< RefetchInexact >; export type RefetchExact = ( data?: unknown | null, ) => RefetchFnExact; export type RefetchExactDynamicResponse = ReturnType< RefetchExact >; export type RefetchFnBase = (vars: TVars, options?: TOptions) => Disposable; export type RefetchFnExact = RefetchFnBase< VariablesOf, TOptions >; export type RefetchFnInexact = RefetchFnBase< Partial>, TOptions >; export interface ReturnTypeNode< TQuery extends OperationType, TKey extends KeyType | null | undefined, TOptions = RefetchableOptions, > { fragmentData: unknown; fragmentRef: unknown; refetch: RefetchFnDynamic; disableStoreUpdates: () => void; enableStoreUpdates: () => void; } export interface RefetchableOptions { fetchPolicy?: FetchPolicy | undefined; onComplete?: ((arg: Error | null) => void) | undefined; UNSTABLE_renderPolicy?: RenderPolicy | undefined; } export interface InternalRefetchableOptions extends RefetchableOptions { __environment?: IEnvironment | undefined; } export type RefetchableAction = | { type: 'reset'; environment: IEnvironment; fragmentIdentifier: string; } | { type: 'refetch'; refetchVariables: Variables; fetchPolicy?: FetchPolicy | undefined; renderPolicy?: RenderPolicy | undefined; onComplete?: ((args: Error | null) => void) | undefined; environment?: IEnvironment | null | undefined; }; export interface RefetchState { fetchPolicy?: FetchPolicy | undefined; renderPolicy?: RenderPolicy | undefined; mirroredEnvironment: IEnvironment; mirroredFragmentIdentifier: string; onComplete?: ((arg: Error | null) => void) | undefined; refetchEnvironment?: IEnvironment | null | undefined; refetchVariables?: Variables | null | undefined; refetchGeneration: number; } export interface DebugIDandTypename { id: string; typename: string; }