graphql 1.9.21 → 1.10.0.pre1

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 (125) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/core.rb +0 -1
  3. data/lib/generators/graphql/install_generator.rb +0 -1
  4. data/lib/generators/graphql/mutation_generator.rb +1 -1
  5. data/lib/generators/graphql/templates/base_field.erb +4 -0
  6. data/lib/generators/graphql/templates/graphql_controller.erb +0 -5
  7. data/lib/generators/graphql/templates/mutation.erb +1 -1
  8. data/lib/generators/graphql/templates/schema.erb +1 -1
  9. data/lib/graphql.rb +1 -11
  10. data/lib/graphql/analysis/ast.rb +2 -2
  11. data/lib/graphql/analysis/ast/analyzer.rb +4 -23
  12. data/lib/graphql/analysis/ast/max_query_complexity.rb +3 -3
  13. data/lib/graphql/analysis/ast/max_query_depth.rb +3 -7
  14. data/lib/graphql/analysis/ast/query_complexity.rb +2 -2
  15. data/lib/graphql/argument.rb +6 -2
  16. data/lib/graphql/backtrace/table.rb +10 -2
  17. data/lib/graphql/base_type.rb +5 -1
  18. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +5 -9
  19. data/lib/graphql/define/assign_object_field.rb +2 -2
  20. data/lib/graphql/define/defined_object_proxy.rb +0 -3
  21. data/lib/graphql/define/instance_definable.rb +3 -14
  22. data/lib/graphql/enum_type.rb +4 -0
  23. data/lib/graphql/execution/directive_checks.rb +2 -2
  24. data/lib/graphql/execution/errors.rb +14 -15
  25. data/lib/graphql/execution/execute.rb +1 -1
  26. data/lib/graphql/execution/interpreter/runtime.rb +17 -39
  27. data/lib/graphql/execution/multiplex.rb +3 -3
  28. data/lib/graphql/field.rb +8 -0
  29. data/lib/graphql/filter.rb +1 -1
  30. data/lib/graphql/function.rb +1 -1
  31. data/lib/graphql/input_object_type.rb +1 -2
  32. data/lib/graphql/introspection/entry_points.rb +1 -2
  33. data/lib/graphql/introspection/input_value_type.rb +27 -9
  34. data/lib/graphql/introspection/schema_type.rb +1 -2
  35. data/lib/graphql/language/block_string.rb +2 -2
  36. data/lib/graphql/language/document_from_schema_definition.rb +5 -11
  37. data/lib/graphql/language/lexer.rb +48 -49
  38. data/lib/graphql/language/lexer.rl +48 -49
  39. data/lib/graphql/language/nodes.rb +11 -14
  40. data/lib/graphql/language/parser.rb +645 -650
  41. data/lib/graphql/language/parser.y +7 -8
  42. data/lib/graphql/language/token.rb +1 -1
  43. data/lib/graphql/non_null_type.rb +0 -10
  44. data/lib/graphql/pagination.rb +6 -0
  45. data/lib/graphql/pagination/active_record_relation_connection.rb +35 -0
  46. data/lib/graphql/pagination/array_connection.rb +78 -0
  47. data/lib/graphql/pagination/connection.rb +150 -0
  48. data/lib/graphql/pagination/connections.rb +103 -0
  49. data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
  50. data/lib/graphql/pagination/relation_connection.rb +157 -0
  51. data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
  52. data/lib/graphql/query.rb +1 -7
  53. data/lib/graphql/query/arguments.rb +3 -9
  54. data/lib/graphql/query/context.rb +9 -31
  55. data/lib/graphql/query/literal_input.rb +29 -10
  56. data/lib/graphql/query/null_context.rb +0 -4
  57. data/lib/graphql/query/variable_validation_error.rb +1 -1
  58. data/lib/graphql/query/variables.rb +2 -4
  59. data/lib/graphql/relay/base_connection.rb +7 -3
  60. data/lib/graphql/relay/edges_instrumentation.rb +1 -1
  61. data/lib/graphql/relay/node.rb +2 -2
  62. data/lib/graphql/relay/relation_connection.rb +5 -9
  63. data/lib/graphql/schema.rb +27 -68
  64. data/lib/graphql/schema/argument.rb +31 -5
  65. data/lib/graphql/schema/base_64_bp.rb +2 -3
  66. data/lib/graphql/schema/build_from_definition.rb +113 -179
  67. data/lib/graphql/schema/build_from_definition/resolve_map.rb +10 -4
  68. data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
  69. data/lib/graphql/schema/directive.rb +6 -7
  70. data/lib/graphql/schema/directive/feature.rb +1 -1
  71. data/lib/graphql/schema/enum.rb +1 -0
  72. data/lib/graphql/schema/enum_value.rb +4 -1
  73. data/lib/graphql/schema/field.rb +37 -39
  74. data/lib/graphql/schema/field/connection_extension.rb +11 -1
  75. data/lib/graphql/schema/input_object.rb +2 -5
  76. data/lib/graphql/schema/interface.rb +2 -0
  77. data/lib/graphql/schema/introspection_system.rb +1 -4
  78. data/lib/graphql/schema/loader.rb +6 -12
  79. data/lib/graphql/schema/member.rb +2 -0
  80. data/lib/graphql/schema/member/base_dsl_methods.rb +2 -2
  81. data/lib/graphql/schema/member/build_type.rb +4 -0
  82. data/lib/graphql/schema/member/cached_graphql_definition.rb +5 -0
  83. data/lib/graphql/schema/member/has_ast_node.rb +17 -0
  84. data/lib/graphql/schema/member/has_fields.rb +10 -16
  85. data/lib/graphql/schema/member/instrumentation.rb +1 -6
  86. data/lib/graphql/schema/member/type_system_helpers.rb +1 -1
  87. data/lib/graphql/schema/mutation.rb +1 -1
  88. data/lib/graphql/schema/object.rb +5 -6
  89. data/lib/graphql/schema/possible_types.rb +3 -3
  90. data/lib/graphql/schema/printer.rb +1 -3
  91. data/lib/graphql/schema/relay_classic_mutation.rb +2 -6
  92. data/lib/graphql/schema/resolver.rb +5 -35
  93. data/lib/graphql/schema/scalar.rb +1 -0
  94. data/lib/graphql/schema/subscription.rb +6 -6
  95. data/lib/graphql/schema/timeout_middleware.rb +2 -3
  96. data/lib/graphql/schema/type_expression.rb +27 -17
  97. data/lib/graphql/schema/union.rb +7 -26
  98. data/lib/graphql/schema/validation.rb +1 -17
  99. data/lib/graphql/schema/warden.rb +3 -77
  100. data/lib/graphql/schema/wrapper.rb +1 -1
  101. data/lib/graphql/static_validation/definition_dependencies.rb +12 -21
  102. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +9 -4
  103. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +10 -7
  104. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +1 -1
  105. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -5
  106. data/lib/graphql/static_validation/rules/fields_will_merge.rb +4 -4
  107. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +3 -3
  108. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +3 -3
  109. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +5 -6
  110. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  111. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +1 -1
  112. data/lib/graphql/subscriptions.rb +7 -7
  113. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +2 -2
  114. data/lib/graphql/subscriptions/event.rb +5 -19
  115. data/lib/graphql/subscriptions/instrumentation.rb +9 -4
  116. data/lib/graphql/subscriptions/subscription_root.rb +2 -10
  117. data/lib/graphql/tracing/skylight_tracing.rb +0 -1
  118. data/lib/graphql/types/int.rb +1 -1
  119. data/lib/graphql/types/relay/base_connection.rb +3 -1
  120. data/lib/graphql/union_type.rb +23 -58
  121. data/lib/graphql/upgrader/member.rb +1 -1
  122. data/lib/graphql/version.rb +1 -1
  123. metadata +20 -13
  124. data/lib/generators/graphql/templates/base_mutation.erb +0 -8
  125. data/lib/graphql/schema/type_membership.rb +0 -34
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7cc71a5ff7b742541447b08e62f4b0561ae2b7ae3767d9b18000e0cfdcd411a1
4
- data.tar.gz: decb826d15ed416571e152b108698a326803cadf45cc78d9a823344bc156b3f4
3
+ metadata.gz: 6d8cd9472c04900ca59a46d06eedf501e09d1f0561a5df1c902faada7c9536df
4
+ data.tar.gz: 409d5ef50405fe5f6ca2f1c197e9c98696c3b89bbf35323e325e7a4bc157419c
5
5
  SHA512:
6
- metadata.gz: ef0ce5989f626b9907fd77c0c54dd42f695e4484236da24f689a160fc521614d7cdc9600f0c9044c2e3b547afc1d862efa23da45b2bc13b0173f3c3af2683059
7
- data.tar.gz: e45810e9c2e0f885e42bfe90c4daf9383e0860543ac9a6ecf6215f994b7af43c0d8d46b74da78a43f9159e3c9fe3882c5ac97257f67a5272407eb6f9b80bbe87
6
+ metadata.gz: '0511959efa6a890699def5ea1d681ed9000435903f078955ecdf0a4f4c1be409ea542cd8e8b9cced7f22e22df49115038bbb544d611b9f66a6fdb5ae75c92566'
7
+ data.tar.gz: cb29aa9f21e13c65d4b700720cd2079968f6f6b709712e464133f78c383841c219c24bce7a5ffe6b6dd6577c6e7c03f282f259dca73896b669d2cfcaaa072abe
@@ -25,7 +25,6 @@ module Graphql
25
25
 
26
26
  def create_mutation_root_type
27
27
  create_dir("#{options[:directory]}/mutations")
28
- template("base_mutation.erb", "#{options[:directory]}/mutations/base_mutation.rb", { skip: true })
29
28
  template("mutation_type.erb", "#{options[:directory]}/types/mutation_type.rb", { skip: true })
