import { getOperationRootType } from 'graphql' ; import { buildResolveInfo , collectFields , ExecutionContext , getFieldDef , } from 'graphql/execution/execute' ; import { addPath } from 'graphql/jsutils/Path' ; import { ServerClosure } from '../types' ; export const constructContext = ( c ) => ( { connectionParams } ) => typeof c . context === 'function' ? c . context ( { connectionParams } ) : { ... c . context , connectionParams } ; export const getResolverAndArgs = ( c ) => ( execContext ) => { const type = getOperationRootType ( c . schema , execContext . operation ) ; const fields = collectFields ( execContext , type , execContext . operation . selectionSet , Object . create ( null ) , Object . create ( null ) ) ; const responseNames = Object . keys ( fields ) ; const responseName = responseNames [ 0 ] ; const fieldNodes = fields [ responseName ] ; const fieldNode = fieldNodes [ 0 ] ; const fieldName = fieldNode . name . value ; const fieldDef = getFieldDef ( c . schema , type , fieldName ) ; const path = addPath ( undefined , responseName , type . name ) ; const info = buildResolveInfo ( execContext , fieldDef ! , fieldNodes , type , path ) ; return [ fieldDef , null , execContext . variableValues , execContext . contextValue , info , ] ; } ; const prepareResolver = < T extends object > ( r ) => { visit < any > ( r , ( node ) => { if ( ! ( 'resolve' in node ) ) { return ; } [ 'onSubscribe' , 'onComplete' ] . forEach ( ( key ) => ( node . resolve [ key ] = node [ key ] ) ) ; return false ; } ) ; return r ; } ; export const prepareResolvers = < T extends object | object [ ] > ( arg ) => Array . isArray ( arg ) ? ( arg . map ( prepareResolver ) as T [ ] ) : prepareResolver ( arg ) ; const visit = < T = object > ( node , handler ) => Object . values ( node ) . forEach ( ( value ) => { if ( typeof value !== 'object' ) { return ; } if ( handler ( value ) === false ) { return ; } visit ( value , handler ) ; } ) ;