graphql 1.12.10 → 1.13.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/core.rb +3 -1
  3. data/lib/generators/graphql/install_generator.rb +9 -2
  4. data/lib/generators/graphql/mutation_generator.rb +1 -1
  5. data/lib/generators/graphql/object_generator.rb +2 -1
  6. data/lib/generators/graphql/relay.rb +19 -11
  7. data/lib/generators/graphql/templates/schema.erb +14 -2
  8. data/lib/generators/graphql/type_generator.rb +0 -1
  9. data/lib/graphql/analysis/ast/field_usage.rb +28 -1
  10. data/lib/graphql/analysis/ast/query_complexity.rb +10 -14
  11. data/lib/graphql/analysis/ast/visitor.rb +4 -4
  12. data/lib/graphql/backtrace/table.rb +15 -3
  13. data/lib/graphql/backtrace/tracer.rb +7 -4
  14. data/lib/graphql/base_type.rb +4 -2
  15. data/lib/graphql/boolean_type.rb +1 -1
  16. data/lib/graphql/dataloader/null_dataloader.rb +1 -0
  17. data/lib/graphql/dataloader/source.rb +50 -2
  18. data/lib/graphql/dataloader.rb +110 -41
  19. data/lib/graphql/define/instance_definable.rb +1 -1
  20. data/lib/graphql/deprecated_dsl.rb +11 -3
  21. data/lib/graphql/deprecation.rb +1 -5
  22. data/lib/graphql/directive/deprecated_directive.rb +1 -1
  23. data/lib/graphql/directive/include_directive.rb +1 -1
  24. data/lib/graphql/directive/skip_directive.rb +1 -1
  25. data/lib/graphql/directive.rb +0 -4
  26. data/lib/graphql/enum_type.rb +5 -1
  27. data/lib/graphql/execution/errors.rb +1 -0
  28. data/lib/graphql/execution/execute.rb +1 -1
  29. data/lib/graphql/execution/interpreter/arguments.rb +1 -1
  30. data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -4
  31. data/lib/graphql/execution/interpreter/resolve.rb +6 -2
  32. data/lib/graphql/execution/interpreter/runtime.rb +513 -213
  33. data/lib/graphql/execution/interpreter.rb +4 -8
  34. data/lib/graphql/execution/lazy.rb +5 -1
  35. data/lib/graphql/execution/lookahead.rb +2 -2
  36. data/lib/graphql/execution/multiplex.rb +4 -1
  37. data/lib/graphql/float_type.rb +1 -1
  38. data/lib/graphql/id_type.rb +1 -1
  39. data/lib/graphql/int_type.rb +1 -1
  40. data/lib/graphql/integer_encoding_error.rb +18 -2
  41. data/lib/graphql/introspection/directive_type.rb +1 -1
  42. data/lib/graphql/introspection/entry_points.rb +2 -2
  43. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  44. data/lib/graphql/introspection/field_type.rb +2 -2
  45. data/lib/graphql/introspection/input_value_type.rb +10 -4
  46. data/lib/graphql/introspection/schema_type.rb +3 -3
  47. data/lib/graphql/introspection/type_type.rb +10 -10
  48. data/lib/graphql/language/block_string.rb +2 -6
  49. data/lib/graphql/language/document_from_schema_definition.rb +10 -4
  50. data/lib/graphql/language/lexer.rb +0 -3
  51. data/lib/graphql/language/lexer.rl +0 -4
  52. data/lib/graphql/language/nodes.rb +13 -3
  53. data/lib/graphql/language/parser.rb +442 -434
  54. data/lib/graphql/language/parser.y +5 -4
  55. data/lib/graphql/language/printer.rb +6 -1
  56. data/lib/graphql/language/sanitized_printer.rb +5 -5
  57. data/lib/graphql/language/token.rb +0 -4
  58. data/lib/graphql/name_validator.rb +0 -4
  59. data/lib/graphql/pagination/active_record_relation_connection.rb +43 -6
  60. data/lib/graphql/pagination/connections.rb +40 -16
  61. data/lib/graphql/pagination/relation_connection.rb +57 -27
  62. data/lib/graphql/query/arguments.rb +1 -1
  63. data/lib/graphql/query/arguments_cache.rb +1 -1
  64. data/lib/graphql/query/context.rb +15 -2
  65. data/lib/graphql/query/literal_input.rb +1 -1
  66. data/lib/graphql/query/null_context.rb +12 -7
  67. data/lib/graphql/query/serial_execution/field_resolution.rb +1 -1
  68. data/lib/graphql/query/validation_pipeline.rb +1 -1
  69. data/lib/graphql/query/variables.rb +5 -1
  70. data/lib/graphql/query.rb +5 -1
  71. data/lib/graphql/relay/edges_instrumentation.rb +0 -1
  72. data/lib/graphql/relay/global_id_resolve.rb +1 -1
  73. data/lib/graphql/relay/page_info.rb +1 -1
  74. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  75. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  76. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  77. data/lib/graphql/rubocop.rb +4 -0
  78. data/lib/graphql/schema/addition.rb +247 -0
  79. data/lib/graphql/schema/argument.rb +103 -45
  80. data/lib/graphql/schema/build_from_definition.rb +13 -7
  81. data/lib/graphql/schema/directive/feature.rb +1 -1
  82. data/lib/graphql/schema/directive/flagged.rb +2 -2
  83. data/lib/graphql/schema/directive/include.rb +1 -1
  84. data/lib/graphql/schema/directive/skip.rb +1 -1
  85. data/lib/graphql/schema/directive/transform.rb +14 -2
  86. data/lib/graphql/schema/directive.rb +7 -3
  87. data/lib/graphql/schema/enum.rb +70 -11
  88. data/lib/graphql/schema/enum_value.rb +6 -0
  89. data/lib/graphql/schema/field/connection_extension.rb +1 -1
  90. data/lib/graphql/schema/field.rb +243 -81
  91. data/lib/graphql/schema/field_extension.rb +89 -2
  92. data/lib/graphql/schema/find_inherited_value.rb +1 -0
  93. data/lib/graphql/schema/finder.rb +5 -5
  94. data/lib/graphql/schema/input_object.rb +39 -29
  95. data/lib/graphql/schema/interface.rb +11 -20
  96. data/lib/graphql/schema/introspection_system.rb +1 -1
  97. data/lib/graphql/schema/list.rb +3 -1
  98. data/lib/graphql/schema/member/accepts_definition.rb +15 -3
  99. data/lib/graphql/schema/member/build_type.rb +1 -4
  100. data/lib/graphql/schema/member/cached_graphql_definition.rb +29 -2
  101. data/lib/graphql/schema/member/has_arguments.rb +145 -57
  102. data/lib/graphql/schema/member/has_deprecation_reason.rb +1 -1
  103. data/lib/graphql/schema/member/has_fields.rb +76 -18
  104. data/lib/graphql/schema/member/has_interfaces.rb +90 -0
  105. data/lib/graphql/schema/member.rb +1 -0
  106. data/lib/graphql/schema/non_null.rb +7 -1
  107. data/lib/graphql/schema/object.rb +10 -75
  108. data/lib/graphql/schema/printer.rb +12 -17
  109. data/lib/graphql/schema/relay_classic_mutation.rb +37 -3
  110. data/lib/graphql/schema/resolver/has_payload_type.rb +27 -2
  111. data/lib/graphql/schema/resolver.rb +75 -65
  112. data/lib/graphql/schema/scalar.rb +2 -0
  113. data/lib/graphql/schema/subscription.rb +36 -8
  114. data/lib/graphql/schema/traversal.rb +1 -1
  115. data/lib/graphql/schema/type_expression.rb +1 -1
  116. data/lib/graphql/schema/type_membership.rb +18 -4
  117. data/lib/graphql/schema/union.rb +8 -1
  118. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  119. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  120. data/lib/graphql/schema/validator/exclusion_validator.rb +3 -1
  121. data/lib/graphql/schema/validator/format_validator.rb +4 -5
  122. data/lib/graphql/schema/validator/inclusion_validator.rb +3 -1
  123. data/lib/graphql/schema/validator/length_validator.rb +5 -3
  124. data/lib/graphql/schema/validator/numericality_validator.rb +13 -2
  125. data/lib/graphql/schema/validator/required_validator.rb +29 -15
  126. data/lib/graphql/schema/validator.rb +33 -25
  127. data/lib/graphql/schema/warden.rb +116 -52
  128. data/lib/graphql/schema.rb +162 -227
  129. data/lib/graphql/static_validation/all_rules.rb +1 -0
  130. data/lib/graphql/static_validation/base_visitor.rb +8 -5
  131. data/lib/graphql/static_validation/definition_dependencies.rb +0 -1
  132. data/lib/graphql/static_validation/error.rb +3 -1
  133. data/lib/graphql/static_validation/literal_validator.rb +1 -1
  134. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  135. data/lib/graphql/static_validation/rules/fields_will_merge.rb +52 -26
  136. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
  137. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
  138. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  139. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  140. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +3 -1
  141. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +4 -4
  142. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +13 -7
  143. data/lib/graphql/static_validation/validation_context.rb +8 -2
  144. data/lib/graphql/static_validation/validator.rb +15 -12
  145. data/lib/graphql/string_encoding_error.rb +13 -3
  146. data/lib/graphql/string_type.rb +1 -1
  147. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +36 -6
  148. data/lib/graphql/subscriptions/event.rb +68 -31
  149. data/lib/graphql/subscriptions/serialize.rb +23 -3
  150. data/lib/graphql/subscriptions.rb +17 -19
  151. data/lib/graphql/tracing/active_support_notifications_tracing.rb +6 -20
  152. data/lib/graphql/tracing/appsignal_tracing.rb +15 -0
  153. data/lib/graphql/tracing/notifications_tracing.rb +59 -0
  154. data/lib/graphql/types/big_int.rb +5 -1
  155. data/lib/graphql/types/int.rb +1 -1
  156. data/lib/graphql/types/relay/connection_behaviors.rb +26 -9
  157. data/lib/graphql/types/relay/default_relay.rb +5 -1
  158. data/lib/graphql/types/relay/edge_behaviors.rb +13 -2
  159. data/lib/graphql/types/relay/has_node_field.rb +2 -2
  160. data/lib/graphql/types/relay/has_nodes_field.rb +2 -2
  161. data/lib/graphql/types/relay/node_field.rb +15 -4
  162. data/lib/graphql/types/relay/nodes_field.rb +14 -4
  163. data/lib/graphql/types/string.rb +1 -1
  164. data/lib/graphql/unauthorized_error.rb +1 -1
  165. data/lib/graphql/version.rb +1 -1
  166. data/lib/graphql.rb +10 -28
  167. data/readme.md +1 -4
  168. metadata +17 -21
  169. data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
