graphql 1.12.18 → 1.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/mutation_generator.rb +1 -1
  3. data/lib/generators/graphql/object_generator.rb +2 -1
  4. data/lib/generators/graphql/relay.rb +19 -11
  5. data/lib/generators/graphql/templates/schema.erb +14 -2
  6. data/lib/generators/graphql/type_generator.rb +0 -1
  7. data/lib/graphql/analysis/ast/field_usage.rb +2 -2
  8. data/lib/graphql/analysis/ast/query_complexity.rb +10 -14
  9. data/lib/graphql/analysis/ast/visitor.rb +4 -4
  10. data/lib/graphql/backtrace/table.rb +1 -1
  11. data/lib/graphql/dataloader/source.rb +30 -2
  12. data/lib/graphql/dataloader.rb +55 -22
  13. data/lib/graphql/deprecation.rb +1 -5
  14. data/lib/graphql/directive.rb +0 -4
  15. data/lib/graphql/enum_type.rb +5 -1
  16. data/lib/graphql/execution/errors.rb +1 -0
  17. data/lib/graphql/execution/interpreter/arguments.rb +1 -1
  18. data/lib/graphql/execution/interpreter/arguments_cache.rb +2 -2
  19. data/lib/graphql/execution/interpreter/runtime.rb +20 -12
  20. data/lib/graphql/execution/lookahead.rb +2 -2
  21. data/lib/graphql/execution/multiplex.rb +1 -1
  22. data/lib/graphql/integer_encoding_error.rb +18 -2
  23. data/lib/graphql/introspection/directive_type.rb +1 -1
  24. data/lib/graphql/introspection/entry_points.rb +2 -2
  25. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  26. data/lib/graphql/introspection/field_type.rb +2 -2
  27. data/lib/graphql/introspection/input_value_type.rb +4 -4
  28. data/lib/graphql/introspection/schema_type.rb +2 -2
  29. data/lib/graphql/introspection/type_type.rb +10 -10
  30. data/lib/graphql/language/block_string.rb +0 -4
  31. data/lib/graphql/language/document_from_schema_definition.rb +4 -2
  32. data/lib/graphql/language/lexer.rb +0 -3
  33. data/lib/graphql/language/lexer.rl +0 -4
  34. data/lib/graphql/language/nodes.rb +2 -1
  35. data/lib/graphql/language/parser.rb +442 -434
  36. data/lib/graphql/language/parser.y +5 -4
  37. data/lib/graphql/language/printer.rb +6 -1
  38. data/lib/graphql/language/sanitized_printer.rb +5 -5
  39. data/lib/graphql/language/token.rb +0 -4
  40. data/lib/graphql/name_validator.rb +0 -4
  41. data/lib/graphql/pagination/connections.rb +35 -16
  42. data/lib/graphql/query/arguments.rb +1 -1
  43. data/lib/graphql/query/arguments_cache.rb +1 -1
  44. data/lib/graphql/query/context.rb +5 -2
  45. data/lib/graphql/query/literal_input.rb +1 -1
  46. data/lib/graphql/query/null_context.rb +12 -7
  47. data/lib/graphql/query/serial_execution/field_resolution.rb +1 -1
  48. data/lib/graphql/query/validation_pipeline.rb +1 -1
  49. data/lib/graphql/query/variables.rb +5 -1
  50. data/lib/graphql/relay/edges_instrumentation.rb +0 -1
  51. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  52. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  53. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  54. data/lib/graphql/rubocop.rb +4 -0
  55. data/lib/graphql/schema/addition.rb +37 -28
  56. data/lib/graphql/schema/argument.rb +6 -6
  57. data/lib/graphql/schema/build_from_definition.rb +5 -5
  58. data/lib/graphql/schema/directive/feature.rb +1 -1
  59. data/lib/graphql/schema/directive/flagged.rb +2 -2
  60. data/lib/graphql/schema/directive/include.rb +1 -1
  61. data/lib/graphql/schema/directive/skip.rb +1 -1
  62. data/lib/graphql/schema/directive/transform.rb +1 -1
  63. data/lib/graphql/schema/directive.rb +2 -2
  64. data/lib/graphql/schema/enum.rb +57 -9
  65. data/lib/graphql/schema/enum_value.rb +4 -0
  66. data/lib/graphql/schema/field/connection_extension.rb +1 -1
  67. data/lib/graphql/schema/field.rb +92 -17
  68. data/lib/graphql/schema/find_inherited_value.rb +1 -0
  69. data/lib/graphql/schema/finder.rb +5 -5
  70. data/lib/graphql/schema/input_object.rb +6 -5
  71. data/lib/graphql/schema/interface.rb +8 -19
  72. data/lib/graphql/schema/member/accepts_definition.rb +8 -1
  73. data/lib/graphql/schema/member/build_type.rb +0 -4
  74. data/lib/graphql/schema/member/has_arguments.rb +62 -14
  75. data/lib/graphql/schema/member/has_deprecation_reason.rb +1 -1
  76. data/lib/graphql/schema/member/has_fields.rb +76 -18
  77. data/lib/graphql/schema/member/has_interfaces.rb +90 -0
  78. data/lib/graphql/schema/member.rb +1 -0
  79. data/lib/graphql/schema/object.rb +7 -74
  80. data/lib/graphql/schema/printer.rb +1 -1
  81. data/lib/graphql/schema/relay_classic_mutation.rb +29 -3
  82. data/lib/graphql/schema/resolver/has_payload_type.rb +27 -2
  83. data/lib/graphql/schema/resolver.rb +29 -5
  84. data/lib/graphql/schema/subscription.rb +11 -1
  85. data/lib/graphql/schema/type_expression.rb +1 -1
  86. data/lib/graphql/schema/type_membership.rb +18 -4
  87. data/lib/graphql/schema/union.rb +6 -1
  88. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  89. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  90. data/lib/graphql/schema/validator/exclusion_validator.rb +3 -1
  91. data/lib/graphql/schema/validator/format_validator.rb +4 -5
  92. data/lib/graphql/schema/validator/inclusion_validator.rb +3 -1
  93. data/lib/graphql/schema/validator/length_validator.rb +5 -3
  94. data/lib/graphql/schema/validator/numericality_validator.rb +8 -1
  95. data/lib/graphql/schema/validator.rb +36 -25
  96. data/lib/graphql/schema/warden.rb +116 -52
  97. data/lib/graphql/schema.rb +87 -15
  98. data/lib/graphql/static_validation/base_visitor.rb +5 -5
  99. data/lib/graphql/static_validation/definition_dependencies.rb +0 -1
  100. data/lib/graphql/static_validation/error.rb +3 -1
  101. data/lib/graphql/static_validation/literal_validator.rb +1 -1
  102. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  103. data/lib/graphql/static_validation/rules/fields_will_merge.rb +41 -22
  104. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
  105. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -1
  106. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +4 -4
  107. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +7 -7
  108. data/lib/graphql/static_validation/validation_context.rb +2 -1
  109. data/lib/graphql/string_encoding_error.rb +13 -3
  110. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +6 -4
  111. data/lib/graphql/subscriptions/event.rb +65 -13
  112. data/lib/graphql/subscriptions.rb +17 -19
  113. data/lib/graphql/types/int.rb +1 -1
  114. data/lib/graphql/types/relay/has_node_field.rb +1 -1
  115. data/lib/graphql/types/relay/has_nodes_field.rb +1 -1
  116. data/lib/graphql/types/string.rb +1 -1
  117. data/lib/graphql/unauthorized_error.rb +1 -1
  118. data/lib/graphql/version.rb +1 -1
  119. data/lib/graphql.rb +9 -31
  120. metadata +12 -5