30
29
  insert_root_type('mutation', 'MutationType')
31
30
  end
@@ -24,7 +24,6 @@ module Graphql
24
24
  # - query_type.rb
25
25
  # - loaders/
26
26
  # - mutations/
27
- # - base_mutation.rb
28
27
  # - {app_name}_schema.rb
29
28
  # ```
30
29
  #
@@ -45,7 +45,7 @@ module Graphql
45
45
  private
46
46
 
47
47
  def assign_names!(name)
48
- @field_name = name.camelize.underscore
48
+ @field_name = name.camelize(:lower)
49
49
  @mutation_name = name.camelize(:upper)
50
50
  @file_name = name.camelize.underscore
51
51
  end
@@ -1,5 +1,9 @@
1
1
  module Types
2
2
  class BaseField < GraphQL::Schema::Field
3
3
  argument_class Types::BaseArgument
4
+
5
+ def resolve_field(obj, args, ctx)
6
+ resolve(obj, args, ctx)
7
+ end
4
8
  end
5
9
  end
@@ -1,9 +1,4 @@
1
1
  class GraphqlController < ApplicationController
2
- # If accessing from outside this domain, nullify the session
3
- # This allows for outside API access while preventing CSRF attacks,
4
- # but you'll have to authenticate your user separately
5
- # protect_from_forgery with: :null_session
6
-
7
2
  def execute
8
3
  variables = ensure_hash(params[:variables])
9
4
  query = params[:query]
@@ -1,5 +1,5 @@
1
1
  module Mutations
2
- class <%= mutation_name %> < BaseMutation
2
+ class <%= mutation_name %> < GraphQL::Schema::RelayClassicMutation
3
3
  # TODO: define return fields
4
4
  # field :post, Types::PostType, null: false
5
5
 
@@ -24,7 +24,7 @@ class <%= schema_name %> < GraphQL::Schema
24
24
  def self.resolve_type(type, obj, ctx)
25
25
  # TODO: Implement this function
26
26
  # to return the correct type for `obj`
27
- raise(GraphQL::RequiredImplementationMissingError)
27
+ raise(NotImplementedError)
28
28
  end
29
29
  <% end %><% if options[:batch] %>
30
30
  # GraphQL::Batch setup:
@@ -7,20 +7,9 @@ require "forwardable"
7
7
  require_relative "./graphql/railtie" if defined? Rails::Railtie
8
8
 
9
9
  module GraphQL
10
- # forwards-compat for argument handling
11
- module Ruby2Keywords
12
- if RUBY_VERSION < "2.7"
13
- def ruby2_keywords(*)
14
- end
15
- end
16
- end
17
-
18
10
  class Error < StandardError
19
11
  end
20
12
 
21
- class RequiredImplementationMissingError < Error
22
- end
23
-
24
13
  # Turn a query string or schema definition into an AST
25
14
  # @param graphql_string [String] a GraphQL query string or schema definition
26
15
  # @return [GraphQL::Language::Nodes::Document]
@@ -131,3 +120,4 @@ require "graphql/authorization"
131
120
  require "graphql/unauthorized_error"
132
121
  require "graphql/unauthorized_field_error"
133
122
  require "graphql/load_application_object_failed_error"
123
+ require "graphql/pagination"
@@ -23,7 +23,7 @@ module GraphQL
23
23
  #
24
24
  # @param multiplex [GraphQL::Execution::Multiplex]
25
25
  # @param analyzers [Array<GraphQL::Analysis::AST::Analyzer>]
26
- # @return [Array<Any>] Results from multiplex analyzers
26
+ # @return [void]
27
27
  def analyze_multiplex(multiplex, analyzers)
28
28
  multiplex_analyzers = analyzers.map { |analyzer| analyzer.new(multiplex) }
29
29
 
@@ -46,8 +46,8 @@ module GraphQL
46
46
  multiplex.queries.each_with_index do |query, idx|
47
47
  query.analysis_errors = multiplex_errors + analysis_errors(query_results[idx])
48
48
  end
49
- multiplex_results
50
49
  end
50
+ nil
51
51
  end
52
52
 
53
53
  # @param query [GraphQL::Query]
@@ -5,21 +5,10 @@ module GraphQL
5
5
  # Query analyzer for query ASTs. Query analyzers respond to visitor style methods
6
6
  # but are prefixed by `enter` and `leave`.
7
7
  #
8
- # When an analyzer is initialized with a Multiplex, you can always get the current query from
9
- # `visitor.query` in the visit methods.
10
- #
11
- # @param [GraphQL::Query, GraphQL::Execution::Multiplex] The query or multiplex to analyze
8
+ # @param [GraphQL::Query] The query to analyze
12
9
  class Analyzer
13
- def initialize(subject)
14
- @subject = subject
15
-
16
- if subject.is_a?(GraphQL::Query)
17
- @query = subject
18
- @multiplex = nil
19
- else
20
- @multiplex = subject
21
- @query = nil
22
- end
10
+ def initialize(query)
11
+ @query = query
23
12
  end
24
13
 
25
14
  # Analyzer hook to decide at analysis time whether a query should
@@ -33,7 +22,7 @@ module GraphQL
33
22
  # in a query error.
34
23
  # @return [Any] The analyzer result
35
24
  def result
36
- raise GraphQL::RequiredImplementationMissingError
25
+ raise NotImplementedError
37
26
  end
38
27
 
39
28
  class << self
@@ -69,15 +58,7 @@ module GraphQL
69
58
 
70
59
  protected
71
60
 
72
- # @return [GraphQL::Query, GraphQL::Execution::Multiplex] Whatever this analyzer is analyzing
73
- attr_reader :subject
74
-
75
- # @return [GraphQL::Query, nil] `nil` if this analyzer is visiting a multiplex
76
- # (When this is `nil`, use `visitor.query` inside visit methods to get the current query)
77
61
  attr_reader :query
78
-
79
- # @return [GraphQL::Execution::Multiplex, nil] `nil` if this analyzer is visiting a query
80
- attr_reader :multiplex
81
62
  end
82
63
  end
83
64
  end
@@ -7,12 +7,12 @@ module GraphQL
7
7
  # see {Schema#max_complexity} and {Query#max_complexity}
8
8
  class MaxQueryComplexity < QueryComplexity