@@ -4,7 +4,6 @@ require "graphql/execution/interpreter/argument_value"
4
4
  require "graphql/execution/interpreter/arguments"
5
5
  require "graphql/execution/interpreter/arguments_cache"
6
6
  require "graphql/execution/interpreter/execution_errors"
7
- require "graphql/execution/interpreter/hash_response"
8
7
  require "graphql/execution/interpreter/runtime"
9
8
  require "graphql/execution/interpreter/resolve"
10
9
  require "graphql/execution/interpreter/handles_raw_value"
@@ -19,7 +18,7 @@ module GraphQL
19
18
  def execute(_operation, _root_type, query)
20
19
  runtime = evaluate(query)
21
20
  sync_lazies(query: query)
22
- runtime.final_value
21
+ runtime.final_result
23
22
  end
24
23
 
25
24
  def self.use(schema_class)
@@ -57,7 +56,7 @@ module GraphQL
57
56
 
58
57
  def self.finish_query(query, _multiplex)
59
58
  {
60
- "data" => query.context.namespace(:interpreter)[:runtime].final_value
59
+ "data" => query.context.namespace(:interpreter)[:runtime].final_result
61
60
  }
62
61
  end
63
62
 
@@ -67,10 +66,7 @@ module GraphQL
67
66
  # Although queries in a multiplex _share_ an Interpreter instance,