@@ -12,9 +12,25 @@ module GraphQL
12
12
  # The value which couldn't be encoded
13
13
  attr_reader :integer_value
14
14
 
15
- def initialize(value)
15
+ # @return [GraphQL::Schema::Field] The field that returned a too-big integer
16
+ attr_reader :field
17
+
18
+ # @return [Array<String, Integer>] Where the field appeared in the GraphQL response
19
+ attr_reader :path
20
+
21
+ def initialize(value, context:)
16
22
  @integer_value = value
17
- super("Integer out of bounds: #{value}. \nConsider using ID or GraphQL::Types::BigInt instead.")
23
+ @field = context[:current_field]
24
+ @path = context[:current_path]
25
+ message = "Integer out of bounds: #{value}".dup
26
+ if @path
27
+ message << " @ #{@path.join(".")}"
28
+ end
29
+ if @field
30
+ message << " (#{@field.path})"
31
+ end
32
+ message << ". Consider using ID or GraphQL::Types::BigInt instead."
33
+ super(message)
18
34
  end
19
35
  end
20
36
  end
@@ -10,7 +10,7 @@ module GraphQL
10
10
  "skipping a field. Directives provide this by describing additional information "\
11
11
  "to the executor."
12
12
  field :name, String, null: false, method: :graphql_name
