graphql 1.12.21 → 1.13.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) 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/type_generator.rb +0 -1
  6. data/lib/graphql/analysis/ast/field_usage.rb +2 -2
  7. data/lib/graphql/analysis/ast/query_complexity.rb +10 -14
  8. data/lib/graphql/analysis/ast/visitor.rb +4 -4
  9. data/lib/graphql/backtrace/table.rb +1 -1
  10. data/lib/graphql/base_type.rb +4 -2
  11. data/lib/graphql/boolean_type.rb +1 -1
  12. data/lib/graphql/dataloader.rb +55 -22
  13. data/lib/graphql/directive/deprecated_directive.rb +1 -1
  14. data/lib/graphql/directive/include_directive.rb +1 -1
  15. data/lib/graphql/directive/skip_directive.rb +1 -1
  16. data/lib/graphql/directive.rb +0 -4
  17. data/lib/graphql/enum_type.rb +5 -1
  18. data/lib/graphql/execution/errors.rb +1 -0
  19. data/lib/graphql/execution/interpreter/arguments.rb +1 -1
  20. data/lib/graphql/execution/interpreter/arguments_cache.rb +2 -2
  21. data/lib/graphql/execution/interpreter/runtime.rb +31 -19
  22. data/lib/graphql/execution/lookahead.rb +2 -2
  23. data/lib/graphql/execution/multiplex.rb +4 -1
  24. data/lib/graphql/float_type.rb +1 -1
  25. data/lib/graphql/id_type.rb +1 -1
  26. data/lib/graphql/int_type.rb +1 -1
  27. data/lib/graphql/introspection/directive_type.rb +1 -1
  28. data/lib/graphql/introspection/entry_points.rb +2 -2
  29. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  30. data/lib/graphql/introspection/field_type.rb +2 -2
  31. data/lib/graphql/introspection/input_value_type.rb +4 -4
  32. data/lib/graphql/introspection/schema_type.rb +2 -2
  33. data/lib/graphql/introspection/type_type.rb +10 -10
  34. data/lib/graphql/language/block_string.rb +2 -6
  35. data/lib/graphql/language/document_from_schema_definition.rb +4 -2
  36. data/lib/graphql/language/lexer.rb +0 -3
  37. data/lib/graphql/language/lexer.rl +0 -4
  38. data/lib/graphql/language/nodes.rb +12 -2
  39. data/lib/graphql/language/parser.rb +442 -434
  40. data/lib/graphql/language/parser.y +5 -4
  41. data/lib/graphql/language/printer.rb +6 -1
  42. data/lib/graphql/language/sanitized_printer.rb +5 -5
  43. data/lib/graphql/language/token.rb +0 -4
  44. data/lib/graphql/name_validator.rb +0 -4
  45. data/lib/graphql/query/arguments.rb +1 -1
  46. data/lib/graphql/query/arguments_cache.rb +1 -1
  47. data/lib/graphql/query/context.rb +15 -2
  48. data/lib/graphql/query/literal_input.rb +1 -1
  49. data/lib/graphql/query/null_context.rb +12 -7
  50. data/lib/graphql/query/serial_execution/field_resolution.rb +1 -1
  51. data/lib/graphql/query/variables.rb +5 -1
  52. data/lib/graphql/relay/edges_instrumentation.rb +0 -1
  53. data/lib/graphql/relay/global_id_resolve.rb +1 -1
  54. data/lib/graphql/relay/page_info.rb +1 -1
  55. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  56. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  57. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  58. data/lib/graphql/rubocop.rb +4 -0
  59. data/lib/graphql/schema/addition.rb +37 -28
  60. data/lib/graphql/schema/argument.rb +8 -6
  61. data/lib/graphql/schema/build_from_definition.rb +5 -5
  62. data/lib/graphql/schema/directive/feature.rb +1 -1
  63. data/lib/graphql/schema/directive/flagged.rb +2 -2
  64. data/lib/graphql/schema/directive/include.rb +1 -1
  65. data/lib/graphql/schema/directive/skip.rb +1 -1
  66. data/lib/graphql/schema/directive/transform.rb +1 -1
  67. data/lib/graphql/schema/directive.rb +7 -3
  68. data/lib/graphql/schema/enum.rb +60 -10
  69. data/lib/graphql/schema/enum_value.rb +6 -0
  70. data/lib/graphql/schema/field/connection_extension.rb +1 -1
  71. data/lib/graphql/schema/field.rb +126 -38
  72. data/lib/graphql/schema/field_extension.rb +52 -2
  73. data/lib/graphql/schema/find_inherited_value.rb +1 -0
  74. data/lib/graphql/schema/finder.rb +5 -5
  75. data/lib/graphql/schema/input_object.rb +8 -5
  76. data/lib/graphql/schema/interface.rb +11 -20
  77. data/lib/graphql/schema/introspection_system.rb +1 -1
  78. data/lib/graphql/schema/list.rb +3 -1
  79. data/lib/graphql/schema/member/accepts_definition.rb +15 -3
  80. data/lib/graphql/schema/member/build_type.rb +0 -4
  81. data/lib/graphql/schema/member/cached_graphql_definition.rb +29 -2
  82. data/lib/graphql/schema/member/has_arguments.rb +55 -13
  83. data/lib/graphql/schema/member/has_deprecation_reason.rb +1 -1
  84. data/lib/graphql/schema/member/has_fields.rb +76 -18
  85. data/lib/graphql/schema/member/has_interfaces.rb +90 -0
  86. data/lib/graphql/schema/member.rb +1 -0
  87. data/lib/graphql/schema/non_null.rb +3 -1
  88. data/lib/graphql/schema/object.rb +10 -75
  89. data/lib/graphql/schema/printer.rb +1 -1
  90. data/lib/graphql/schema/relay_classic_mutation.rb +37 -3
  91. data/lib/graphql/schema/resolver/has_payload_type.rb +27 -2
  92. data/lib/graphql/schema/resolver.rb +37 -17
  93. data/lib/graphql/schema/scalar.rb +2 -0
  94. data/lib/graphql/schema/subscription.rb +11 -1
  95. data/lib/graphql/schema/traversal.rb +1 -1
  96. data/lib/graphql/schema/type_expression.rb +1 -1
  97. data/lib/graphql/schema/type_membership.rb +18 -4
  98. data/lib/graphql/schema/union.rb +8 -1
  99. data/lib/graphql/schema/validator/format_validator.rb +0 -4
  100. data/lib/graphql/schema/validator/numericality_validator.rb +1 -0
  101. data/lib/graphql/schema/validator.rb +4 -7
  102. data/lib/graphql/schema/warden.rb +116 -52
  103. data/lib/graphql/schema.rb +106 -22
  104. data/lib/graphql/static_validation/base_visitor.rb +5 -5
  105. data/lib/graphql/static_validation/definition_dependencies.rb +0 -1
  106. data/lib/graphql/static_validation/literal_validator.rb +1 -1
  107. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  108. data/lib/graphql/static_validation/rules/fields_will_merge.rb +15 -8
  109. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +3 -1
  110. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +4 -4
  111. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +7 -7
  112. data/lib/graphql/string_type.rb +1 -1
  113. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +8 -4
  114. data/lib/graphql/subscriptions/event.rb +20 -12
  115. data/lib/graphql/subscriptions.rb +17 -19
  116. data/lib/graphql/types/relay/connection_behaviors.rb +26 -9
  117. data/lib/graphql/types/relay/default_relay.rb +5 -1
  118. data/lib/graphql/types/relay/edge_behaviors.rb +13 -2
  119. data/lib/graphql/types/relay/has_node_field.rb +1 -1
  120. data/lib/graphql/types/relay/has_nodes_field.rb +1 -1
  121. data/lib/graphql/version.rb +1 -1
  122. data/lib/graphql.rb +10 -32
  123. metadata +10 -5