68
67
  # they also have another item of state, which is private to that query
69
68
  # in particular, assign it here:
70
- runtime = Runtime.new(
71
- query: query,
72
- response: HashResponse.new,
73
- )
69
+ runtime = Runtime.new(query: query)
74
70
  query.context.namespace(:interpreter)[:runtime] = runtime
75
71
 
76
72
  query.trace("execute_query", {query: query}) do
@@ -91,7 +87,7 @@ module GraphQL
91
87
  final_values = queries.map do |query|
92
88
  runtime = query.context.namespace(:interpreter)[:runtime]
93
89
  # it might not be present if the query has an error
94
- runtime ? runtime.final_value : nil
90
+ runtime ? runtime.final_result : nil
95
91
  end
96
92
  final_values.compact!
97
93
  tracer.trace("execute_query_lazy", {multiplex: multiplex, query: query}) do
@@ -48,7 +48,11 @@ module GraphQL
48
48
  end
49
49
  end
50
50
 
51
- if @value.is_a?(StandardError)
51
+ # `SKIP` was made into a subclass of `GraphQL::Error` to improve runtime performance
52
+ # (fewer clauses in a hot `case` block), but now it requires special handling here.
53
+ # I think it's still worth it for the performance win, but if the number of special
54
+ # cases grows, then maybe it's worth rethinking somehow.
55
+ if @value.is_a?(StandardError) && @value != GraphQL::Execution::Execute::SKIP
52
56
  raise @value
