import { GraphQLUnionType , GraphQLWrappingType , GraphQLObjectType , GraphQLInputObjectType , GraphQLInputField , GraphQLField , GraphQLInputType , GraphQLOutputType , GraphQLScalarType , GraphQLNamedType , isWrappingType , isNonNullType , isListType , GraphQLFieldMap , GraphQLEnumType , GraphQLType , GraphQLInterfaceType , } from 'graphql' ; import { Generator } from '../types' ; export const generator = { Main : renderMainMethod , Header : renderHeader , } ; function renderHeader ( schema ) { return `const { Graphcool } = require('graphcool-binding')
const { GraphQLResolveInfo } = require('graphql')

const typeDefs = \`
${ schema }\`` ; } function renderMainMethod ( queryType , mutationType ? , subscriptionType ? ) { return `module.exports.Graphcool = class Binding extends Graphcool {
  
  constructor({ endpoint, secret, fragmentReplacements, debug }) {
    super({ typeDefs, endpoint, secret, fragmentReplacements, debug });

    var self = this
    this.exists = {
${ renderExistsFields ( queryType . getFields ( ) ) }
    }

    this.query = {
${ renderMainMethodFields ( 'query' , queryType . getFields ( ) ) }
    }${ mutationType ? `
      
    this.mutation = {
${ renderMainMethodFields ( 'mutation' , mutationType . getFields ( ) ) }
    }` : '' }${ subscriptionType ? `
      
    this.subscription = {
${ renderMainSubscriptionMethodFields ( 'mutation' , subscriptionType . getFields ( ) ) }
    }` : '' }
  }
  
  delegate(operation, field, args, context, info) {
    return super.delegate(operation, field, args, context, info)
  }

  delegateSubscription(field, args, context, infoOrQuery) {
    return super.delegateSubscription(field, args, context, infoOrQuery)
  }
}` ; } export function renderExistsFields ( fields ) { return Object . keys ( fields ) . map ( f => { const field = fields [ f ] ; let type = field . type ; let foundList = false ; while ( isWrappingType ( type ) ) { type = type . ofType ; foundList = foundList || isListType ( type ) ; } if ( foundList ) { const whereType = ( field . args . find ( a => a . name === 'where' ) ! . type as GraphQLInputObjectType ) . name ; return `      ${ type . name }(where) {
        return super.existsDelegate('query', '${ field . name }', { where }, {}, '{ id }')
      }` ; } } ) . filter ( f => f ) . join ( ',\n' ) ; } export function renderMainMethodFields ( operation , fields ) { return Object . keys ( fields ) . map ( f => { const field = fields [ f ] ; return `      ${ field . name }(args, info) { 
        return self.delegate('${ operation }', '${ field . name }', args, {}, info)
      }` ; } ) . join ( ',\n' ) ; } export function renderMainSubscriptionMethodFields ( operation , fields ) { return Object . keys ( fields ) . map ( f => { const field = fields [ f ] ; return `      ${ field . name }(args, infoOrQuery) { 
        return self.delegateSubscription('${ field . name }', args, {}, infoOrQuery)
      }` ; } ) . join ( ',\n' ) ; }