9
9
  def result
10
- return if subject.max_complexity.nil?
10
+ return if query.max_complexity.nil?
11
11
 
12
12
  total_complexity = max_possible_complexity
13
13
 
14
- if total_complexity > subject.max_complexity
15
- GraphQL::AnalysisError.new("Query has complexity of #{total_complexity}, which exceeds max complexity of #{subject.max_complexity}")
14
+ if total_complexity > query.max_complexity
15
+ GraphQL::AnalysisError.new("Query has complexity of #{total_complexity}, which exceeds max complexity of #{query.max_complexity}")
16
16
  else
17
17
  nil
18
18
  end
@@ -4,14 +4,10 @@ module GraphQL
4
4
  module AST
5
5
  class MaxQueryDepth < QueryDepth
6
6
  def result
7
- configured_max_depth = if query
8
- query.max_depth
9
- else
10
- multiplex.schema.max_depth
11
- end
7
+ return unless query.max_depth
12
8
 
13
- if configured_max_depth && @max_depth > configured_max_depth
14
- GraphQL::AnalysisError.new("Query has depth of #{@max_depth}, which exceeds max depth of #{configured_max_depth}")
9
+ if @max_depth > query.max_depth
10
+ GraphQL::AnalysisError.new("Query has depth of #{@max_depth}, which exceeds max depth of #{query.max_depth}")
15
11
  else
16
12
  nil
17
13
  end
@@ -42,7 +42,7 @@ module GraphQL
42
42
  if @complexities_on_type.last.is_a?(AbstractTypeComplexity)
43
43
  key = selection_key(visitor.response_path, visitor.query)
44
44
  parent_type = visitor.parent_type_definition
45
- visitor.query.possible_types(parent_type).each do |type|
45
+ query.possible_types(parent_type).each do |type|
46
46
  @complexities_on_type.last.merge(type, key, own_complexity)
47
47
  end
48
48
  else
@@ -74,7 +74,7 @@ module GraphQL
74
74
 
75
75
  case defined_complexity
76
76
  when Proc
77
- defined_complexity.call(visitor.query.context, arguments, child_complexity)
77
+ defined_complexity.call(query.context, arguments, child_complexity)
78
78
  when Numeric
79
79
  defined_complexity + (child_complexity || 0)
80
80
  else
@@ -113,6 +113,10 @@ module GraphQL
113
113
  @prepare_proc = BackwardsCompatibility.wrap_arity(prepare_proc, from: 1, to: 2, name: "Argument#prepare(value, ctx)")
114
114
  end
115
115
 
116
+ def type_class
117
+ metadata[:type_class]
118
+ end
119
+
116
120
  NO_DEFAULT_VALUE = Object.new
117
121
  # @api private
118
122
  def self.from_dsl(name, type_or_argument = nil, description = nil, default_value: NO_DEFAULT_VALUE, as: nil, prepare: DefaultPrepare, **kwargs, &block)
@@ -134,9 +138,9 @@ module GraphQL
134
138
  end
135
139
 
136
140
  if type_or_argument.is_a?(GraphQL::Argument)
137
- type_or_argument.redefine(**kwargs, &block)
141
+ type_or_argument.redefine(kwargs, &block)
138
142
  else
139
- GraphQL::Argument.define(**kwargs, &block)
143
+ GraphQL::Argument.define(kwargs, &block)
140
144
  end
141
145
  end
142
146
 
@@ -84,10 +84,14 @@ module GraphQL
84
84
  field_name = "#{ctx.irep_node.owner_type.name}.#{ctx.field.name}"
85
85
  position = "#{ctx.ast_node.line}:#{ctx.ast_node.col}"
86
86
  field_alias = ctx.ast_node.alias
87
+ object = ctx.object
88
+ if object.is_a?(GraphQL::Schema::Object)
89
+ object = object.object
90
+ end
87
91
  rows << [
88
92
  "#{position}",
89
93
  "#{field_name}#{field_alias ? " as #{field_alias}" : ""}",
90
- "#{ctx.object.inspect}",
94
+ "#{object.inspect}",
91
95
  ctx.irep_node.arguments.to_h.inspect,
92
96
  Backtrace::InspectResult.inspect_result(top && @override_value ? @override_value : ctx.value),
93
97
  ]
