File: required_input_object_attributes_are_present.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 (59 lines) | stat: -rw-r--r-- 2,247 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
# frozen_string_literal: true
module GraphQL
  module StaticValidation
    module RequiredInputObjectAttributesArePresent
      def on_input_object(node, parent)
        if parent.is_a? GraphQL::Language::Nodes::Argument
          validate_input_object(node, context, parent)
        end
        super
      end

      private

      def get_parent_type(context, parent)
        # If argument_definition is defined we're at nested object
        # and need to refer to the containing input object type rather
        # than the field_definition.
        # h/t @rmosolgo
        arg_defn = context.argument_definition

        # Double checking that arg_defn is an input object as nested
        # scalars, namely JSON, can make it to this branch
        defn = if arg_defn && arg_defn.type.unwrap.kind.input_object?
          arg_defn.type.unwrap
        else
          context.directive_definition || context.field_definition
        end

        parent_type = context.warden.get_argument(defn, parent_name(parent, defn))
        parent_type ? parent_type.type.unwrap : nil
      end

      def validate_input_object(ast_node, context, parent)
        parent_type = get_parent_type(context, parent)
        return unless parent_type && parent_type.kind.input_object?

        required_fields = context.warden.arguments(parent_type)
          .select{ |arg| arg.type.kind.non_null? && !arg.default_value? }
          .map!(&:graphql_name)

        present_fields = ast_node.arguments.map(&:name)
        missing_fields = required_fields - present_fields

        missing_fields.each do |missing_field|
          path = [*context.path, missing_field]
          missing_field_type = context.warden.get_argument(parent_type, missing_field).type
          add_error(RequiredInputObjectAttributesArePresentError.new(
            "Argument '#{missing_field}' on InputObject '#{parent_type.to_type_signature}' is required. Expected type #{missing_field_type.to_type_signature}",
            argument_name: missing_field,
            argument_type: missing_field_type.to_type_signature,
            input_object_type: parent_type.to_type_signature,
            path: path,
            nodes: ast_node,
          ))
        end
      end
    end
  end
end