53
57
  else
54
58
  @value
@@ -254,14 +254,14 @@ module GraphQL
254
254
  subselections_on_type = selections_on_type
255
255
  if (t = ast_selection.type)
256
256
  # Assuming this is valid, that `t` will be found.
257
- on_type = @query.schema.get_type(t.name).type_class
257
+ on_type = @query.get_type(t.name).type_class
258
258
  subselections_on_type = subselections_by_type[on_type] ||= {}
259
259
  end
260
260
  find_selections(subselections_by_type, subselections_on_type, on_type, ast_selection.selections, arguments)
261
261
  when GraphQL::Language::Nodes::FragmentSpread
262
262
  frag_defn = @query.fragments[ast_selection.name] || raise("Invariant: Can't look ahead to nonexistent fragment #{ast_selection.name} (found: #{@query.fragments.keys})")
263
263
  # Again, assuming a valid AST
264
- on_type = @query.schema.get_type(frag_defn.type.name).type_class
264
+ on_type = @query.get_type(frag_defn.type.name).type_class
265
265
  subselections_on_type = subselections_by_type[on_type] ||= {}
266
266
  find_selections(subselections_by_type, subselections_on_type, on_type, frag_defn.selections, arguments)
267
267
  else
@@ -35,7 +35,7 @@ module GraphQL
35
35
  @queries = queries
36
36
  @queries.each { |q| q.multiplex = self }
37
37
  @context = context
38
- @context[:dataloader] = @dataloader = @schema.dataloader_class.new
38
+ @dataloader = @context[:dataloader] ||= @schema.dataloader_class.new
39
39
  @tracers = schema.tracers + (context[:tracers] || [])
40
40
  # Support `context: {backtrace: true}`
41
41
  if context[:backtrace] && !@tracers.include?(GraphQL::Backtrace::Tracer)
@@ -151,6 +151,9 @@ module GraphQL
151
151
 
152
152
  result
153
153
  end
154
+ if query.context.namespace?(:__query_result_extensions__)
155
+ query.result_values["extensions"] = query.context.namespace(:__query_result_extensions__)
156
+ end
154
157
  end
155
158
 
156
159
  # use the old `query_execution_strategy` etc to run this query
@@ -1,2 +1,2 @@
1
1
  # frozen_string_literal: true
2
- GraphQL::FLOAT_TYPE = GraphQL::Types::Float.graphql_definition
2
+ GraphQL::FLOAT_TYPE = GraphQL::Types::Float.graphql_definition(silence_deprecation_warning: true)
@@ -1,2 +1,2 @@
1
1
  # frozen_string_literal: true
2
- GraphQL::ID_TYPE = GraphQL::Types::ID.graphql_definition
2
+ GraphQL::ID_TYPE = GraphQL::Types::ID.graphql_definition(silence_deprecation_warning: true)
@@ -1,2 +1,2 @@
1
1
  # frozen_string_literal: true
2
- GraphQL::INT_TYPE = GraphQL::Types::Int.graphql_definition
2
+ GraphQL::INT_TYPE = GraphQL::Types::Int.graphql_definition(silence_deprecation_warning: true)
@@ -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
@@ -23,6 +23,12 @@ module GraphQL
23
23
  if value.nil?
24
24
  'null'
25
25
  else
26
+ if (@object.type.kind.list? || (@object.type.kind.non_null? && @object.type.of_type.kind.list?)) && !value.respond_to?(:map)
27
+ # This is a bit odd -- we expect the default value to be an application-style value, so we use coerce result below.
28
+ # But coerce_result doesn't wrap single-item lists, which are valid inputs to list types.
29
+ # So, apply that wrapper here if needed.
30
+ value = [value]
31
+ end
26
32
  coerced_default_value = @object.type.coerce_result(value, @context)
27
33
  serialize_default_value(coerced_default_value, @object.type)
28
34
  end
@@ -48,7 +54,7 @@ module GraphQL
48
54
  elsif type.kind.input_object?
49
55
  "{" +
50
56
  value.map do |k, v|
