import { ScalarsMap , ParsedScalarsMap , NamingConvention , ConvertFn , ConvertOptions , LoadedFragment , NormalizedScalarsMap , DeclarationKind , } from './types' ; import { DeclarationBlockConfig } from './utils' ; import autoBind from 'auto-bind' ; import { convertFactory } from './naming' ; import { ASTNode , FragmentDefinitionNode , OperationDefinitionNode } from 'graphql' ; import { ImportDeclaration , FragmentImport } from './imports' ; export interface BaseVisitorConvertOptions { useTypesPrefix ? : boolean ; useTypesSuffix ? : boolean ; } export type InlineFragmentTypeOptions = 'inline' | 'combine' ; export interface ParsedConfig { scalars : ParsedScalarsMap ; convert : ConvertFn ; typesPrefix : string ; typesSuffix : string ; addTypename : boolean ; nonOptionalTypename : boolean ; externalFragments : LoadedFragment [ ] ; fragmentImports : ImportDeclaration < FragmentImport > [ ] ; immutableTypes : boolean ; useTypeImports : boolean ; dedupeFragments : boolean ; allowEnumStringTypes : boolean ; inlineFragmentTypes : InlineFragmentTypeOptions ; } export interface RawConfig { description default exampleMarkdown strictScalars ? : boolean ; description default exampleMarkdown defaultScalarType ? : string ; description exampleMarkdown scalars ? : ScalarsMap ; default description exampleMarkdown namingConvention ? : NamingConvention ; default description exampleMarkdown typesPrefix ? : string ; default description exampleMarkdown typesSuffix ? : string ; default description exampleMarkdown skipTypename ? : boolean ; default description exampleMarkdown nonOptionalTypename ? : boolean ; name type boolean default description example useTypeImports ? : boolean ; ignore externalFragments ? : LoadedFragment [ ] ; ignore fragmentImports ? : ImportDeclaration < FragmentImport > [ ] ; ignore globalNamespace ? : boolean ; description type boolean default dedupeFragments ? : boolean ; ignore allowEnumStringTypes ? : boolean ; description type string default inlineFragmentTypes ? : InlineFragmentTypeOptions ; } export class BaseVisitor < TRawConfig extends RawConfig = RawConfig , TPluginConfig extends ParsedConfig = ParsedConfig > { protected _parsedConfig : TPluginConfig ; protected _declarationBlockConfig : DeclarationBlockConfig = { } ; public readonly scalars : NormalizedScalarsMap ; constructor ( rawConfig , additionalConfig ) { this . _parsedConfig = { convert : convertFactory ( rawConfig ) , typesPrefix : rawConfig . typesPrefix || '' , typesSuffix : rawConfig . typesSuffix || '' , externalFragments : rawConfig . externalFragments || [ ] , fragmentImports : rawConfig . fragmentImports || [ ] , addTypename : ! rawConfig . skipTypename , nonOptionalTypename : ! ! rawConfig . nonOptionalTypename , useTypeImports : ! ! rawConfig . useTypeImports , dedupeFragments : ! ! rawConfig . dedupeFragments , allowEnumStringTypes : ! ! rawConfig . allowEnumStringTypes , inlineFragmentTypes : rawConfig . inlineFragmentTypes ?? 'inline' , ... ( ( additionalConfig || { } ) as any ) , } ; this . scalars = { } ; Object . keys ( this . config . scalars || { } ) . forEach ( key => { this . scalars [ key ] = this . config . scalars [ key ] . type ; } ) ; autoBind ( this ) ; } protected getVisitorKindContextFromAncestors ( ancestors ) { if ( ! ancestors ) { return [ ] ; } return ancestors . map ( t => t . kind ) . filter ( Boolean ) ; } get config ( ) : TPluginConfig { return this . _parsedConfig ; } public convertName ( node , options ? ) { const useTypesPrefix = typeof ( options && options . useTypesPrefix ) === 'boolean' ? options . useTypesPrefix : true ; const useTypesSuffix = typeof ( options && options . useTypesSuffix ) === 'boolean' ? options . useTypesSuffix : true ; let convertedName = '' ; if ( useTypesPrefix ) { convertedName += this . config . typesPrefix ; } convertedName += this . config . convert ( node , options ) ; if ( useTypesSuffix ) { convertedName += this . config . typesSuffix ; } return convertedName ; } public getOperationSuffix ( node , operationType ) { const { omitOperationSuffix = false , dedupeOperationSuffix = false } = this . config as { [ key ] : any ; } ; const operationName = typeof node === 'string' ? node : node . name ? node . name . value : '' ; return omitOperationSuffix ? '' : dedupeOperationSuffix && operationName . toLowerCase ( ) . endsWith ( operationType . toLowerCase ( ) ) ? '' : operationType ; } public getFragmentSuffix ( node ) { return this . getOperationSuffix ( node , 'Fragment' ) ; } public getFragmentName ( node ) { return this . convertName ( node , { suffix : this . getFragmentSuffix ( node ) , useTypesPrefix : false , } ) ; } public getFragmentVariableName ( node ) { const { omitOperationSuffix = false , dedupeOperationSuffix = false , fragmentVariableSuffix = 'FragmentDoc' , fragmentVariablePrefix = '' , } = this . config as { [ key ] : any ; } ; const fragmentName = typeof node === 'string' ? node : node . name . value ; const suffix = omitOperationSuffix ? '' : dedupeOperationSuffix && fragmentName . toLowerCase ( ) . endsWith ( 'fragment' ) && fragmentVariableSuffix . toLowerCase ( ) . startsWith ( 'fragment' ) ? fragmentVariableSuffix . substring ( 'fragment' . length ) : fragmentVariableSuffix ; return this . convertName ( node , { prefix : fragmentVariablePrefix , suffix , useTypesPrefix : false , } ) ; } protected getPunctuation ( _declarationKind ) { return '' ; } }