import type { ComponentProps, JSXElementConstructor } from 'react'; import type { ApolloClient, NetworkStatus, OperationVariables, QueryRef, UseBackgroundQueryResult } from '@apollo/client'; import type { DocumentNode } from 'graphql'; import type { A, L, O, U } from 'ts-toolbelt'; /** * * If the Cell has a `beforeQuery` function, then the variables are not required, * but instead the arguments of the `beforeQuery` function are required. * * If the Cell does not have a `beforeQuery` function, then the variables are required. * * Note that a query that doesn't take any variables is defined as {[x: string]: never} * The ternary at the end makes sure we don't include it, otherwise it won't allow merging any * other custom props from the Success component. * */ type CellPropsVariables = Cell extends { beforeQuery: (...args: any[]) => any; } ? Parameters[0] extends unknown ? Record : Parameters[0] : GQLVariables extends Record ? unknown : GQLVariables; /** * Cell component props which is the combination of query variables and Success props. */ export type CellProps, GQLResult, CellType, GQLVariables> = A.Compute, keyof CellPropsVariables | keyof GQLResult | 'updating' | 'queryResult'> & CellPropsVariables>; type InputVarProps = T extends { [key: string]: never; } ? unknown : T; export type CellLoadingProps = { queryResult?: NonSuspenseCellQueryResult | SuspenseCellQueryResult; } & InputVarProps; export type CellFailureProps = { queryResult?: NonSuspenseCellQueryResult | SuspenseCellQueryResult; error?: QueryOperationResult['error'] | Error; /** * @see {@link https://www.apollographql.com/docs/apollo-server/data/errors/#error-codes} */ errorCode?: string; updating?: boolean; } & InputVarProps; type Guaranteed = { [K in keyof T]-?: NonNullable; }; type KeyCount = L.Length>>; type ConditionallyGuaranteed = KeyCount extends 1 ? Guaranteed : T; /** * @params TData = Type of data based on your graphql query. This can be imported from 'types/graphql' * @example * import type { FindPosts } from 'types/graphql' * * const { post }: CellSuccessData = props */ export type CellSuccessData = ConditionallyGuaranteed>; /** * @MARK not sure about this partial, but we need to do this for tests and storybook. * * `updating` is just `loading` renamed; since Cells default to stale-while-refetch, * this prop lets users render something like a spinner to show that a request is in-flight. */ export type CellSuccessProps = { queryResult?: NonSuspenseCellQueryResult | SuspenseCellQueryResult; updating?: boolean; } & InputVarProps & A.Compute>; /** * A coarse type for the `data` prop returned by `useQuery`. * * ```js * { * data: { * post: { ... } * } * } * ``` */ export type DataObject = { [key: string]: unknown; }; /** * The main interface. */ export interface CreateCellProps { /** * The GraphQL syntax tree to execute or function to call that returns it. * If `QUERY` is a function, it's called with the result of `beforeQuery`. */ QUERY: DocumentNode | ((variables: Record) => DocumentNode); /** * Parse `props` into query variables. Most of the time `props` are appropriate variables as is. */ beforeQuery?: ((props: CellProps) => { variables: CellVariables; }) | (() => { variables: CellVariables; }); /** * Sanitize the data returned from the query. */ afterQuery?: (data: DataObject) => DataObject; /** * How to decide if the result of a query should render the `Empty` component. * The default implementation checks that the first field isn't `null` or an empty array. * * @example * * In the example below, only `users` is checked: * * ```js * export const QUERY = gql` * users { * name * } * posts { * title * } * ` * ``` */ isEmpty?: (response: DataObject, options: { isDataEmpty: (data: DataObject) => boolean; }) => boolean; /** * If the query's in flight and there's no stale data, render this. */ Loading?: React.FC>; /** * If something went wrong, render this. */ Failure?: React.FC>; /** * If no data was returned, render this. */ Empty?: React.FC>; /** * If data was returned, render this. */ Success: React.FC>; /** * What to call the Cell. Defaults to the filename. */ displayName?: string; } export type SuspendingSuccessProps = React.PropsWithChildren> & { queryRef: QueryRef; suspenseQueryResult: SuspenseCellQueryResult; userProps: Record; }; export type NonSuspenseCellQueryResult = Partial, 'loading' | 'error' | 'data'>>; export interface SuspenseCellQueryResult<_TData = any, _TVariables extends OperationVariables = any> extends UseBackgroundQueryResult { client: ApolloClient; networkStatus?: NetworkStatus; called: boolean; } export {}; //# sourceMappingURL=cellTypes.d.ts.map