From abe0ee84ebe23daefed2344f7c16c46b60d9b0b1 Mon Sep 17 00:00:00 2001 From: yaacovCR Date: Wed, 15 Jan 2020 20:02:25 -0500 Subject: [PATCH] feat(stitching): add returnType option to delegateToSchema facilitates proxying from objects to lists or possibly otherwise incompatible schemas, see #33. --- src/Interfaces.ts | 2 ++ src/stitching/checkResultAndHandleErrors.ts | 7 +++++-- src/stitching/delegateToSchema.ts | 3 ++- src/test/testDataloader.ts | 6 ++---- src/transforms/CheckResultAndHandleErrors.ts | 8 ++++++-- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/Interfaces.ts b/src/Interfaces.ts index 18240280c21..73446f5d737 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -20,6 +20,7 @@ import { GraphQLInterfaceType, GraphQLObjectType, InlineFragmentNode, + GraphQLOutputType, } from 'graphql'; import { SchemaDirectiveVisitor } from './utils/SchemaDirectiveVisitor'; @@ -115,6 +116,7 @@ export interface IDelegateToSchemaOptions { schema: GraphQLSchema | SubschemaConfig; operation: Operation; fieldName: string; + returnType?: GraphQLOutputType; args?: { [key: string]: any }; context: TContext; info: IGraphQLToolsResolveInfo; diff --git a/src/stitching/checkResultAndHandleErrors.ts b/src/stitching/checkResultAndHandleErrors.ts index e13096248c5..d956ae255d5 100644 --- a/src/stitching/checkResultAndHandleErrors.ts +++ b/src/stitching/checkResultAndHandleErrors.ts @@ -9,6 +9,7 @@ import { GraphQLCompositeType, GraphQLError, GraphQLList, + GraphQLOutputType, GraphQLType, GraphQLSchema, FieldNode, @@ -34,6 +35,7 @@ export function checkResultAndHandleErrors( info: GraphQLResolveInfo, responseKey?: string, subschema?: GraphQLSchema | SubschemaConfig, + returnType: GraphQLOutputType = info.returnType, ): any { if (!responseKey) { responseKey = getResponseKeyFromInfo(info); @@ -43,7 +45,7 @@ export function checkResultAndHandleErrors( const data = result.data && result.data[responseKey]; const subschemas = [subschema]; - return handleResult(data, errors, subschemas, context, info); + return handleResult(data, errors, subschemas, context, info, returnType); } export function handleResult( @@ -52,8 +54,9 @@ export function handleResult( subschemas: Array, context: Record, info: IGraphQLToolsResolveInfo, + returnType = info.returnType, ): any { - const type = getNullableType(info.returnType); + const type = getNullableType(returnType); if (result == null) { return handleNull(info.fieldNodes, responsePathAsArray(info.path), errors); diff --git a/src/stitching/delegateToSchema.ts b/src/stitching/delegateToSchema.ts index 78dd203ce99..44c83eb6b1e 100644 --- a/src/stitching/delegateToSchema.ts +++ b/src/stitching/delegateToSchema.ts @@ -65,6 +65,7 @@ function delegateToSchemaImplementation({ info, operation = info.operation.operation, fieldName, + returnType = info.returnType, args, context, transforms = [], @@ -101,7 +102,7 @@ function delegateToSchemaImplementation({ }; transforms = [ - new CheckResultAndHandleErrors(info, fieldName, subschema, context), + new CheckResultAndHandleErrors(info, fieldName, subschema, context, returnType), ...transforms, new ExpandAbstractTypes(info.schema, targetSchema), ]; diff --git a/src/test/testDataloader.ts b/src/test/testDataloader.ts index 173b927de14..7b2e90e38dc 100644 --- a/src/test/testDataloader.ts +++ b/src/test/testDataloader.ts @@ -81,10 +81,8 @@ describe('dataloader', () => { ids: keys.map((k: { id: any }) => k.id) }, context: null, - info: { - ...keys[0].info, - returnType: new GraphQLList(keys[0].info.returnType), - } + info: keys[0].info, + returnType: new GraphQLList(keys[0].info.returnType), }); expect(users).to.deep.equal([{ diff --git a/src/transforms/CheckResultAndHandleErrors.ts b/src/transforms/CheckResultAndHandleErrors.ts index c54c2b78723..259000aab7a 100644 --- a/src/transforms/CheckResultAndHandleErrors.ts +++ b/src/transforms/CheckResultAndHandleErrors.ts @@ -1,4 +1,4 @@ -import { GraphQLSchema } from 'graphql'; +import { GraphQLSchema, GraphQLOutputType } from 'graphql'; import { checkResultAndHandleErrors } from '../stitching/checkResultAndHandleErrors'; import { Transform } from './transforms'; import { SubschemaConfig, IGraphQLToolsResolveInfo } from '../Interfaces'; @@ -8,17 +8,20 @@ export default class CheckResultAndHandleErrors implements Transform { private info: IGraphQLToolsResolveInfo; private fieldName?: string; private subschema?: GraphQLSchema | SubschemaConfig; + private returnType?: GraphQLOutputType; constructor( info: IGraphQLToolsResolveInfo, fieldName?: string, subschema?: GraphQLSchema | SubschemaConfig, context?: Record, + returnType: GraphQLOutputType = info.returnType, ) { this.context = context; this.info = info; this.fieldName = fieldName; this.subschema = subschema; + this.returnType = returnType; } public transformResult(result: any): any { @@ -27,7 +30,8 @@ export default class CheckResultAndHandleErrors implements Transform { this.context, this.info, this.fieldName, - this.subschema + this.subschema, + this.returnType, ); } }