@@ -34,16 +34,16 @@ module GraphQL
34
34
  parent_type = get_parent_type(context, parent)
35
35
  return unless parent_type && parent_type.kind.input_object?
36
36
 
37
- required_fields = parent_type.arguments
38
- .select{|k,v| v.type.kind.non_null?}
39
- .keys
37
+ required_fields = context.warden.arguments(parent_type)
38
+ .select{|arg| arg.type.kind.non_null?}
39
+ .map(&:graphql_name)
40
40
 
41
41
  present_fields = ast_node.arguments.map(&:name)
42
42
  missing_fields = required_fields - present_fields
43
43
 
44
44
  missing_fields.each do |missing_field|
45
45
  path = [*context.path, missing_field]
46
- missing_field_type = parent_type.arguments[missing_field].type
46
+ missing_field_type = context.warden.get_argument(parent_type, missing_field).type
47
47
  add_error(RequiredInputObjectAttributesArePresentError.new(
48
48
  "Argument '#{missing_field}' on InputObject '#{parent_type.to_type_signature}' is required. Expected type #{missing_field_type.to_type_signature}",
49
49
  argument_name: missing_field,
@@ -22,15 +22,15 @@ module GraphQL
22
22
  node_values = node_values.select { |value| value.is_a? GraphQL::Language::Nodes::VariableIdentifier }
23
23
 
24
24
  if node_values.any?
25
- arguments = case parent
25
+ argument_owner = case parent
26
26
  when GraphQL::Language::Nodes::Field
27
- context.field_definition.arguments
27
+ context.field_definition
28
28
  when GraphQL::Language::Nodes::Directive
29
- context.directive_definition.arguments
29
+ context.directive_definition
30
30
  when GraphQL::Language::Nodes::InputObject
31
31
  arg_type = context.argument_definition.type.unwrap
32
32
  if arg_type.kind.input_object?
33
- arguments = arg_type.arguments
33
+ arg_type
34
34
  else
35
35
  # This is some kind of error
36
36
  nil
@@ -43,7 +43,7 @@ module GraphQL
43
43
  var_defn_ast = @declared_variables[node_value.name]
44
44
  # Might be undefined :(
45
45
  # VariablesAreUsedAndDefined can't finalize its search until the end of the document.
46
- var_defn_ast && arguments && validate_usage(arguments, node, var_defn_ast)
46
+ var_defn_ast && argument_owner && validate_usage(argument_owner, node, var_defn_ast)
47
47
  end
48
48
  end
49
49
  super
@@ -51,7 +51,7 @@ module GraphQL
51
51
 
52
52
  private
53
53
 
54
- def validate_usage(arguments, arg_node, ast_var)
54
+ def validate_usage(argument_owner, arg_node, ast_var)
55
55
  var_type = context.schema.type_from_ast(ast_var.type, context: context)
56
56
  if var_type.nil?
57
57
  return
@@ -65,7 +65,7 @@ module GraphQL
65
65
  end
66
66
  end
67
67
 
68
- arg_defn = arguments[arg_node.name]
68
+ arg_defn = context.warden.get_argument(argument_owner, arg_node.name)
69
69
  arg_defn_type = arg_defn.type
70
70
 
71
71
  var_inner_type = var_type.unwrap
@@ -1,2 +1,2 @@
1
1
  # frozen_string_literal: true
2
- GraphQL::STRING_TYPE = GraphQL::Types::String.graphql_definition
2
+ GraphQL::STRING_TYPE = GraphQL::Types::String.graphql_definition(silence_deprecation_warning: true)
@@ -170,10 +170,12 @@ module GraphQL
170
170
  first_subscription_id = first_event.context.fetch(:subscription_id)
171
171
  object ||= load_action_cable_message(message, first_event.context)
172
172
  result = execute_update(first_subscription_id, first_event, object)
173
- # Having calculated the result _once_, send the same payload to all subscribers
174
- events.each do |event|
175
- subscription_id = event.context.fetch(:subscription_id)
176
- deliver(subscription_id, result)
173
+ if !result.nil?
174
+ # Having calculated the result _once_, send the same payload to all subscribers
175
+ events.each do |event|
176
+ subscription_id = event.context.fetch(:subscription_id)
177
+ deliver(subscription_id, result)
178
+ end
177
179
  end
178
180
  end
179
181
  end
@@ -214,6 +216,8 @@ module GraphQL
214
216
  # The channel was closed, forget about it.
215
217
  def delete_subscription(subscription_id)
216
218
  query = @subscriptions.delete(subscription_id)
219
+ # In case this came from the server, tell the client to unsubscribe:
220
+ @action_cable.server.broadcast(stream_subscription_name(subscription_id), { more: false })
217
221
  # This can be `nil` when `.trigger` happens inside an unsubscribed ActionCable channel,
218
222
  # see https://github.com/rmosolgo/graphql-ruby/issues/2478
219
223
  if query
@@ -23,15 +23,23 @@ module GraphQL
23
23
  @arguments = arguments
24
24
  @context = context
25
25
  field ||= context.field
26
- scope_val = scope || (context && field.subscription_scope && context[field.subscription_scope])
26
+ scope_key = field.subscription_scope
27
+ scope_val = scope || (context && scope_key && context[scope_key])
28
+ if scope_key &&
29
+ (subscription = field.resolver) &&
30
+ (subscription.respond_to?(:subscription_scope_optional?)) &&
31
+ !subscription.subscription_scope_optional? &&
32
+ scope_val.nil?
33
+ raise Subscriptions::SubscriptionScopeMissingError, "#{field.path} (#{subscription}) requires a `scope:` value to trigger updates (Set `subscription_scope ..., optional: true` to disable this requirement)"
34
+ end
27
35
 
28
- @topic = self.class.serialize(name, arguments, field, scope: scope_val)
36
+ @topic = self.class.serialize(name, arguments, field, scope: scope_val, context: context)
29
37
  end
30
38
 
31
39
  # @return [String] an identifier for this unit of subscription
32
- def self.serialize(_name, arguments, field, scope:)
40
+ def self.serialize(_name, arguments, field, scope:, context: GraphQL::Query::NullContext)
33
41
  subscription = field.resolver || GraphQL::Schema::Subscription
34
- normalized_args = stringify_args(field, arguments.to_h)
42
+ normalized_args = stringify_args(field, arguments.to_h, context)
35
43
  subscription.topic_for(arguments: normalized_args, field: field, scope: scope)
36
44
  end
37
45
 
@@ -83,7 +91,7 @@ module GraphQL
83
91
  end
84
92
  end
85
93
 
86
- def stringify_args(arg_owner, args)
94
+ def stringify_args(arg_owner, args, context)
87
95
  arg_owner = arg_owner.respond_to?(:unwrap) ? arg_owner.unwrap : arg_owner # remove list and non-null wrappers
88
96
  case args
89
97
  when Hash
@@ -91,13 +99,13 @@ module GraphQL
91
99
  args.each do |k, v|
92
100
  arg_name = k.to_s
93
101
  camelized_arg_name = GraphQL::Schema::Member::BuildType.camelize(arg_name)
94
- arg_defn = get_arg_definition(arg_owner, camelized_arg_name)
102
+ arg_defn = get_arg_definition(arg_owner, camelized_arg_name, context)
95
103
 
96
104
  if arg_defn
97
105
  normalized_arg_name = camelized_arg_name
98
106
  else
99
107
  normalized_arg_name = arg_name
100
- arg_defn = get_arg_definition(arg_owner, normalized_arg_name)
108
+ arg_defn = get_arg_definition(arg_owner, normalized_arg_name, context)
101
109
  end
102
110
  arg_base_type = arg_defn.type.unwrap
103
111
  # In the case where the value being emitted is seen as a "JSON"
@@ -113,22 +121,22 @@ module GraphQL
113
121
  end
114
122
  next_args[normalized_arg_name] = sorted_value.respond_to?(:to_json) ? sorted_value.to_json : sorted_value
115
123
  else
116
- next_args[normalized_arg_name] = stringify_args(arg_base_type, v)
124
+ next_args[normalized_arg_name] = stringify_args(arg_base_type, v, context)
117
125
  end
118
126
  end
119
127
  # Make sure they're deeply sorted
120
128
  next_args.sort.to_h
121
129
  when Array
122
- args.map { |a| stringify_args(arg_owner, a) }
130
+ args.map { |a| stringify_args(arg_owner, a, context) }
123
131
  when GraphQL::Schema::InputObject
124
- stringify_args(arg_owner, args.to_h)
132
+ stringify_args(arg_owner, args.to_h, context)
125
133
  else
126
134
  args
127
135
  end
128
136
  end
129
137
 
130
- def get_arg_definition(arg_owner, arg_name)
131
- arg_owner.arguments[arg_name] || arg_owner.arguments.each_value.find { |v| v.keyword.to_s == arg_name }
138
+ def get_arg_definition(arg_owner, arg_name, context)
139
+ arg_owner.get_argument(arg_name, context) || arg_owner.arguments(context).each_value.find { |v| v.keyword.to_s == arg_name }
132
140
  end
133
141
  end
134
142
  end
@@ -16,6 +16,13 @@ module GraphQL
16
16
  class InvalidTriggerError < GraphQL::Error
17
17
  end
18
18
 
19
+ # Raised when either:
20
+ # - An initial subscription didn't have a value for `context[subscription_scope]`
21
+ # - Or, an update didn't pass `.trigger(..., scope:)`
22
+ # When raised, the initial subscription or update fails completely.
23
+ class SubscriptionScopeMissingError < GraphQL::Error
24
+ end
25
+
19
26
  # @see {Subscriptions#initialize} for options, concrete implementations may add options.
20
27
  def self.use(defn, options = {})
21
28
  schema = defn.is_a?(Class) ? defn : defn.target
@@ -76,7 +83,8 @@ module GraphQL
76
83
  end
77
84
 
78
85
  # Normalize symbol-keyed args to strings, try camelizing them
79
- normalized_args = normalize_arguments(normalized_event_name, field, args)
86
+ # Should this accept a real context somehow?
87
+ normalized_args = normalize_arguments(normalized_event_name, field, args, GraphQL::Query::NullContext)
80
88
 
81
89
  event = Subscriptions::Event.new(
82
90
  name: normalized_event_name,
@@ -151,16 +159,6 @@ module GraphQL
151
159
  # @param object [Object]
152
160
  # @return [void]
153
161
  def execute_all(event, object)
154
- each_subscription_id(event) do |subscription_id|
155
- execute(subscription_id, event, object)
156
- end
157
- end
158
-
159
- # Get each `subscription_id` subscribed to `event.topic` and yield them
160
- # @param event [GraphQL::Subscriptions::Event]
161
- # @yieldparam subscription_id [String]
162
- # @return [void]
163
- def each_subscription_id(event)
164
162
  raise GraphQL::RequiredImplementationMissingError
165
163
  end
166
164
 
@@ -233,7 +231,7 @@ module GraphQL
233
231
  # @param arg_owner [GraphQL::Field, GraphQL::BaseType]
234
232
  # @param args [Hash, Array, Any] some GraphQL input value to coerce as `arg_owner`
235
233
  # @return [Any] normalized arguments value
236
- def normalize_arguments(event_name, arg_owner, args)
234
+ def normalize_arguments(event_name, arg_owner, args, context)
237
235
  case arg_owner
238
236
  when GraphQL::Field, GraphQL::InputObjectType, GraphQL::Schema::Field, Class
239
237
  if arg_owner.is_a?(Class) && !arg_owner.kind.input_object?
@@ -244,19 +242,19 @@ module GraphQL
244
242
  missing_arg_names = []
245
243
  args.each do |k, v|
246
244
  arg_name = k.to_s
247
- arg_defn = arg_owner.arguments[arg_name]
245
+ arg_defn = arg_owner.get_argument(arg_name, context)
248
246
  if arg_defn
249
247
  normalized_arg_name = arg_name
250
248
  else
251
249
  normalized_arg_name = normalize_name(arg_name)
252
- arg_defn = arg_owner.arguments[normalized_arg_name]
250
+ arg_defn = arg_owner.get_argument(normalized_arg_name, context)
253
251
  end
254
252
 
255
253
  if arg_defn
256
254
  if arg_defn.loads
257
255
  normalized_arg_name = arg_defn.keyword.to_s
258
256
  end
259
- normalized = normalize_arguments(event_name, arg_defn.type, v)
257
+ normalized = normalize_arguments(event_name, arg_defn.type, v, context)
260
258
  normalized_args[normalized_arg_name] = normalized
261
259
  else
262
260
  # Couldn't find a matching argument definition
@@ -266,12 +264,12 @@ module GraphQL
266
264
 
267
265
  # Backfill default values so that trigger arguments
268
266
  # match query arguments.
269
- arg_owner.arguments.each do |name, arg_defn|
267
+ arg_owner.arguments(context).each do |_name, arg_defn|
270
268
  if arg_defn.default_value? && !normalized_args.key?(arg_defn.name)
271
269
  default_value = arg_defn.default_value
272
270
  # We don't have an underlying "object" here, so it can't call methods.
273
271
  # This is broken.
274
- normalized_args[arg_defn.name] = arg_defn.prepare_value(nil, default_value, context: GraphQL::Query::NullContext)
272
+ normalized_args[arg_defn.name] = arg_defn.prepare_value(nil, default_value, context: context)
275
273
  end
276
274
  end
277
275
 
@@ -290,9 +288,9 @@ module GraphQL
290
288
 
291
289
  normalized_args
292
290
  when GraphQL::ListType, GraphQL::Schema::List
293
- args.map { |a| normalize_arguments(event_name, arg_owner.of_type, a) }
291
+ args.map { |a| normalize_arguments(event_name, arg_owner.of_type, a, context) }
294
292
  when GraphQL::NonNullType, GraphQL::Schema::NonNull
295
- normalize_arguments(event_name, arg_owner.of_type, args)
293
+ normalize_arguments(event_name, arg_owner.of_type, args, context)
296
294
  else
297
295
  args
298
296
  end
@@ -35,7 +35,8 @@ module GraphQL
35
35
  # It's called when you subclass this base connection, trying to use the
36
36
  # class name to set defaults. You can call it again in the class definition
37
37
  # to override the default (or provide a value, if the default lookup failed).
38
- def edge_type(edge_type_class, edge_class: GraphQL::Relay::Edge, node_type: edge_type_class.node_type, nodes_field: self.has_nodes_field, node_nullable: self.node_nullable, edges_nullable: self.edges_nullable, edge_nullable: self.edge_nullable)
38
+ # @param field_options [Hash] Any extra keyword arguments to pass to the `field :edges, ...` and `field :nodes, ...` configurations
39
+ def edge_type(edge_type_class, edge_class: GraphQL::Relay::Edge, node_type: edge_type_class.node_type, nodes_field: self.has_nodes_field, node_nullable: self.node_nullable, edges_nullable: self.edges_nullable, edge_nullable: self.edge_nullable, field_options: nil)
39
40
  # Set this connection's graphql name
40
41
  node_type_name = node_type.graphql_name
41
42
 
@@ -43,13 +44,22 @@ module GraphQL
43
44
  @edge_type = edge_type_class
44
45
  @edge_class = edge_class
45
46
 
46
- field :edges, [edge_type_class, null: edge_nullable],
47
+ base_field_options = {
48
+ name: :edges,
49
+ type: [edge_type_class, null: edge_nullable],
47
50
  null: edges_nullable,
48
51
  description: "A list of edges.",
49
52
  legacy_edge_class: edge_class, # This is used by the old runtime only, for EdgesInstrumentation
50
- connection: false
53
+ connection: false,
54
+ }
51
55
 
52
- define_nodes_field(node_nullable) if nodes_field
56
+ if field_options
57
+ base_field_options.merge!(field_options)
58
+ end
59
+
60
+ field(**base_field_options)
61
+
62
+ define_nodes_field(node_nullable, field_options: field_options) if nodes_field
53
63
 
54
64
  description("The connection type for #{node_type_name}.")
55
65
  end
@@ -60,8 +70,8 @@ module GraphQL
60
70
  end
61
71
 
62
72
  # Add the shortcut `nodes` field to this connection and its subclasses
63
- def nodes_field(node_nullable: self.node_nullable)
64
- define_nodes_field(node_nullable)
73
+ def nodes_field(node_nullable: self.node_nullable, field_options: nil)
74
+ define_nodes_field(node_nullable, field_options: field_options)
65
75
  end
66
76
 
67
77
  def authorized?(obj, ctx)
@@ -118,11 +128,18 @@ module GraphQL
118
128
 
119
129
  private
120
130
 
121
- def define_nodes_field(nullable)
122
- field :nodes, [@node_type, null: nullable],
131
+ def define_nodes_field(nullable, field_options: nil)
132
+ base_field_options = {
133
+ name: :nodes,
134
+ type: [@node_type, null: nullable],
123
135
  null: nullable,
124
136
  description: "A list of nodes.",
125
- connection: false
137
+ connection: false,
138
+ }
139
+ if field_options
140
+ base_field_options.merge!(field_options)
141
+ end
142
+ field(**base_field_options)
126
143
  end
127
144
  end
128
145
 
@@ -17,7 +17,11 @@ module GraphQL
17
17
  end
18
18
 
19
19
  def to_graphql
20
- type_defn = super
20
+ type_defn = if method(:to_graphql).super_method.arity
21
+ super(silence_deprecation_warning: true)
22
+ else
23
+ super
24
+ end
21
25
  type_defn.default_relay = default_relay?
22
26
  type_defn
23
27
  end
@@ -16,11 +16,22 @@ module GraphQL
16
16
  #
17
17
  # @param node_type [Class] A `Schema::Object` subclass
18
18
  # @param null [Boolean]
19
- def node_type(node_type = nil, null: self.node_nullable)
19
+ # @param field_options [Hash] Any extra arguments to pass to the `field :node` configuration
20
+ def node_type(node_type = nil, null: self.node_nullable, field_options: nil)
20
21
  if node_type
21
22
  @node_type = node_type
22
23
  # Add a default `node` field
23
- field :node, node_type, null: null, description: "The item at the end of the edge.", connection: false
24
+ base_field_options = {
25
+ name: :node,
26
+ type: node_type,
27
+ null: null,
28
+ description: "The item at the end of the edge.",
29
+ connection: false,
30
+ }
31
+ if field_options
32
+ base_field_options.merge!(field_options)
33
+ end
34
+ field(**base_field_options)
24
35
  end
25
36
  @node_type
26
37
  end
@@ -22,7 +22,7 @@ module GraphQL
22
22
 
23
23
  def field_block
24
24
  Proc.new {
25
- argument :id, "ID!", required: true,
25
+ argument :id, "ID!",
26
26
  description: "ID of the object."
27
27
 
28
28
  def resolve(obj, args, ctx)
@@ -22,7 +22,7 @@ module GraphQL
22
22
 
23
23
  def field_block
24
24
  Proc.new {
25
- argument :ids, "[ID!]!", required: true,
25
+ argument :ids, "[ID!]!",
26
26
  description: "IDs of the objects."
27
27
 
28
28
  def resolve(obj, args, ctx)
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "1.12.21"
3
+ VERSION = "1.13.2"
4
4
  end
data/lib/graphql.rb CHANGED
@@ -55,31 +55,6 @@ module GraphQL
55
55
  def self.scan_with_ragel(graphql_string)
56
56
  GraphQL::Language::Lexer.tokenize(graphql_string)
57
57
  end
58
-
59
- # Support Ruby 2.2 by implementing `-"str"`. If we drop 2.2 support, we can remove this backport.
60
- if !String.method_defined?(:-@)
61
- module StringDedupBackport
62
- refine String do
63
- def -@
64
- if frozen?
65
- self
66
- else
67
- self.dup.freeze
68
- end
69
- end
70
- end
71
- end
72
- end
73
-
74
- if !String.method_defined?(:match?)
75
- module StringMatchBackport
76
- refine String do
77
- def match?(pattern)
78
- self =~ pattern
79
- end
80
- end
81
- end
82
- end
83
58
  end
84
59
 
85
60
  # Order matters for these:
@@ -125,10 +100,14 @@ require "graphql/execution"
125
100
  require "graphql/pagination"
126
101
  require "graphql/schema"
127
102
  require "graphql/query"
103
+ require "graphql/types"
104
+ require "graphql/dataloader"
105
+ require "graphql/filter"
106
+ require "graphql/internal_representation"
128
107
  require "graphql/directive"
108
+ require "graphql/static_validation"
129
109
  require "graphql/execution"
130
- require "graphql/types"
131
- require "graphql/relay"
110
+ require "graphql/deprecation"
132
111
  require "graphql/boolean_type"
133
112
  require "graphql/float_type"
134
113
  require "graphql/id_type"
@@ -137,11 +116,8 @@ require "graphql/string_type"
137
116
  require "graphql/schema/built_in_types"
138
117
  require "graphql/schema/loader"
139
118
  require "graphql/schema/printer"
140
- require "graphql/filter"
141
- require "graphql/internal_representation"
142
- require "graphql/static_validation"
143
- require "graphql/dataloader"
144
119
  require "graphql/introspection"
120
+ require "graphql/relay"
145
121
 
146
122
  require "graphql/version"
147
123
  require "graphql/compatibility"
@@ -155,7 +131,9 @@ require "graphql/authorization"
155
131
  require "graphql/unauthorized_error"
156
132
  require "graphql/unauthorized_field_error"
157
133
  require "graphql/load_application_object_failed_error"
158
- require "graphql/deprecation"
134
+ require "graphql/directive/include_directive"
135
+ require "graphql/directive/skip_directive"
136
+ require "graphql/directive/deprecated_directive"
159
137
 
160
138
  module GraphQL
161
139
  # Ruby has `deprecate_constant`,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.12.21
4
+ version: 1.13.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-23 00:00:00.000000000 Z
11
+ date: 2021-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark-ips
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - '='
130
130
  - !ruby/object:Gem::Version
131
- version: '0.68'
131
+ version: '1.12'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - '='
137
137
  - !ruby/object:Gem::Version
138
- version: '0.68'
138
+ version: '1.12'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: parser
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -467,6 +467,10 @@ files:
467
467
  - lib/graphql/relay/range_add.rb
468
468
  - lib/graphql/relay/relation_connection.rb
469
469
  - lib/graphql/relay/type_extensions.rb
470
+ - lib/graphql/rubocop.rb
471
+ - lib/graphql/rubocop/graphql/base_cop.rb
472
+ - lib/graphql/rubocop/graphql/default_null_true.rb
473
+ - lib/graphql/rubocop/graphql/default_required_true.rb
470
474
  - lib/graphql/runtime_type_error.rb
471
475
  - lib/graphql/scalar_type.rb
472
476
  - lib/graphql/schema.rb
@@ -514,6 +518,7 @@ files:
514
518
  - lib/graphql/schema/member/has_deprecation_reason.rb
515
519
  - lib/graphql/schema/member/has_directives.rb
516
520
  - lib/graphql/schema/member/has_fields.rb
521
+ - lib/graphql/schema/member/has_interfaces.rb
517
522
  - lib/graphql/schema/member/has_path.rb
518
523
  - lib/graphql/schema/member/has_unresolved_type_error.rb
519
524
  - lib/graphql/schema/member/has_validators.rb
@@ -695,7 +700,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
695
700
  requirements:
696
701
  - - ">="
697
702
  - !ruby/object:Gem::Version
698
- version: 2.2.0
703
+ version: 2.4.0
699
704
  required_rubygems_version: !ruby/object:Gem::Requirement
700
705
  requirements:
701
706
  - - ">="