From 2dde956bd1de6ad404416ec9dc4406a25951fe4b Mon Sep 17 00:00:00 2001 From: Vladimir Razuvaev Date: Tue, 1 Jun 2021 19:48:41 +0700 Subject: [PATCH] fix(gatsby): merge resolveType when merging abstract types (#31710) --- .../src/schema/__tests__/build-schema.js | 64 +++++++++++++++++++ packages/gatsby/src/schema/schema.js | 27 ++++++++ 2 files changed, 91 insertions(+) diff --git a/packages/gatsby/src/schema/__tests__/build-schema.js b/packages/gatsby/src/schema/__tests__/build-schema.js index 59b814134b2ce..c3e07d91da678 100644 --- a/packages/gatsby/src/schema/__tests__/build-schema.js +++ b/packages/gatsby/src/schema/__tests__/build-schema.js @@ -979,6 +979,70 @@ describe(`Build schema`, () => { expect(interfaces).toEqual([`Foo`, `Bar`]) }) + it(`merges resolveType for abstract types (Type Builder)`, async () => { + createTypes( + [ + `interface Foo { foo: String }`, + ` + type Fizz { id: ID! } + type Buzz { id: ID! } + union FizzBuzz = Fizz | Buzz + `, + buildInterfaceType({ + name: `Foo`, + fields: { id: `ID!` }, + resolveType: source => source.expectedType, + }), + buildUnionType({ + name: `FizzBuzz`, + resolveType: source => (source.isFizz ? `Fizz` : `Buzz`), + }), + ], + { + name: `default-site-plugin`, + } + ) + const schema = await buildSchema() + const Foo = schema.getType(`Foo`) + expect(Foo.resolveType({ expectedType: `Bar` })).toEqual(`Bar`) + + const FizzBuzz = schema.getType(`FizzBuzz`) + expect(FizzBuzz.resolveType({ isFizz: true })).toEqual(`Fizz`) + expect(FizzBuzz.resolveType({ isFizz: false })).toEqual(`Buzz`) + }) + + it(`merges resolveType for abstract types (graphql-js)`, async () => { + createTypes( + [ + `interface Foo { foo: String }`, + ` + type Fizz { id: ID! } + type Buzz { id: ID! } + union FizzBuzz = Fizz | Buzz + `, + new GraphQLInterfaceType({ + name: `Foo`, + fields: { foo: { type: GraphQLString } }, + resolveType: source => source.expectedType, + }), + new GraphQLUnionType({ + name: `FizzBuzz`, + resolveType: source => (source.isFizz ? `Fizz` : `Buzz`), + }), + ], + { + name: `default-site-plugin`, + } + ) + const schema = await buildSchema() + const Foo = schema.getType(`Foo`) + expect(Foo.resolveType({ expectedType: `Bar` })).toEqual(`Bar`) + + const FizzBuzz = schema.getType(`FizzBuzz`) + expect(FizzBuzz.resolveType({ isFizz: true })).toEqual(`Fizz`) + expect(FizzBuzz.resolveType({ isFizz: false })).toEqual(`Buzz`) + }) + it(`merges plugin-defined type (Type Builder) with overridable built-in type without warning`, async () => { createTypes( [ diff --git a/packages/gatsby/src/schema/schema.js b/packages/gatsby/src/schema/schema.js index e97f33be09409..df9ecd00be4bd 100644 --- a/packages/gatsby/src/schema/schema.js +++ b/packages/gatsby/src/schema/schema.js @@ -8,6 +8,7 @@ const { GraphQLList, GraphQLObjectType, GraphQLInterfaceType, + GraphQLUnionType, } = require(`graphql`) const { ObjectTypeComposer, @@ -406,6 +407,15 @@ const mergeTypes = ({ type.getInterfaces().forEach(iface => typeComposer.addInterface(iface)) } + if ( + type instanceof GraphQLInterfaceType || + type instanceof InterfaceTypeComposer || + type instanceof GraphQLUnionType || + type instanceof UnionTypeComposer + ) { + mergeResolveType({ typeComposer, type }) + } + if (isNamedTypeComposer(type)) { typeComposer.extendExtensions(type.getExtensions()) } @@ -1387,3 +1397,20 @@ const mergeFields = ({ typeComposer, fields }) => typeComposer.setField(fieldName, fieldConfig) } }) + +const mergeResolveType = ({ typeComposer, type }) => { + if ( + (type instanceof GraphQLInterfaceType || + type instanceof GraphQLUnionType) && + type.resolveType + ) { + typeComposer.setResolveType(type.resolveType) + } + if ( + (type instanceof InterfaceTypeComposer || + type instanceof UnionTypeComposer) && + type.getResolveType() + ) { + typeComposer.setResolveType(type.getResolveType()) + } +}