@@ -104,10 +108,14 @@ module GraphQL
104
108
  position = "?:?"
105
109
  end
106
110
  op_name = query.selected_operation_name
111
+ object = query.root_value
112
+ if object.is_a?(GraphQL::Schema::Object)
113
+ object = object.object
114
+ end
107
115
  rows << [
108
116
  "#{position}",
109
117
  "#{op_type}#{op_name ? " #{op_name}" : ""}",
110
- "#{query.root_value.inspect}",
118
+ "#{object.inspect}",
111
119
  query.variables.to_h.inspect,
112
120
  Backtrace::InspectResult.inspect_result(query.context.value),
113
121
  ]
@@ -43,6 +43,10 @@ module GraphQL
43
43
  # @see {GraphQL::SchemaMember}
44
44
  alias :graphql_definition :itself
45
45
 
46
+ def type_class
47
+ metadata[:type_class]
48
+ end
49
+
46
50
  def name=(name)
47
51
  GraphQL::NameValidator.validate!(name)
48
52
  @name = name
@@ -167,7 +171,7 @@ module GraphQL
167
171
  end
168
172
 
169
173
  def coerce_result(value, ctx)
170
- raise GraphQL::RequiredImplementationMissingError
174
+ raise NotImplementedError
171
175
  end
172
176
 
173
177
  # Types with fields may override this
@@ -70,15 +70,11 @@ module GraphQL
70
70
  ")
71
71
  end
72
72
 
73
- def assert_empty_document(query_string)
74
- doc = parse(query_string)
75
- assert_equal 0, doc.definitions.length
76
- end
77
-
78
- def test_it_parses_blank_queries
79
- assert_empty_document("")
80
- assert_empty_document(" ")
81
- assert_empty_document("\t \t")
73
+ def test_it_rejects_blank_queries
74
+ assert_raises_parse_error("")
75
+ assert_raises_parse_error(" ")
76
+ assert_raises_parse_error("\t \t")
77
+ assert_raises_parse_error(" # comment ")
82
78
  end
83
79
 
84
80
  def test_it_restricts_on
@@ -28,9 +28,9 @@ module GraphQL
28
28
  end
29
29
 
30
30
  obj_field = if base_field
31
- base_field.redefine(**kwargs, &block)
31
+ base_field.redefine(kwargs, &block)
32
32
  else
33
- GraphQL::Field.define(**kwargs, &block)
33
+ GraphQL::Field.define(kwargs, &block)
34
34
  end
35
35
 
36
36
 
@@ -1,12 +1,10 @@
1
1
  # frozen_string_literal: true
2
-
3
2
  module GraphQL
4
3
  module Define
5
4
  # This object delegates most methods to a dictionary of functions, {@dictionary}.
6
5
  # {@target} is passed to the specified function, along with any arguments and block.
7
6
  # This allows a method-based DSL without adding methods to the defined class.
8
7
  class DefinedObjectProxy
9
- extend GraphQL::Ruby2Keywords
10
8
  # The object which will be defined by definition functions
11
9
  attr_reader :target
12
10
 
@@ -34,7 +32,6 @@ module GraphQL
34
32
  end
35
33
 
36
34
  # Lookup a function from the dictionary and call it if it's found.
37
- ruby2_keywords
38
35
  def method_missing(name, *args, &block)
39
36
  definition = @dictionary[name]
40
37
  if definition
@@ -154,12 +154,7 @@ module GraphQL
154
154
  defn_proxy = DefinedObjectProxy.new(self)
155
155
  # Apply definition from `define(...)` kwargs
156
156
  defn.define_keywords.each do |keyword, value|
157
- # Don't splat string hashes, which blows up on Rubies before 2.7
158
- if value.is_a?(Hash) && !value.empty? && value.each_key.all? { |k| k.is_a?(Symbol) }
159
- defn_proxy.public_send(keyword, **value)
160
- else
161
- defn_proxy.public_send(keyword, value)
162
- end
157
+ defn_proxy.public_send(keyword, value)
163
158
  end