13
- field :description, String, null: true
13
+ field :description, String
14
14
  field :locations, [GraphQL::Schema::LateBoundType.new("__DirectiveLocation")], null: false
15
15
  field :args, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: false do
16
16
  argument :include_deprecated, Boolean, required: false, default_value: false
@@ -3,8 +3,8 @@ module GraphQL
3
3
  module Introspection
4
4
  class EntryPoints < Introspection::BaseObject
5
5
  field :__schema, GraphQL::Schema::LateBoundType.new("__Schema"), "This GraphQL schema", null: false
6
- field :__type, GraphQL::Schema::LateBoundType.new("__Type"), "A type in the GraphQL system", null: true do
7
- argument :name, String, required: true
6
+ field :__type, GraphQL::Schema::LateBoundType.new("__Type"), "A type in the GraphQL system" do
7
+ argument :name, String
8
8
  end
9
9
 
10
10
  def __schema
@@ -7,9 +7,9 @@ module GraphQL
7
7
  "placeholder for a string or numeric value. However an Enum value is returned in "\
8
8
  "a JSON response as a string."
9
9
  field :name, String, null: false
10
- field :description, String, null: true
10
+ field :description, String
11
11
  field :is_deprecated, Boolean, null: false
12
- field :deprecation_reason, String, null: true
12
+ field :deprecation_reason, String
13
13
 
14
14
  def name
15
15
  object.graphql_name
@@ -6,13 +6,13 @@ module GraphQL
6
6
  description "Object and Interface types are described by a list of Fields, each of which has "\
7
7
  "a name, potentially a list of arguments, and a return type."
8
8
  field :name, String, null: false
9
- field :description, String, null: true
9
+ field :description, String
10
10
  field :args, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: false do
11
11
  argument :include_deprecated, Boolean, required: false, default_value: false
12
12
  end
13
13
  field :type, GraphQL::Schema::LateBoundType.new("__Type"), null: false
14
14
  field :is_deprecated, Boolean, null: false
15
- field :deprecation_reason, String, null: true
15
+ field :deprecation_reason, String
16
16
 
17
17
  def is_deprecated
18
18
  !!@object.deprecation_reason
@@ -7,11 +7,11 @@ module GraphQL
7
7
  "InputObject are represented as Input Values which describe their type and "\
8
8
  "optionally a default value."
9
9
  field :name, String, null: false
10
- field :description, String, null: true
10
+ field :description, String
11
11
  field :type, GraphQL::Schema::LateBoundType.new("__Type"), null: false
12
- field :default_value, String, "A GraphQL-formatted string representing the default value for this input value.", null: true
12
+ field :default_value, String, "A GraphQL-formatted string representing the default value for this input value."
13
13
  field :is_deprecated, Boolean, null: false
14
- field :deprecation_reason, String, null: true
14
+ field :deprecation_reason, String
15
15
 
