Module: GraphQL::Client::QueryTypename

Defined in:
lib/graphql/client/query_typename.rb

Overview

Internal: Insert __typename field selections into query.

Class Method Summary collapse

Class Method Details

.insert_typename_fields(document, types: {}) ⇒ Object

Internal: Insert __typename field selections into query.

Skips known types when schema is provided.

document - GraphQL::Language::Nodes::Document to modify schema - Optional Map of GraphQL::Language::Nodes::Node to GraphQL::Type

Returns nothing.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/graphql/client/query_typename.rb', line 17

def self.insert_typename_fields(document, types: {})
  on_selections = ->(node, _parent) do
    type = types[node]

    if node.selections.any?
      case type && type.unwrap
      when NilClass, GraphQL::InterfaceType, GraphQL::UnionType
        names = node_flatten_selections(node.selections).map { |s| s.respond_to?(:name) ? s.name : nil }
        names = Set.new(names.compact)

        unless names.include?("__typename")
          node.selections = [GraphQL::Language::Nodes::Field.new(name: "__typename")] + node.selections
        end
      end
    elsif type && type.unwrap.is_a?(GraphQL::ObjectType)
      node.selections = [GraphQL::Language::Nodes::Field.new(name: "__typename")]
    end
  end

  visitor = GraphQL::Language::Visitor.new(document)
  visitor[GraphQL::Language::Nodes::Field].leave << on_selections
  visitor[GraphQL::Language::Nodes::FragmentDefinition].leave << on_selections
  visitor[GraphQL::Language::Nodes::OperationDefinition].leave << on_selections
  visitor.visit

  nil
end

.node_flatten_selections(selections) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/graphql/client/query_typename.rb', line 45

def self.node_flatten_selections(selections)
  selections.flat_map do |selection|
    case selection
    when GraphQL::Language::Nodes::Field
      selection
    when GraphQL::Language::Nodes::InlineFragment
      node_flatten_selections(selection.selections)
    else
      []
    end
  end
end