From 4f649ac730d2dcac70a7f77013b1e1e883b8c0e0 Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Sat, 5 Sep 2020 13:23:36 +0300 Subject: [PATCH] resolveType: remove support for returning GraphQLObjectType --- src/execution/__tests__/abstract-test.js | 91 ++---------------------- src/execution/execute.js | 18 ++--- src/type/definition.d.ts | 2 +- src/type/definition.js | 2 +- 4 files changed, 18 insertions(+), 95 deletions(-) diff --git a/src/execution/__tests__/abstract-test.js b/src/execution/__tests__/abstract-test.js index 1d8bbeaab0..519585af0f 100644 --- a/src/execution/__tests__/abstract-test.js +++ b/src/execution/__tests__/abstract-test.js @@ -1,8 +1,6 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; -import invariant from '../../jsutils/invariant'; - import { parse } from '../../language/parser'; import { GraphQLSchema } from '../../type/schema'; @@ -297,89 +295,6 @@ describe('Execute: Handles execution of abstract types', () => { }); }); - it('deprecated(will be removed in v16.0.0): resolveType allows resolving with type object', async () => { - const PetType = new GraphQLInterfaceType({ - name: 'Pet', - resolveType(obj, context) { - if (obj instanceof Dog) { - return context.async ? Promise.resolve(DogType) : DogType; - } - // istanbul ignore else (See: 'https://github.com/graphql/graphql-js/issues/2618') - if (obj instanceof Cat) { - return context.async ? Promise.resolve(CatType) : CatType; - } - - // istanbul ignore next (Not reachable. All possible types have been considered) - invariant(false); - }, - fields: { - name: { type: GraphQLString }, - }, - }); - - const DogType = new GraphQLObjectType({ - name: 'Dog', - interfaces: [PetType], - fields: { - name: { type: GraphQLString }, - woofs: { type: GraphQLBoolean }, - }, - }); - - const CatType = new GraphQLObjectType({ - name: 'Cat', - interfaces: [PetType], - fields: { - name: { type: GraphQLString }, - meows: { type: GraphQLBoolean }, - }, - }); - - const schema = new GraphQLSchema({ - query: new GraphQLObjectType({ - name: 'Query', - fields: { - pets: { - type: new GraphQLList(PetType), - resolve() { - return [new Dog('Odie', true), new Cat('Garfield', false)]; - }, - }, - }, - }), - types: [CatType, DogType], - }); - - const query = ` - { - pets { - name - ... on Dog { - woofs - } - ... on Cat { - meows - } - } - } - `; - - expect(await executeQuery({ schema, query })).to.deep.equal({ - data: { - pets: [ - { - name: 'Odie', - woofs: true, - }, - { - name: 'Garfield', - meows: false, - }, - ], - }, - }); - }); - it('resolveType can throw', async () => { const PetType = new GraphQLInterfaceType({ name: 'Pet', @@ -658,5 +573,11 @@ describe('Execute: Handles execution of abstract types', () => { expectError({ forTypeName: undefined }).toEqual( 'Abstract type "Pet" must resolve to an Object type at runtime for field "Query.pet" with value { __typename: undefined }, received "[]".', ); + + // FIXME: workaround since we can't inject resolveType into SDL + (schema.getType('Pet'): any).resolveType = () => schema.getType('Cat'); + expectError({ forTypeName: undefined }).toEqual( + 'Support for returning GraphQLObjectType from resolveType was removed in graphql-js@16.0.0 please return type name instead.', + ); }); }); diff --git a/src/execution/execute.js b/src/execution/execute.js index 9c4c9f2c1d..cc62e0b556 100644 --- a/src/execution/execute.js +++ b/src/execution/execute.js @@ -52,7 +52,6 @@ import { GraphQLSkipDirective, } from '../type/directives'; import { - isNamedType, isObjectType, isAbstractType, isLeafType, @@ -954,29 +953,32 @@ function completeAbstractValue( } function ensureValidRuntimeType( - runtimeTypeOrName: mixed, + runtimeTypeName: mixed, exeContext: ExecutionContext, returnType: GraphQLAbstractType, fieldNodes: $ReadOnlyArray, info: GraphQLResolveInfo, result: mixed, ): GraphQLObjectType { - if (runtimeTypeOrName == null) { + if (runtimeTypeName == null) { throw new GraphQLError( `Abstract type "${returnType.name}" must resolve to an Object type at runtime for field "${info.parentType.name}.${info.fieldName}". Either the "${returnType.name}" type should provide a "resolveType" function or each possible type should provide an "isTypeOf" function.`, fieldNodes, ); } - // FIXME: temporary workaround until support for passing object types would be removed in v16.0.0 - const runtimeTypeName = isNamedType(runtimeTypeOrName) - ? runtimeTypeOrName.name - : runtimeTypeOrName; + // releases before 16.0.0 supported returning `GraphQLObjectType` from `resolveType` + // TODO: remove in 17.0.0 release + if (isObjectType(runtimeTypeName)) { + throw new GraphQLError( + 'Support for returning GraphQLObjectType from resolveType was removed in graphql-js@16.0.0 please return type name instead.', + ); + } if (typeof runtimeTypeName !== 'string') { throw new GraphQLError( `Abstract type "${returnType.name}" must resolve to an Object type at runtime for field "${info.parentType.name}.${info.fieldName}" with ` + - `value ${inspect(result)}, received "${inspect(runtimeTypeOrName)}".`, + `value ${inspect(result)}, received "${inspect(runtimeTypeName)}".`, ); } diff --git a/src/type/definition.d.ts b/src/type/definition.d.ts index 5e5edb0548..b37ea16dad 100644 --- a/src/type/definition.d.ts +++ b/src/type/definition.d.ts @@ -456,7 +456,7 @@ export type GraphQLTypeResolver = ( context: TContext, info: GraphQLResolveInfo, abstractType: GraphQLAbstractType, -) => PromiseOrValue | string>>; +) => PromiseOrValue; export type GraphQLIsTypeOfFn = ( source: TSource, diff --git a/src/type/definition.js b/src/type/definition.js index c73b77ea80..e3a8c5c722 100644 --- a/src/type/definition.js +++ b/src/type/definition.js @@ -931,7 +931,7 @@ export type GraphQLTypeResolver = ( context: TContext, info: GraphQLResolveInfo, abstractType: GraphQLAbstractType, -) => PromiseOrValue; +) => PromiseOrValue; export type GraphQLIsTypeOfFn = ( source: TSource,