16
16
  def is_deprecated
17
17
  !!@object.deprecation_reason
@@ -54,7 +54,7 @@ module GraphQL
54
54
  elsif type.kind.input_object?
55
55
  "{" +
56
56
  value.map do |k, v|
57
- arg_defn = type.arguments[k]
57
+ arg_defn = type.get_argument(k, context)
58
58
  "#{k}: #{serialize_default_value(v, arg_defn.type)}"
59
59
  end.join(", ") +
60
60
  "}"
@@ -10,8 +10,8 @@ module GraphQL
10
10
 
11
11
  field :types, [GraphQL::Schema::LateBoundType.new("__Type")], "A list of all types supported by this server.", null: false
12
12
  field :query_type, GraphQL::Schema::LateBoundType.new("__Type"), "The type that query operations will be rooted at.", null: false
13
- field :mutation_type, GraphQL::Schema::LateBoundType.new("__Type"), "If this server supports mutation, the type that mutation operations will be rooted at.", null: true
14
- field :subscription_type, GraphQL::Schema::LateBoundType.new("__Type"), "If this server support subscription, the type that subscription operations will be rooted at.", null: true
13
+ field :mutation_type, GraphQL::Schema::LateBoundType.new("__Type"), "If this server supports mutation, the type that mutation operations will be rooted at."
14
+ field :subscription_type, GraphQL::Schema::LateBoundType.new("__Type"), "If this server support subscription, the type that subscription operations will be rooted at."
15
15
  field :directives, [GraphQL::Schema::LateBoundType.new("__Directive")], "A list of all directives supported by this server.", null: false
16
16
 
17
17
  def types
@@ -12,20 +12,20 @@ module GraphQL
12
12
  "possible at runtime. List and NonNull types compose other types."
13
13
 
14
14
  field :kind, GraphQL::Schema::LateBoundType.new("__TypeKind"), null: false
15
- field :name, String, null: true
16
- field :description, String, null: true
17
- field :fields, [GraphQL::Schema::LateBoundType.new("__Field")], null: true do
15
+ field :name, String
16
+ field :description, String
17
+ field :fields, [GraphQL::Schema::LateBoundType.new("__Field")] do
18
18
  argument :include_deprecated, Boolean, required: false, default_value: false
19
19
  end
20
- field :interfaces, [GraphQL::Schema::LateBoundType.new("__Type")], null: true
21
- field :possible_types, [GraphQL::Schema::LateBoundType.new("__Type")], null: true
22
- field :enum_values, [GraphQL::Schema::LateBoundType.new("__EnumValue")], null: true do
20
+ field :interfaces, [GraphQL::Schema::LateBoundType.new("__Type")]
21
+ field :possible_types, [GraphQL::Schema::LateBoundType.new("__Type")]
22
+ field :enum_values, [GraphQL::Schema::LateBoundType.new("__EnumValue")] do
23
23
  argument :include_deprecated, Boolean, required: false, default_value: false
24
24
  end
25
- field :input_fields, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: true do
25
+ field :input_fields, [GraphQL::Schema::LateBoundType.new("__InputValue")] do
26
26
  argument :include_deprecated, Boolean, required: false, default_value: false
27
27
  end
28
- field :of_type, GraphQL::Schema::LateBoundType.new("__Type"), null: true
28
+ field :of_type, GraphQL::Schema::LateBoundType.new("__Type")
29
29
 
30
30
  def name
31
31
  object.graphql_name
@@ -50,8 +50,8 @@ module GraphQL
50
50
  end
51
51
 
52
52
  def interfaces
53
- if @object.kind == GraphQL::TypeKinds::OBJECT
54
- @context.warden.interfaces(@object)
53
+ if @object.kind.object? || @object.kind.interface?
54
+ @context.warden.interfaces(@object).sort_by(&:graphql_name)
55
55
  else
56
56
  nil
57
57
  end
@@ -2,10 +2,6 @@
2
2
  module GraphQL
3
3
  module Language
