Skip to content

Commit 19a6a93

Browse files
authored
Merge pull request #5602 from rmosolgo/sdl-transitive-deps-error
Require transitive interface names when loading a schema from SDL
2 parents a1e0b0e + 00276ab commit 19a6a93

2 files changed

Lines changed: 35 additions & 2 deletions

File tree

lib/graphql/schema/build_from_definition.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,16 @@ def build(schema_superclass, document, default_resolve:, using: {}, base_types:
9999
# It's possible that this was already loaded by the directives
100100
prev_type = types[definition.name]
101101
if prev_type.nil? || prev_type.is_a?(Schema::LateBoundType)
102+
if definition.is_a?(GraphQL::Language::Nodes::ObjectTypeDefinition) || definition.is_a?(Language::Nodes::InterfaceTypeDefinition)
103+
interface_names = definition.interfaces.map(&:name)
104+
transitive_names = interface_names.map { |n| document.definitions.find { |d| d.respond_to?(:name) && d.name == n }&.interfaces&.map(&:name) }
105+
transitive_names.flatten!
106+
transitive_names.compact!
107+
if !(missing_transitive_interfaces = transitive_names - interface_names).empty?
108+
raise GraphQL::Schema::InvalidDocumentError, "type #{definition.name} is missing one or more transitive interface names: #{missing_transitive_interfaces.join(", ")}. Add them to the type's `implements` list and try again."
109+
end
110+
end
111+
102112
types[definition.name] = build_definition_from_node(definition, type_resolver, default_resolve, base_types)
103113
end
104114
end

spec/graphql/schema/build_from_definition_spec.rb

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,29 @@ def assert_schema_and_compare_output(definition)
539539
assert_schema_and_compare_output(schema)
540540
end
541541

542+
it "requires transitive dependencies to be named" do
543+
schema_str = <<~GRAPHQL
544+
interface A implements B {
545+
s: String
546+
}
547+
548+
interface B {
549+
s: String
550+
}
551+
552+
type Query implements A & B {
553+
s: String
554+
}
555+
GRAPHQL
556+
557+
assert_schema_and_compare_output(schema_str)
558+
559+
invalid_schema_str = schema_str.sub("A & B", "A")
560+
assert_raises GraphQL::Schema::InvalidDocumentError do
561+
GraphQL::Schema.from_definition(invalid_schema_str)
562+
end
563+
end
564+
542565
it "supports interfaces that implement interfaces" do
543566
schema = <<-SCHEMA
544567
interface Named implements Node {
@@ -1542,13 +1565,13 @@ def self.parse(string)
15421565
person: Person
15431566
}
15441567
1545-
type Person implements NamedEntity {
1568+
type Person implements NamedEntity & Entity {
15461569
id: ID!
15471570
name: String
15481571
nationality: String
15491572
}
15501573
1551-
type Product implements NamedEntity {
1574+
type Product implements NamedEntity & Entity {
15521575
id: ID!
15531576
name: String
15541577
amount: Int

0 commit comments

Comments
 (0)