@@ -5,9 +5,17 @@ import type {
55 GraphQLResolveInfo ,
66 GraphQLSchema ,
77 GraphQLType ,
8+ OperationTypeNode ,
89 SelectionSetNode ,
910} from 'graphql' ;
10- import { getNamedType , isAbstractType , isInterfaceType , isObjectType , Kind } from 'graphql' ;
11+ import {
12+ getNamedType ,
13+ GraphQLList ,
14+ isAbstractType ,
15+ isInterfaceType ,
16+ isObjectType ,
17+ Kind ,
18+ } from 'graphql' ;
1119import lodashGet from 'lodash.get' ;
1220import toPath from 'lodash.topath' ;
1321import { process } from '@graphql-mesh/cross-helpers' ;
@@ -20,9 +28,11 @@ import {
2028 type MeshPubSub ,
2129 type YamlConfig ,
2230} from '@graphql-mesh/types' ;
31+ import { batchDelegateToSchema } from '@graphql-tools/batch-delegate' ;
2332import {
33+ delegateToSchema ,
2434 subtractSelectionSets ,
25- type MergedTypeResolver ,
35+ type MergedTypeConfig ,
2636 type StitchingInfo ,
2737 type Subschema ,
2838} from '@graphql-tools/delegate' ;
@@ -224,7 +234,7 @@ export function resolveAdditionalResolversWithoutImport(
224234 return resolvePayload ( payload ) ; // no stitching, cannot be resolved anywhere else
225235 }
226236 const returnTypeName = getNamedType ( info . returnType ) . name ;
227- const mergedTypeInfo = stitchingInfo ? .mergedTypes ?. [ returnTypeName ] ;
237+ const mergedTypeInfo = stitchingInfo . mergedTypes [ returnTypeName ] ;
228238 if ( ! mergedTypeInfo ) {
229239 return resolvePayload ( payload ) ; // this type is not merged or resolvable
230240 }
@@ -244,39 +254,65 @@ export function resolveAdditionalResolversWithoutImport(
244254 return resolvePayload ( payload ) ;
245255 }
246256
247- // find the best resolver by diffing the selection sets
248- let resolver : MergedTypeResolver | null = null ;
257+ // find the best subgraph by diffing the selection sets
249258 let subschema : Subschema | null = null ;
259+ let mergedTypeConfig : MergedTypeConfig | null = null ;
250260 for ( const [ requiredSubschema , requiredSelSet ] of mergedTypeInfo . selectionSets ) {
251- const matchResolver = mergedTypeInfo ?. resolvers . get ( requiredSubschema ) ;
252- if ( ! matchResolver ) {
253- // the subschema has no resolvers, nothing to search for
261+ const tentativeMergedTypeConfig = requiredSubschema . merge ?. [ returnTypeName ] ;
262+ if ( tentativeMergedTypeConfig ?. fields ) {
263+ // this resolver requires additional fields (think `@requires(fields: "x")`)
264+ // TODO: actually implement whether the payload already contains those fields
265+ // TODO: is there a better way for finding a match?
254266 continue ;
255267 }
256268 const diff = subtractSelectionSets ( requiredSelSet , availableSelSet ) ;
257269 if ( ! diff . selections . length ) {
258270 // all of the fields of the requesting (available) selection set is exist in the required selection set
259- resolver = matchResolver ;
260271 subschema = requiredSubschema ;
272+ mergedTypeConfig = tentativeMergedTypeConfig ;
261273 break ;
262274 }
263275 }
264- if ( ! resolver || ! subschema ) {
276+ if ( ! subschema || ! mergedTypeConfig ) {
265277 // the type cannot be resolved
266278 return resolvePayload ( payload ) ;
267279 }
268280
269281 return handleMaybePromise (
270- ( ) =>
271- resolver (
272- payload ,
273- ctx ,
274- info ,
275- subschema ,
276- missingSelectionSet ,
277- undefined ,
278- info . returnType ,
279- ) ,
282+ ( ) => {
283+ if ( mergedTypeConfig . argsFromKeys ) {
284+ return batchDelegateToSchema ( {
285+ schema : subschema ,
286+ operation : 'query' as OperationTypeNode ,
287+ fieldName : mergedTypeConfig . fieldName ,
288+ returnType : new GraphQLList ( info . returnType ) ,
289+ key : mergedTypeConfig . key ?.( payload ) || payload , // TODO: should use valueFromResults on the args too?
290+ argsFromKeys : mergedTypeConfig . argsFromKeys ,
291+ valuesFromResults : mergedTypeConfig . valuesFromResults ,
292+ selectionSet : missingSelectionSet ,
293+ context : ctx ,
294+ info,
295+ dataLoaderOptions : mergedTypeConfig . dataLoaderOptions ,
296+ skipTypeMerging : false , // important to be false so that fields outside this subgraph can be resolved properly
297+ } ) ;
298+ }
299+ if ( mergedTypeConfig . args ) {
300+ return delegateToSchema ( {
301+ schema : subschema ,
302+ operation : 'query' as OperationTypeNode ,
303+ fieldName : mergedTypeConfig . fieldName ,
304+ returnType : info . returnType ,
305+ args : mergedTypeConfig . args ( payload ) , // TODO: should use valueFromResults on the args too?
306+ selectionSet : missingSelectionSet ,
307+ context : ctx ,
308+ info,
309+ skipTypeMerging : false , // important to be false so that fields outside this subgraph can be resolved properly
310+ } ) ;
311+ }
312+ // no way to delegate to anything, return empty - i.e. resolve just payload
313+ // should not happen though, there'll be something to use
314+ return { } ;
315+ } ,
280316 resolved => resolvePayload ( mergeDeep ( [ payload , resolved ] ) ) ,
281317 ) ;
282318 } ,
0 commit comments