4
4
  module BlockString
5
- if !String.method_defined?(:match?)
6
- using GraphQL::StringMatchBackport
7
- end
8
-
9
5
  # Remove leading and trailing whitespace from a block string.
10
6
  # See "Block Strings" in https://github.com/facebook/graphql/blob/master/spec/Section%202%20--%20Language.md
11
7
  def self.trim_whitespace(str)
@@ -34,6 +34,7 @@ module GraphQL
34
34
  schema: @schema,
35
35
  context: schema_context,
36
36
  )
37
+ schema_context.warden = @warden
37
38
  end
38
39
 
39
40
  def document
@@ -87,6 +88,7 @@ module GraphQL
87
88
  def build_interface_type_node(interface_type)
88
89
  GraphQL::Language::Nodes::InterfaceTypeDefinition.new(
89
90
  name: interface_type.graphql_name,
91
+ interfaces: warden.interfaces(interface_type).sort_by(&:graphql_name).map { |type| build_type_name_node(type) },
90
92
  description: interface_type.description,
91
93
  fields: build_field_nodes(warden.fields(interface_type)),
92
94
  directives: directives(interface_type),
@@ -194,7 +196,7 @@ module GraphQL
194
196
  when "INPUT_OBJECT"
195
197
  GraphQL::Language::Nodes::InputObject.new(
196
198
  arguments: default_value.to_h.map do |arg_name, arg_value|
197
- arg_type = type.arguments.fetch(arg_name.to_s).type
199
+ arg_type = @warden.arguments(type).find { |a| a.graphql_name == arg_name.to_s }.type
198
200
  GraphQL::Language::Nodes::Argument.new(
199
201
  name: arg_name.to_s,
200
202
  value: build_default_value(arg_value, arg_type)
@@ -295,7 +297,7 @@ module GraphQL
295
297
  else
296
298
  member.directives.map do |dir|
297
299
  args = []
298
- dir.arguments.argument_values.each_value do |arg_value|
300
+ dir.arguments.argument_values.each_value do |arg_value| # rubocop:disable Development/ContextIsPassedCop -- directive instance method
299
301
  arg_defn = arg_value.definition
300
302
  if arg_defn.default_value? && arg_value.value == arg_defn.default_value
301
303
  next
@@ -3,9 +3,6 @@
3
3
  module GraphQL
4
4
  module Language
5
5
  module Lexer
6
- if !String.method_defined?(:match?)
7
- using GraphQL::StringMatchBackport
8
- end
9
6
 
10
7
  def self.tokenize(query_string)
11
8
  run_lexer(query_string)
@@ -121,10 +121,6 @@
121
121
  module GraphQL
122
122
  module Language
123
123
  module Lexer
124
- if !String.method_defined?(:match?)
125
- using GraphQL::StringMatchBackport
126
- end
127
-
128
124
  def self.tokenize(query_string)
129
125
  run_lexer(query_string)
130
126
  end
@@ -467,7 +467,6 @@ module GraphQL
467
467
  end
468
468
  end
469
469
 
470
-
471
470
  # A list type definition, denoted with `[...]` (used for variable type definitions)
472
471
  class ListType < WrapperType
473
472
  end
@@ -618,6 +617,7 @@ module GraphQL
618
617
  attr_reader :description
619
618
  scalar_methods :name
620
619
  children_methods({
620
+ interfaces: GraphQL::Language::Nodes::TypeName,
621
621
  directives: GraphQL::Language::Nodes::Directive,
622
622
  fields: GraphQL::Language::Nodes::FieldDefinition,
623
623
  })
@@ -627,6 +627,7 @@ module GraphQL
627
627
  class InterfaceTypeExtension < AbstractNode
628
628
  scalar_methods :name
629
629
  children_methods({
630
+ interfaces: GraphQL::Language::Nodes::TypeName,
630
631
  directives: GraphQL::Language::Nodes::Directive,
631
632
  fields: GraphQL::Language::Nodes::FieldDefinition,
632
633
  })