Skip to content

Commit

Permalink
fix(gatsby): merge inherited interfaces when merging types (#30501) (#…
Browse files Browse the repository at this point in the history
…30562)

(cherry picked from commit e1f1656)
  • Loading branch information
vladar committed Mar 30, 2021
1 parent cf975d0 commit b9dfd16
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 15 deletions.
89 changes: 89 additions & 0 deletions packages/gatsby/src/schema/__tests__/build-schema.js
Expand Up @@ -890,6 +890,95 @@ describe(`Build schema`, () => {
expect(report.warn).not.toHaveBeenCalled()
})

it(`merges interfaces extending other interfaces`, async () => {
createTypes(
[
`interface Foo { foo: String }`,
`interface Bar { bar: String }`,
`interface Baz implements Foo { foo: String }`,
`interface Baz implements Bar & Node { bar: String, id: ID! }`,
],
{
name: `default-site-plugin`,
}
)
const schema = await buildSchema()
const Baz = schema.getType(`Baz`)
const interfaces = Baz.getInterfaces().map(iface => iface.name)
expect(interfaces).toEqual([`Foo`, `Bar`, `Node`])
})

it(`merges interfaces extending other interfaces (Type Builder)`, async () => {
createTypes(
[
`interface Foo { foo: String }`,
buildInterfaceType({
name: `Bar`,
fields: {
bar: `String`,
},
}),
buildInterfaceType({
name: `Baz`,
fields: {
foo: `String`,
},
interfaces: [`Foo`],
}),
buildInterfaceType({
name: `Baz`,
fields: {
id: `ID!`,
bar: `String`,
},
interfaces: [`Bar`, `Node`],
}),
],
{
name: `default-site-plugin`,
}
)
const schema = await buildSchema()
const Baz = schema.getType(`Baz`)
const interfaces = Baz.getInterfaces().map(iface => iface.name)
expect(interfaces).toEqual([`Foo`, `Bar`, `Node`])
})

it(`merges interfaces extending other interfaces (graphql-js)`, async () => {
const Foo = new GraphQLInterfaceType({
name: `Foo`,
fields: {
foo: { type: GraphQLString },
},
})
const Bar = new GraphQLInterfaceType({
name: `Bar`,
fields: {
bar: { type: GraphQLString },
},
})
const Baz1 = new GraphQLInterfaceType({
name: `Baz`,
fields: {
foo: { type: GraphQLString },
},
interfaces: [Foo],
})
const Baz2 = new GraphQLInterfaceType({
name: `Baz`,
fields: {
bar: { type: GraphQLString },
},
interfaces: [Bar],
})

createTypes([Foo, Bar, Baz1, Baz2], { name: `default-site-plugin` })
const schema = await buildSchema()
const Baz = schema.getType(`Baz`)
const interfaces = Baz.getInterfaces().map(iface => iface.name)
expect(interfaces).toEqual([`Foo`, `Bar`])
})

it(`merges plugin-defined type (Type Builder) with overridable built-in type without warning`, async () => {
createTypes(
[
Expand Down
21 changes: 6 additions & 15 deletions packages/gatsby/src/schema/schema.js
Expand Up @@ -16,7 +16,6 @@ const {
InputTypeComposer,
ScalarTypeComposer,
EnumTypeComposer,
defineFieldMapToConfig,
} = require(`graphql-compose`)
const { getNode, getNodesByType } = require(`../redux/nodes`)

Expand Down Expand Up @@ -397,22 +396,14 @@ const mergeTypes = ({
}
}

if (type instanceof ObjectTypeComposer) {
mergeFields({ typeComposer, fields: type.getFields() })
type.getInterfaces().forEach(iface => typeComposer.addInterface(iface))
} else if (type instanceof InterfaceTypeComposer) {
if (
type instanceof ObjectTypeComposer ||
type instanceof InterfaceTypeComposer ||
type instanceof GraphQLObjectType ||
type instanceof GraphQLInterfaceType
) {
mergeFields({ typeComposer, fields: type.getFields() })
} else if (type instanceof GraphQLObjectType) {
mergeFields({
typeComposer,
fields: defineFieldMapToConfig(type.getFields()),
})
type.getInterfaces().forEach(iface => typeComposer.addInterface(iface))
} else if (type instanceof GraphQLInterfaceType) {
mergeFields({
typeComposer,
fields: defineFieldMapToConfig(type.getFields()),
})
}

if (isNamedTypeComposer(type)) {
Expand Down

0 comments on commit b9dfd16

Please sign in to comment.