import { Kind , TypeNode , VariableNode , NameNode , ValueNode , DirectiveNode } from 'graphql' ; import { indent , getBaseTypeNode } from './utils' ; import { NormalizedScalarsMap , ConvertNameFn , ParsedEnumValuesMap , ParsedDirectiveArgumentAndInputFieldMappings , } from './types' ; import { BaseVisitorConvertOptions } from './base-visitor' ; import autoBind from 'auto-bind' ; export interface InterfaceOrVariable { name ? : NameNode ; variable ? : VariableNode ; type : TypeNode ; defaultValue ? : ValueNode ; directives ? : ReadonlyArray < DirectiveNode > ; } export class OperationVariablesToObject { constructor ( protected _scalars , protected _convertName , protected _namespacedImportName = null , protected _enumNames = [ ] , protected _enumPrefix = true , protected _enumValues = { } , protected _applyCoercion = false , protected _directiveArgumentAndInputFieldMappings = { } ) { autoBind ( this ) ; } getName < TDefinitionType extends InterfaceOrVariable > ( node ) { if ( node . name ) { if ( typeof node . name === 'string' ) { return node . name ; } return node . name . value ; } else if ( node . variable ) { return node . variable . name . value ; } return null ; } transform < TDefinitionType extends InterfaceOrVariable > ( variablesNode ) { if ( ! variablesNode || variablesNode . length === 0 ) { return null ; } return ( variablesNode . map ( variable => indent ( this . transformVariable ( variable ) ) ) . join ( `${ this . getPunctuation ( ) }\n` ) + this . getPunctuation ( ) ) ; } protected getScalar ( name ) { const prefix = this . _namespacedImportName ? `${ this . _namespacedImportName }.` : '' ; return `${ prefix }Scalars['${ name }']` ; } protected getDirectiveMapping ( name ) { return `DirectiveArgumentAndInputFieldMappings['${ name }']` ; } protected getDirectiveOverrideType ( directives ) { if ( ! this . _directiveArgumentAndInputFieldMappings ) return null ; const type = directives . map ( directive => { const directiveName = directive . name . value ; if ( this . _directiveArgumentAndInputFieldMappings [ directiveName ] ) { return this . getDirectiveMapping ( directiveName ) ; } return null ; } ) . reverse ( ) . find ( a => ! ! a ) ; return type || null ; } protected transformVariable < TDefinitionType extends InterfaceOrVariable > ( variable ) { let typeValue = null ; const prefix = this . _namespacedImportName ? `${ this . _namespacedImportName }.` : '' ; if ( typeof variable . type === 'string' ) { typeValue = variable . type ; } else { const baseType = getBaseTypeNode ( variable . type ) ; const overrideType = variable . directives ? this . getDirectiveOverrideType ( variable . directives ) : null ; const typeName = baseType . name . value ; if ( overrideType ) { typeValue = overrideType ; } else if ( this . _scalars [ typeName ] ) { typeValue = this . getScalar ( typeName ) ; } else if ( this . _enumValues [ typeName ] && this . _enumValues [ typeName ] . sourceFile ) { typeValue = this . _enumValues [ typeName ] . typeIdentifier || this . _enumValues [ typeName ] . sourceIdentifier ; } else { typeValue = `${ prefix }${ this . _convertName ( baseType , { useTypesPrefix : this . _enumNames . includes ( typeName ) ? this . _enumPrefix : true , } ) }` ; } } const fieldName = this . getName ( variable ) ; const fieldType = this . wrapAstTypeWithModifiers ( typeValue , variable . type , this . _applyCoercion ) ; const hasDefaultValue = variable . defaultValue != null && typeof variable . defaultValue !== 'undefined' ; const isNonNullType = variable . type . kind === Kind . NON_NULL_TYPE ; const formattedFieldString = this . formatFieldString ( fieldName , isNonNullType , hasDefaultValue ) ; const formattedTypeString = this . formatTypeString ( fieldType , isNonNullType , hasDefaultValue ) ; return `${ formattedFieldString }: ${ formattedTypeString }` ; } public wrapAstTypeWithModifiers ( _baseType , _typeNode , _applyCoercion ? ) { throw new Error ( `You must override "wrapAstTypeWithModifiers" of OperationVariablesToObject!` ) ; } protected formatFieldString ( fieldName , isNonNullType , _hasDefaultValue ) { return fieldName ; } protected formatTypeString ( fieldType , isNonNullType , hasDefaultValue ) { const prefix = this . _namespacedImportName ? `${ this . _namespacedImportName }.` : '' ; if ( hasDefaultValue ) { return `${ prefix }Maybe<${ fieldType }>` ; } return fieldType ; } protected getPunctuation ( ) { return ',' ; } }