fix: deduplicate interfaces implementing interfaces (#608)

This commit is contained in:
Tim Griesser 2020-11-05 13:12:13 -05:00 committed by GitHub
parent 6e06f8f3c6
commit 2e9333849d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 2 deletions

View File

@ -1055,7 +1055,7 @@ export class SchemaBuilder {
const type = this.getInterface(i) const type = this.getInterface(i)
list.push(type, ...type.getInterfaces()) list.push(type, ...type.getInterfaces())
}) })
return list return Array.from(new Set(list))
} }
protected buildInterfaceFields(interfaces: (string | NexusInterfaceTypeDef<any>)[]) { protected buildInterfaceFields(interfaces: (string | NexusInterfaceTypeDef<any>)[]) {

View File

@ -26,6 +26,31 @@ Object {
exports[`interfaceType can not implement itself 1`] = `"GraphQL Nexus: Interface Node can't implement itself"`; exports[`interfaceType can not implement itself 1`] = `"GraphQL Nexus: Interface Node can't implement itself"`;
exports[`interfaceType deduplicates interfaces implementing interfaces 1`] = `
"### This file was generated by Nexus Schema
### Do not make changes to this file directly
interface Node {
id: ID
}
interface Node2 implements Node {
id: ID
id2: ID
}
type Foo implements Node2 & Node {
id: ID
id2: ID
}
type Query {
ok: Boolean!
}
"
`;
exports[`interfaceType detects circular dependencies 1`] = `"GraphQL Nexus: Interface circular dependency detected NodeA -> NodeC -> NodeB -> NodeA"`; exports[`interfaceType detects circular dependencies 1`] = `"GraphQL Nexus: Interface circular dependency detected NodeA -> NodeC -> NodeB -> NodeA"`;
exports[`interfaceType logs error when resolveType is not provided for an interface 1`] = ` exports[`interfaceType logs error when resolveType is not provided for an interface 1`] = `

View File

@ -1,6 +1,6 @@
import { graphql } from 'graphql' import { graphql } from 'graphql'
import path from 'path' import path from 'path'
import { interfaceType, makeSchema, objectType, queryField } from '../src/core' import { interfaceType, makeSchema, objectType, queryField, generateSchema } from '../src/core'
describe('interfaceType', () => { describe('interfaceType', () => {
it('can be implemented by object types', async () => { it('can be implemented by object types', async () => {
@ -127,6 +127,38 @@ describe('interfaceType', () => {
}) })
).toThrowErrorMatchingSnapshot() ).toThrowErrorMatchingSnapshot()
}) })
it('deduplicates interfaces implementing interfaces', async () => {
const { schemaTypes } = await generateSchema.withArtifacts(
{
types: [
interfaceType({
name: 'Node',
definition(t) {
t.id('id')
t.resolveType(() => null)
},
}),
interfaceType({
name: 'Node2',
definition(t) {
t.implements('Node')
t.id('id2')
t.resolveType(() => null)
},
}),
objectType({
name: 'Foo',
definition(t) {
t.implements('Node2', 'Node')
},
}),
],
outputs: false,
},
false
)
expect(schemaTypes).toMatchSnapshot()
})
it('detects circular dependencies', async () => { it('detects circular dependencies', async () => {
expect(() => expect(() =>
makeSchema({ makeSchema({