164
159
  # and/or apply definition from `define { ... }` block
165
160
  if defn.define_proc
@@ -292,18 +287,12 @@ module GraphQL
292
287
  end
293
288
 
294
289
  class AssignAttribute
295
- extend GraphQL::Ruby2Keywords
296
-
297
290
  def initialize(attr_name)
298
291
  @attr_assign_method = :"#{attr_name}="
299
292
  end
300
293
 
301
- # Even though we're just using the first value here,
302
- # We have to add a splat here to use `ruby2_keywords`,
303
- # so that it will accept a `[{}]` input from the caller.
304
- ruby2_keywords
305
- def call(defn, *value)
306
- defn.public_send(@attr_assign_method, value.first)
294
+ def call(defn, value)
295
+ defn.public_send(@attr_assign_method, value)
307
296
  end
308
297
  end
309
298
  end
@@ -151,6 +151,10 @@ module GraphQL
151
151
  def graphql_name
152
152
  name
153
153
  end
154
+
155
+ def type_class
156
+ metadata[:type_class]
157
+ end
154
158
  end
155
159
 
156
160
  class UnresolvedValueError < GraphQL::Error
@@ -18,12 +18,12 @@ module GraphQL
18
18
  case name
19
19
  when SKIP
20
20
  args = query.arguments_for(directive_ast_node, directive_defn)
21
- if args['if'] == true
21
+ if args[:if] == true
22
22
  return false
23
23
  end
24
24
  when INCLUDE
25
25
  args = query.arguments_for(directive_ast_node, directive_defn)
26
- if args['if'] == false
26
+ if args[:if] == false
27
27
  return false
28
28
  end
29
29
  else
@@ -2,7 +2,7 @@
2
2
 
3
3
  module GraphQL
4
4
  module Execution
5
- # A plugin that wraps query execution with error handling.
5
+ # A tracer that wraps query execution with error handling.
6
6
  # Supports class-based schemas and the new {Interpreter} runtime only.
7
7
  #
8
8
  # @example Handling ActiveRecord::NotFound
@@ -19,35 +19,34 @@ module GraphQL
19
19
  class Errors
20
20
  def self.use(schema)
21
21
  schema_class = schema.is_a?(Class) ? schema : schema.target.class
22
- schema_class.error_handler = self.new(schema_class)
22
+ schema.tracer(self.new(schema_class))
23
23
  end
24
24
 
25
25
  def initialize(schema)
26
26
  @schema = schema
27
27
  end
28
28
 
29
- class NullErrorHandler
30
- def self.with_error_handling(_ctx)
29
+ def trace(event, data)
30
+ case event
31
+ when "execute_field", "execute_field_lazy"
32
+ with_error_handling(data) { yield }
33
+ else
31
34
  yield
32
35
  end
33
36
  end
34
37
 
35
- # Call the given block with the schema's configured error handlers.
36
- #
37
- # If the block returns a lazy value, it's not wrapped with error handling. That area will have to be wrapped itself.
38
- #
39
- # @param ctx [GraphQL::Query::Context]
40
- # @return [Object] Either the result of the given block, or some object to replace the result, in case of error handling.
41
- def with_error_handling(ctx)
38
+ private
39
+
40
+ def with_error_handling(trace_data)
42
41
  yield
43
42
  rescue StandardError => err
44
43
  rescues = @schema.rescues
45
44
  _err_class, handler = rescues.find { |err_class, handler| err.is_a?(err_class) }
46
45
  if handler
47
- runtime_info = ctx.namespace(:interpreter) || {}
48
- obj = runtime_info[:current_object]
49
- args = runtime_info[:current_arguments]
50
- field = runtime_info[:current_field]
46
+ obj = trace_data[:object]
47
+ args = trace_data[:arguments]
48
+ ctx = trace_data[:query].context
49
+ field = trace_data[:field]
51
50
  if obj.is_a?(GraphQL::Schema::Object)
52
51
  obj = obj.object
53
52
  end