import { GraphQLUnionType , GraphQLWrappingType , GraphQLObjectType , GraphQLInputObjectType , GraphQLInputField , GraphQLField , GraphQLInputType , GraphQLOutputType , GraphQLScalarType , GraphQLNamedType , isNonNullType , isListType , GraphQLFieldMap , GraphQLEnumType , GraphQLType , GraphQLInterfaceType , } from 'graphql' ; import { Generator } from '../types' ; import { generator as gcgenerator , renderFieldType , renderFieldName , renderTypeWrapper } from './graphcool-ts' ; export const generator = { ... gcgenerator , Main : renderMainMethod , RootType : renderRootType , SubscriptionType : renderSubscriptionType , Header : renderHeader , } ; function renderSubscriptionType ( type ) { const fieldDefinition = Object . keys ( type . getFields ( ) ) . map ( f => { const field = type . getFields ( ) [ f ] ; return `  ${ field . name }: (args: {${ field . args . length > 0 ? ' ' : '' }${ field . args . map ( f => `${ renderFieldName ( f ) }: ${ renderFieldType ( f . type ) }` ) . join ( ', ' ) }${ field . args . length > 0 ? ' ' : '' }}, context: { [key: string]: any }, infoOrQuery?: GraphQLResolveInfo | string) => Promise<AsyncIterator<${ renderFieldType ( field . type ) }>>` ; } ) . join ( '\n' ) ; return renderTypeWrapper ( type . name , type . description , fieldDefinition ) ; } function renderHeader ( schema ) { return `import { Binding as BaseBinding, BindingOptions } from 'graphql-binding'
import { GraphQLResolveInfo } from 'graphql'` ; } function renderMainMethod ( queryType , mutationType ? , subscriptionType ? ) { return `export class Binding extends BaseBinding {
  
  constructor({ schema, fragmentReplacements }: BindingOptions) {
    super({ schema, fragmentReplacements });
  }
  
  query: Query = {
${ renderMainMethodFields ( 'query' , queryType . getFields ( ) ) }
  }${ mutationType ? `

  mutation: Mutation = {
${ renderMainMethodFields ( 'mutation' , mutationType . getFields ( ) ) }
  }` : '' }${ subscriptionType ? `

  subscription: Subscription = {
${ renderMainSubscriptionMethodFields ( subscriptionType . getFields ( ) ) }
  }` : '' }
}` ; } function renderRootType ( type ) { const fieldDefinition = Object . keys ( type . getFields ( ) ) . map ( f => { const field = type . getFields ( ) [ f ] ; return `  ${ field . name }: (args: {${ field . args . length > 0 ? ' ' : '' }${ field . args . map ( f => `${ renderFieldName ( f ) }: ${ renderFieldType ( f . type ) }` ) . join ( ', ' ) }${ field . args . length > 0 ? ' ' : '' }}, context: { [key: string]: any }, info?: GraphQLResolveInfo | string) => Promise<${ renderFieldType ( field . type ) }${ ! isNonNullType ( field . type ) ? ' | null' : '' }>` ; } ) . join ( '\n' ) ; return renderTypeWrapper ( type . name , type . description , fieldDefinition ) ; } export function renderMainMethodFields ( operation , fields ) { return Object . keys ( fields ) . map ( f => { const field = fields [ f ] ; return `    ${ field . name }: (args, context, info): Promise<${ renderFieldType ( field . type ) }${ ! isNonNullType ( field . type ) ? ' | null' : '' }> => super.delegate('${ operation }', '${ field . name }', args, context, info)` ; } ) . join ( ',\n' ) ; } export function renderMainSubscriptionMethodFields ( fields ) { return Object . keys ( fields ) . map ( f => { const field = fields [ f ] ; return `    ${ field . name }: (args, context, infoOrQuery): Promise<AsyncIterator<${ renderFieldType ( field . type ) }>> => super.delegateSubscription('${ field . name }', args, context, infoOrQuery)` ; } ) . join ( ',\n' ) ; }