import { TypeScriptResolversPluginConfig } from './config' ; import { FieldDefinitionNode , ListTypeNode , NamedTypeNode , NonNullTypeNode , GraphQLSchema , EnumTypeDefinitionNode , } from 'graphql' ; import autoBind from 'auto-bind' ; import { ParsedResolversConfig , BaseResolversVisitor , getConfigValue , DeclarationKind , } from '@graphql-codegen/visitor-plugin-common' ; import { TypeScriptOperationVariablesToObject } from '@graphql-codegen/typescript' ; export const ENUM_RESOLVERS_SIGNATURE = 'export type EnumResolverSignature<T, AllowedValues = any> = { [key in keyof T]?: AllowedValues };' ; export interface ParsedTypeScriptResolversConfig extends ParsedResolversConfig { useIndexSignature : boolean ; wrapFieldDefinitions : boolean ; allowParentTypeOverride : boolean ; optionalInfoArgument : boolean ; } export class TypeScriptResolversVisitor extends BaseResolversVisitor < TypeScriptResolversPluginConfig , ParsedTypeScriptResolversConfig > { constructor ( pluginConfig , schema ) { super ( pluginConfig , { avoidOptionals : getConfigValue ( pluginConfig . avoidOptionals , false ) , useIndexSignature : getConfigValue ( pluginConfig . useIndexSignature , false ) , wrapFieldDefinitions : getConfigValue ( pluginConfig . wrapFieldDefinitions , false ) , allowParentTypeOverride : getConfigValue ( pluginConfig . allowParentTypeOverride , false ) , optionalInfoArgument : getConfigValue ( pluginConfig . optionalInfoArgument , false ) , } as ParsedTypeScriptResolversConfig , schema ) ; autoBind ( this ) ; this . setVariablesTransformer ( new TypeScriptOperationVariablesToObject ( this . scalars , this . convertName , this . config . avoidOptionals , this . config . immutableTypes , this . config . namespacedImportName , [ ] , this . config . enumPrefix , this . config . enumValues ) ) ; if ( this . config . useIndexSignature ) { this . _declarationBlockConfig = { blockTransformer ( block ) { return `ResolversObject<${ block }>` ; } , } ; } } protected transformParentGenericType ( parentType ) { if ( this . config . allowParentTypeOverride ) { return `ParentType = ${ parentType }` ; } return `ParentType extends ${ parentType } = ${ parentType }` ; } protected formatRootResolver ( schemaTypeName , resolverType , declarationKind ) { return `${ schemaTypeName }${ this . config . avoidOptionals ? '' : '?' }: ${ resolverType }${ this . getPunctuation ( declarationKind ) }` ; } private clearOptional ( str ) { if ( str . startsWith ( 'Maybe' ) ) { return str . replace ( /Maybe<(.*?)>$/ , '$1' ) ; } return str ; } ListType ( node ) { return `Maybe<${ super . ListType ( node ) }>` ; } protected wrapWithListType ( str ) { return `${ this . config . immutableTypes ? 'ReadonlyArray' : 'Array' }<${ str }>` ; } protected getParentTypeForSignature ( node ) { if ( this . _federation . isResolveReferenceField ( node ) && this . config . wrapFieldDefinitions ) { return 'UnwrappedObject<ParentType>' ; } return 'ParentType' ; } NamedType ( node ) { return `Maybe<${ super . NamedType ( node ) }>` ; } NonNullType ( node ) { const baseValue = super . NonNullType ( node ) ; return this . clearOptional ( baseValue ) ; } protected getPunctuation ( _declarationKind ) { return ';' ; } protected buildEnumResolverContentBlock ( node , mappedEnumType ) { const valuesMap = `{ ${ ( node . values || [ ] ) . map ( v => `${ v . name as any as string }${ this . config . avoidOptionals ? '' : '?' }: any` ) . join ( ', ' ) } }` ; this . _globalDeclarations . add ( ENUM_RESOLVERS_SIGNATURE ) ; return `EnumResolverSignature<${ valuesMap }, ${ mappedEnumType }>` ; } protected buildEnumResolversExplicitMappedValues ( node , valuesMapping ) { return `{ ${ ( node . values || [ ] ) . map ( v => { const valueName = v . name as any as string ; const mappedValue = valuesMapping [ valueName ] ; return `${ valueName }: ${ typeof mappedValue === 'number' ? mappedValue : `'${ mappedValue }'` }` ; } ) . join ( ', ' ) } }` ; } }