The ReactApolloVisitor class is the core engine that generates React Apollo-specific TypeScript code. It extends the base ClientSideBaseVisitor and provides specialized methods for creating React hooks, components, HOCs, and type definitions from GraphQL operations.
class ReactApolloVisitor extends ClientSideBaseVisitor<ReactApolloRawPluginConfig, ReactApolloPluginConfig> {
constructor(
schema: GraphQLSchema,
fragments: LoadedFragment[],
rawConfig: ReactApolloRawPluginConfig,
documents: Types.DocumentFile[],
);
getImports(): string[];
buildOperation(
node: OperationDefinitionNode,
documentVariableName: string,
operationType: string,
operationResultType: string,
operationVariablesTypes: string,
hasRequiredVariables: boolean,
): string;
get fragments(): string;
}Creates a new visitor instance with processed configuration and schema information.
GraphQLSchema - The GraphQL schema to generate code fromLoadedFragment[] - Array of GraphQL fragments available for operationsReactApolloRawPluginConfig - Raw plugin configurationTypes.DocumentFile[] - GraphQL document files containing operationsThe constructor processes raw configuration into typed configuration with defaults:
// Example of internal configuration processing
{
withHooks: getConfigValue(rawConfig.withHooks, true),
withComponent: getConfigValue(rawConfig.withComponent, false),
withHOC: getConfigValue(rawConfig.withHOC, false),
reactApolloVersion: getConfigValue(rawConfig.reactApolloVersion, 3),
componentSuffix: getConfigValue(rawConfig.componentSuffix, 'Component'),
// ... other options with defaults
}Returns an array of import statements required for the generated code.
getImports(): string[];Returns: Array of import statements based on configuration and generated code needs.
For Apollo Client v3 with hooks:
[
"import * as React from 'react';",
"import * as Apollo from '@apollo/client';",
"const defaultOptions = {} as const;"
]For Apollo Client v2 with components and HOCs:
[
"import * as React from 'react';",
"import * as ApolloReactCommon from '@apollo/react-common';",
"import * as ApolloReactComponents from '@apollo/react-components';",
"import * as ApolloReactHoc from '@apollo/react-hoc';",
"import * as ApolloReactHooks from '@apollo/react-hooks';"
]Generates React Apollo code for a specific GraphQL operation based on configuration.
buildOperation(
node: OperationDefinitionNode,
documentVariableName: string,
operationType: string,
operationResultType: string,
operationVariablesTypes: string,
hasRequiredVariables: boolean,
): string;OperationDefinitionNode - GraphQL operation AST nodestring - Name of the document variablestring - Type of operation ("Query", "Mutation", "Subscription")string - TypeScript type for operation resultstring - TypeScript type for operation variablesboolean - Whether operation has required variablesThe method generates different code patterns based on configuration:
// Query hooks
export function useGetUserQuery(baseOptions?: Apollo.QueryHookOptions<GetUserQuery, GetUserQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<GetUserQuery, GetUserQueryVariables>(GetUserDocument, options);
}
// Lazy query hooks
export function useGetUserLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetUserQuery, GetUserQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<GetUserQuery, GetUserQueryVariables>(GetUserDocument, options);
}
// Suspense query hooks (Apollo Client 3.7+)
export function useGetUserSuspenseQuery(baseOptions?: Apollo.SkipToken | Apollo.SuspenseQueryHookOptions<GetUserQuery, GetUserQueryVariables>) {
const options = baseOptions === Apollo.skipToken ? baseOptions : {...defaultOptions, ...baseOptions}
return Apollo.useSuspenseQuery<GetUserQuery, GetUserQueryVariables>(GetUserDocument, options);
}
// Hook result types
export type GetUserQueryHookResult = ReturnType<typeof useGetUserQuery>;
export type GetUserLazyQueryHookResult = ReturnType<typeof useGetUserLazyQuery>;// Component props type
export type GetUserComponentProps = Omit<ApolloReactComponents.QueryComponentOptions<GetUserQuery, GetUserQueryVariables>, 'query'>;
// Component
export const GetUserComponent = (props: GetUserComponentProps) => (
<ApolloReactComponents.Query<GetUserQuery, GetUserQueryVariables> query={GetUserDocument} {...props} />
);// Props type for HOC
export type GetUserProps<TChildProps = {}, TDataName extends string = 'data'> = {
[key in TDataName]: ApolloReactHoc.DataValue<GetUserQuery, GetUserQueryVariables>
} & TChildProps;
// HOC function
export function withGetUser<TProps, TChildProps = {}, TDataName extends string = 'data'>(
operationOptions?: ApolloReactHoc.OperationOption<TProps, GetUserQuery, GetUserQueryVariables, GetUserProps<TChildProps, TDataName>>
) {
return ApolloReactHoc.withQuery<TProps, GetUserQuery, GetUserQueryVariables, GetUserProps<TChildProps, TDataName>>(
GetUserDocument,
{ alias: 'getUserQuery', ...operationOptions }
);
}// Mutation function type (withMutationFn: true)
export type CreateUserMutationFn = Apollo.MutationFunction<CreateUserMutation, CreateUserMutationVariables>;
// Result types (withResultType: true)
export type GetUserQueryResult = Apollo.QueryResult<GetUserQuery, GetUserQueryVariables>;
export type CreateUserMutationResult = Apollo.MutationResult<CreateUserMutation>;
// Mutation options type (withMutationOptionsType: true)
export type CreateUserMutationOptions = Apollo.BaseMutationOptions<CreateUserMutation, CreateUserMutationVariables>;
// Refetch function (withRefetchFn: true)
export function refetchGetUserQuery(variables?: GetUserQueryVariables) {
return { query: GetUserDocument, variables: variables }
}Returns generated fragment-related code, including fragment hooks when enabled.
get fragments(): string;When fragment hooks are enabled, generates useFragment wrappers:
// Generated fragment hook
export function useUserFieldsFragment<F = { id: string }>(identifiers: F) {
return Apollo.useFragment<UserFieldsFragment>({
fragment: UserFieldsFragmentDoc,
fragmentName: "UserFields",
from: {
__typename: "User",
...identifiers,
},
});
}
// Fragment hook result type
export type UserFieldsFragmentHookResult = ReturnType<typeof useUserFieldsFragment>;The visitor is typically used internally by the plugin function:
// Internal plugin usage
const visitor = new ReactApolloVisitor(schema, allFragments, config, documents);
const visitorResult = oldVisit(allAst, { leave: visitor });
const output = {
prepend: visitor.getImports(),
content: [
visitor.fragments,
...visitorResult.definitions.filter(t => typeof t === 'string'),
].join('\n'),
};The visitor respects all configuration options:
The visitor ensures complete type safety by: