File: fields_have_appropriate_selections.rb

package info (click to toggle)
ruby-graphql 2.2.17-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 9,584 kB
  • sloc: ruby: 67,505; ansic: 1,753; yacc: 831; javascript: 331; makefile: 6
file content (81 lines) | stat: -rw-r--r-- 2,721 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# frozen_string_literal: true
module GraphQL
  module StaticValidation
    # Scalars _can't_ have selections
    # Objects _must_ have selections
    module FieldsHaveAppropriateSelections
      include GraphQL::StaticValidation::Error::ErrorHelper

      def on_field(node, parent)
        field_defn = field_definition
        if validate_field_selections(node, field_defn.type.unwrap)
          super
        end
      end

      def on_operation_definition(node, _parent)
        if validate_field_selections(node, type_definition)
          super
        end
      end

      private


      def validate_field_selections(ast_node, resolved_type)
        msg = if resolved_type.nil?
          nil
        elsif resolved_type.kind.scalar? && ast_node.selections.any?
          selection_strs = ast_node.selections.map do |n|
            case n
            when GraphQL::Language::Nodes::InlineFragment
              "\"... on #{n.type.name} { ... }\""
            when GraphQL::Language::Nodes::Field
              "\"#{n.name}\""
            when GraphQL::Language::Nodes::FragmentSpread
              "\"#{n.name}\""
            else
              raise "Invariant: unexpected selection node: #{n}"
            end
          end
          "Selections can't be made on scalars (%{node_name} returns #{resolved_type.graphql_name} but has selections [#{selection_strs.join(", ")}])"
        elsif resolved_type.kind.fields? && ast_node.selections.empty?
          "Field must have selections (%{node_name} returns #{resolved_type.graphql_name} but has no selections. Did you mean '#{ast_node.name} { ... }'?)"
        else
          nil
        end

        if msg
          node_name = case ast_node
          when GraphQL::Language::Nodes::Field
            "field '#{ast_node.name}'"
          when GraphQL::Language::Nodes::OperationDefinition
            if ast_node.name.nil?
              "anonymous query"
            else
              "#{ast_node.operation_type} '#{ast_node.name}'"
            end
          else
            raise("Unexpected node #{ast_node}")
          end
          extensions = {
            "rule": "StaticValidation::FieldsHaveAppropriateSelections",
            "name": node_name.to_s
          }
          unless resolved_type.nil?
            extensions["type"] = resolved_type.to_type_signature
          end
          add_error(GraphQL::StaticValidation::FieldsHaveAppropriateSelectionsError.new(
            msg % { node_name: node_name },
            nodes: ast_node,
            node_name: node_name.to_s,
            type: resolved_type.nil? ? nil : resolved_type.graphql_name,
          ))
          false
        else
          true
        end
      end
    end
  end
end