51
- arg_defn = type.arguments[k]
57
+ arg_defn = type.get_argument(k, context)
52
58
  "#{k}: #{serialize_default_value(v, arg_defn.type)}"
53
59
  end.join(", ") +
54
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
@@ -31,7 +31,7 @@ module GraphQL
31
31
  end
32
32
 
33
33
  def directives
34
- context.schema.directives.values
34
+ @context.warden.directives
35
35
  end
36
36
 
37
37
  private
@@ -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,16 +2,12 @@
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)
12
8
  # Early return for the most common cases:
13
9
  if str == ""
14
- return ""
10
+ return "".dup
15
11
  elsif !(has_newline = str.include?("\n")) && !(str.start_with?(" "))
16
12
  return str
17
13
  end
@@ -59,7 +55,7 @@ module GraphQL
59
55
  end
60
56
 
61
57
  # Rebuild the string
62
- lines.size > 1 ? lines.join("\n") : (lines.first || "")
58
+ lines.size > 1 ? lines.join("\n") : (lines.first || "".dup)
63
59
  end
64
60
 
65
61
  def self.print(str, indent: '')
@@ -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,10 +196,14 @@ 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
+ args = @warden.arguments(type)
200
+ arg = args.find { |a| a.keyword.to_s == arg_name.to_s }
201
+ if arg.nil?
202
+ raise ArgumentError, "No argument definition on #{type.graphql_name} for argument: #{arg_name.inspect} (expected one of: #{args.map(&:keyword)})"
203
+ end
198
204
  GraphQL::Language::Nodes::Argument.new(
199
- name: arg_name.to_s,
200
- value: build_default_value(arg_value, arg_type)
205
+ name: arg.graphql_name.to_s,
206
+ value: build_default_value(arg_value, arg.type)
201
207
  )
202
208
  end
203
209
  )
@@ -295,7 +301,7 @@ module GraphQL
295
301
  else
296
302
  member.directives.map do |dir|
297
303
  args = []
298
- dir.arguments.argument_values.each_value do |arg_value|
304
+ dir.arguments.argument_values.each_value do |arg_value| # rubocop:disable Development/ContextIsPassedCop -- directive instance method
299
305
  arg_defn = arg_value.definition
300
306
  if arg_defn.default_value? && arg_value.value == arg_defn.default_value
301
307
  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
@@ -197,7 +197,16 @@ module GraphQL
197
197
  else
198
198
  module_eval <<-RUBY, __FILE__, __LINE__
199
199
  def children
200
- @children ||= (#{children_of_type.keys.map { |k| "@#{k}" }.join(" + ")}).freeze
200
+ @children ||= begin
201
+ if #{children_of_type.keys.map { |k| "@#{k}.any?" }.join(" || ")}
202
+ new_children = []
203
+ #{children_of_type.keys.map { |k| "new_children.concat(@#{k})" }.join("; ")}
204
+ new_children.freeze
205
+ new_children
206
+ else
207
+ NO_CHILDREN
208
+ end
209
+ end
201
210
  end
202
211
  RUBY
203
212
  end
@@ -332,7 +341,7 @@ module GraphQL
332
341
  # end
333
342
  # end
334
343
  #
335
- # document.to_query_string(printer: VariableSrubber.new)
344
+ # document.to_query_string(printer: VariableScrubber.new)
336
345
  #
337
346
  class Document < AbstractNode
338
347
  scalar_methods false
@@ -467,7 +476,6 @@ module GraphQL
467
476
  end
468
477
  end
469
478
 
470
-
471
479
  # A list type definition, denoted with `[...]` (used for variable type definitions)
472
480
  class ListType < WrapperType
473
481
  end
@@ -618,6 +626,7 @@ module GraphQL
618
626
  attr_reader :description
619
627
  scalar_methods :name
620
628
  children_methods({
629
+ interfaces: GraphQL::Language::Nodes::TypeName,
621
630
  directives: GraphQL::Language::Nodes::Directive,
622
631
  fields: GraphQL::Language::Nodes::FieldDefinition,
623
632
  })
@@ -627,6 +636,7 @@ module GraphQL
627
636
  class InterfaceTypeExtension < AbstractNode
628
637
  scalar_methods :name
629
638
  children_methods({
639
+ interfaces: GraphQL::Language::Nodes::TypeName,
630
640
  directives: GraphQL::Language::Nodes::Directive,
631
641
  fields: GraphQL::Language::Nodes::FieldDefinition,
632
642
  })