graphql 0.19.3 → 0.19.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/analysis/max_query_complexity.rb +1 -1
  3. data/lib/graphql/analysis/max_query_depth.rb +1 -1
  4. data/lib/graphql/boolean_type.rb +2 -2
  5. data/lib/graphql/define/instance_definable.rb +2 -2
  6. data/lib/graphql/enum_type.rb +3 -3
  7. data/lib/graphql/field.rb +6 -6
  8. data/lib/graphql/float_type.rb +2 -2
  9. data/lib/graphql/id_type.rb +2 -2
  10. data/lib/graphql/input_object_type.rb +1 -1
  11. data/lib/graphql/int_type.rb +2 -2
  12. data/lib/graphql/internal_representation/rewrite.rb +12 -12
  13. data/lib/graphql/introspection/arguments_field.rb +1 -1
  14. data/lib/graphql/introspection/enum_value_type.rb +1 -1
  15. data/lib/graphql/introspection/enum_values_field.rb +1 -1
  16. data/lib/graphql/introspection/field_type.rb +1 -1
  17. data/lib/graphql/introspection/fields_field.rb +1 -1
  18. data/lib/graphql/introspection/input_fields_field.rb +1 -1
  19. data/lib/graphql/introspection/input_value_type.rb +2 -2
  20. data/lib/graphql/introspection/interfaces_field.rb +1 -1
  21. data/lib/graphql/introspection/of_type_field.rb +1 -1
  22. data/lib/graphql/introspection/possible_types_field.rb +1 -1
  23. data/lib/graphql/introspection/schema_field.rb +1 -1
  24. data/lib/graphql/introspection/schema_type.rb +5 -5
  25. data/lib/graphql/introspection/type_by_name_field.rb +1 -1
  26. data/lib/graphql/introspection/type_type.rb +6 -6
  27. data/lib/graphql/introspection/typename_field.rb +1 -1
  28. data/lib/graphql/language.rb +1 -0
  29. data/lib/graphql/language/comments.rb +44 -0
  30. data/lib/graphql/language/definition_slice.rb +1 -1
  31. data/lib/graphql/language/generation.rb +35 -12
  32. data/lib/graphql/language/lexer.rb +29 -10
  33. data/lib/graphql/language/lexer.rl +25 -6
  34. data/lib/graphql/language/nodes.rb +30 -23
  35. data/lib/graphql/language/parser.rb +33 -14
  36. data/lib/graphql/language/parser.y +33 -14
  37. data/lib/graphql/language/parser_tests.rb +86 -2
  38. data/lib/graphql/language/token.rb +3 -2
  39. data/lib/graphql/language/visitor.rb +3 -3
  40. data/lib/graphql/object_type.rb +1 -1
  41. data/lib/graphql/query/arguments.rb +23 -2
  42. data/lib/graphql/query/serial_execution/field_resolution.rb +31 -14
  43. data/lib/graphql/relay/base_connection.rb +1 -3
  44. data/lib/graphql/relay/connection_type.rb +1 -1
  45. data/lib/graphql/relay/mutation.rb +1 -1
  46. data/lib/graphql/relay/relation_connection.rb +7 -3
  47. data/lib/graphql/scalar_type.rb +1 -1
  48. data/lib/graphql/schema.rb +19 -8
  49. data/lib/graphql/schema/loader.rb +2 -2
  50. data/lib/graphql/schema/printer.rb +63 -8
  51. data/lib/graphql/schema/timeout_middleware.rb +11 -11
  52. data/lib/graphql/schema/validation.rb +12 -12
  53. data/lib/graphql/static_validation/arguments_validator.rb +1 -1
  54. data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
  55. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +1 -1
  56. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +1 -1
  57. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +1 -1
  58. data/lib/graphql/static_validation/rules/fields_will_merge.rb +3 -2
  59. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  60. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +1 -1
  61. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +9 -4
  62. data/lib/graphql/static_validation/rules/fragments_are_named.rb +1 -1
  63. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  64. data/lib/graphql/static_validation/rules/fragments_are_used.rb +3 -3
  65. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
  66. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +2 -2
  67. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
  68. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +1 -1
  69. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
  70. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  71. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +6 -6
  72. data/lib/graphql/static_validation/type_stack.rb +2 -2
  73. data/lib/graphql/string_type.rb +2 -2
  74. data/lib/graphql/version.rb +1 -1
  75. data/readme.md +1 -1
  76. data/spec/graphql/analysis/analyze_query_spec.rb +3 -3
  77. data/spec/graphql/analysis/query_complexity_spec.rb +7 -7
  78. data/spec/graphql/introspection/directive_type_spec.rb +2 -2
  79. data/spec/graphql/introspection/introspection_query_spec.rb +26 -26
  80. data/spec/graphql/language/generation_spec.rb +137 -53
  81. data/spec/graphql/language/lexer_spec.rb +22 -0
  82. data/spec/graphql/language/visitor_spec.rb +6 -6
  83. data/spec/graphql/query/arguments_spec.rb +45 -1
  84. data/spec/graphql/query/context_spec.rb +4 -4
  85. data/spec/graphql/query/executor_spec.rb +1 -1
  86. data/spec/graphql/query/serial_execution/value_resolution_spec.rb +1 -1
  87. data/spec/graphql/relay/mutation_spec.rb +2 -2
  88. data/spec/graphql/relay/node_spec.rb +2 -2
  89. data/spec/graphql/relay/relation_connection_spec.rb +16 -0
  90. data/spec/graphql/schema/loader_spec.rb +2 -2
  91. data/spec/graphql/schema/middleware_chain_spec.rb +6 -6
  92. data/spec/graphql/schema/printer_spec.rb +268 -18
  93. data/spec/graphql/schema/rescue_middleware_spec.rb +1 -1
  94. data/spec/graphql/schema/timeout_middleware_spec.rb +2 -2
  95. data/spec/graphql/schema_spec.rb +2 -2
  96. data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +13 -0
  97. data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +1 -1
  98. data/spec/graphql/static_validation/type_stack_spec.rb +1 -1
  99. data/spec/support/dairy_app.rb +25 -25
  100. data/spec/support/dairy_data.rb +2 -0
  101. data/spec/support/star_wars_data.rb +2 -1
  102. data/spec/support/star_wars_schema.rb +18 -18
  103. metadata +19 -2
@@ -54,35 +54,52 @@ module GraphQL
54
54
  end
55
55
  end
56
56
 
57
-
58
57
  # Get the result of:
59
58
  # - Any middleware on this schema
60
59
  # - The field's resolve method
61
60
  # If the middleware chain returns a GraphQL::ExecutionError, its message
62
61
  # is added to the "errors" key.
63
62
  def get_raw_value
64
- steps = execution_context.query.schema.middleware + [get_middleware_proc_from_field_resolve]
65
- chain = GraphQL::Schema::MiddlewareChain.new(
66
- steps: steps,
67
- arguments: [parent_type, target, field, arguments, execution_context.query.context]
68
- )
69
- chain.call
63
+ middlewares = execution_context.query.schema.middleware
64
+ field_resolve_step = FieldResolveStep.new(irep_node)
65
+ resolve_arguments = [parent_type, target, field, arguments, execution_context.query.context]
66
+ # only run a middleware chain if there are any middleware
67
+ if middlewares.any?
68
+ chain = GraphQL::Schema::MiddlewareChain.new(
69
+ steps: middlewares + [field_resolve_step],
70
+ arguments: resolve_arguments
71
+ )
72
+ chain.call
73
+ else
74
+ field_resolve_step.call(*resolve_arguments)
75
+ end
70
76
  rescue GraphQL::ExecutionError => err
71
77
  err
72
78
  end
73
79
 
74
80
 
75
- # Execute the field's resolve method
76
- # @return [Proc] suitable to be the last step in a middleware chain
77
- def get_middleware_proc_from_field_resolve
78
- -> (_parent_type, parent_object, field_definition, field_args, context, _next) {
79
- context.ast_node = irep_node.ast_node
80
- context.irep_node = irep_node
81
+ # A `.call`-able suitable to be the last step in a middleware chain
82
+ class FieldResolveStep
83
+ def initialize(irep_node)
84
+ @irep_node = irep_node
85
+ end
86
+
87
+ # Execute the field's resolve method
88
+ def call(_parent_type, parent_object, field_definition, field_args, context, _next = nil)
89
+ # setup
90
+ context.ast_node = @irep_node.ast_node
91
+ context.irep_node = @irep_node
92
+
93
+ # resolve
81
94
  value = field_definition.resolve(parent_object, field_args, context)
95
+
96
+ # teardown
82
97
  context.ast_node = nil
83
98
  context.irep_node = nil
99
+
100
+ # return
84
101
  value
85
- }
102
+ end
86
103
  end
87
104
  end
88
105
  end
@@ -74,7 +74,7 @@ module GraphQL
74
74
  deprecate(:object, :nodes, 2016, 9)
75
75
 
76
76
  # Provide easy access to provided arguments:
77
- METHODS_FROM_ARGUMENTS = [:first, :after, :last, :before, :order]
77
+ METHODS_FROM_ARGUMENTS = [:first, :after, :last, :before]
78
78
 
79
79
  # @!method first
80
80
  # The value passed as `first:`, if there was one
@@ -84,8 +84,6 @@ module GraphQL
84
84
  # The value passed as `last:`, if there was one
85
85
  # @!method before
86
86
  # The value passed as `before:`, if there was one
87
- # @!method order
88
- # The value passed as `order:`, if there was one
89
87
  METHODS_FROM_ARGUMENTS.each do |arg_name|
90
88
  define_method(arg_name) do
91
89
  arguments[arg_name]
@@ -11,7 +11,7 @@ module GraphQL
11
11
  name(connection_type_name)
12
12
  field :edges, types[edge_type] do
13
13
  description "A list of edges."
14
- resolve -> (obj, args, ctx) {
14
+ resolve ->(obj, args, ctx) {
15
15
  obj.edge_nodes.map { |item| edge_class.new(item, obj) }
16
16
  }
17
17
  end
@@ -19,7 +19,7 @@ module GraphQL
19
19
  #
20
20
  # return_field :item, ItemType
21
21
  #
22
- # resolve -> (inputs, ctx) {
22
+ # resolve ->(inputs, ctx) {
23
23
  # item = Item.find_by_id(inputs[:id])
24
24
  # item.update(name: inputs[:name])
25
25
  # {item: item}
@@ -6,8 +6,13 @@ module GraphQL
6
6
  # - `Sequel::Dataset`
7
7
  class RelationConnection < BaseConnection
8
8
  def cursor_from_node(item)
9
- offset = starting_offset + paged_nodes_array.index(item) + 1
10
- Base64.strict_encode64(offset.to_s)
9
+ item_index = paged_nodes_array.index(item)
10
+ if item_index.nil?
11
+ raise("Can't generate cursor, item not found in connection: #{item}")
12
+ else
13
+ offset = starting_offset + item_index + 1
14
+ Base64.strict_encode64(offset.to_s)
15
+ end
11
16
  end
12
17
 
13
18
  def has_next_page
@@ -81,7 +86,6 @@ module GraphQL
81
86
  end
82
87
  end
83
88
 
84
-
85
89
  if defined?(ActiveRecord::Relation)
86
90
  BaseConnection.register_connection_implementation(ActiveRecord::Relation, RelationConnection)
87
91
  end
@@ -44,7 +44,7 @@ module GraphQL
44
44
  def validate_non_null_input(value)
45
45
  result = Query::InputValidationResult.new
46
46
  if coerce_non_null_input(value).nil?
47
- result.add_problem("Could not coerce value #{JSON.dump(value)} to #{name}")
47
+ result.add_problem("Could not coerce value #{JSON.generate(value, quirks_mode: true)} to #{name}")
48
48
  end
49
49
  result
50
50
  end
@@ -50,9 +50,9 @@ module GraphQL
50
50
  :max_depth, :max_complexity,
51
51
  :orphan_types, :resolve_type,
52
52
  :object_from_id, :id_from_object,
53
- query_analyzer: -> (schema, analyzer) { schema.query_analyzers << analyzer },
54
- middleware: -> (schema, middleware) { schema.middleware << middleware },
55
- rescue_from: -> (schema, err_class, &block) { schema.rescue_from(err_class, &block)}
53
+ query_analyzer: ->(schema, analyzer) { schema.query_analyzers << analyzer },
54
+ middleware: ->(schema, middleware) { schema.middleware << middleware },
55
+ rescue_from: ->(schema, err_class, &block) { schema.rescue_from(err_class, &block)}
56
56
 
57
57
  lazy_defined_attr_accessor \
58
58
  :query, :mutation, :subscription,
@@ -61,7 +61,7 @@ module GraphQL
61
61
  :orphan_types,
62
62
  :query_analyzers, :middleware
63
63
 
64
- DIRECTIVES = [GraphQL::Directive::SkipDirective, GraphQL::Directive::IncludeDirective, GraphQL::Directive::DeprecatedDirective]
64
+ DIRECTIVES = [GraphQL::Directive::IncludeDirective, GraphQL::Directive::SkipDirective, GraphQL::Directive::DeprecatedDirective]
65
65
  DYNAMIC_FIELDS = ["__type", "__typename", "__schema"]
66
66
 
67
67
  attr_reader :directives, :static_validator, :object_from_id_proc, :id_from_object_proc, :resolve_type_proc
@@ -86,8 +86,7 @@ module GraphQL
86
86
  @orphan_types = types
87
87
  @directives = DIRECTIVES.reduce({}) { |m, d| m[d.name] = d; m }
88
88
  @static_validator = GraphQL::StaticValidation::Validator.new(schema: self)
89
- @rescue_middleware = GraphQL::Schema::RescueMiddleware.new
90
- @middleware = [@rescue_middleware]
89
+ @middleware = []
91
90
  @query_analyzers = []
92
91
  @resolve_type_proc = nil
93
92
  @object_from_id_proc = nil
@@ -100,12 +99,12 @@ module GraphQL
100
99
 
101
100
  def rescue_from(*args, &block)
102
101
  ensure_defined
103
- @rescue_middleware.rescue_from(*args, &block)
102
+ rescue_middleware.rescue_from(*args, &block)
104
103
  end
105
104
 
106
105
  def remove_handler(*args, &block)
107
106
  ensure_defined
108
- @rescue_middleware.remove_handler(*args, &block)
107
+ rescue_middleware.remove_handler(*args, &block)
109
108
  end
110
109
 
111
110
  def define(**kwargs, &block)
@@ -258,5 +257,17 @@ module GraphQL
258
257
  ensure_defined
259
258
  @id_from_object_proc = new_proc
260
259
  end
260
+
261
+ private
262
+
263
+ # Lazily create a middleware and add it to the schema
264
+ # (Don't add it if it's not used)
265
+ def rescue_middleware
266
+ @rescue_middleware ||= begin
267
+ middleware = GraphQL::Schema::RescueMiddleware.new
268
+ @middleware << middleware
269
+ middleware
270
+ end
271
+ end
261
272
  end
262
273
  end
@@ -14,7 +14,7 @@ module GraphQL
14
14
  schema = introspection_result.fetch("data").fetch("__schema")
15
15
 
16
16
  types = {}
17
- type_resolver = -> (type) { -> { resolve_type(types, type) } }
17
+ type_resolver = ->(type) { -> { resolve_type(types, type) } }
18
18
 
19
19
  schema.fetch("types").each do |type|
20
20
  next if type.fetch("name").start_with?("__")
@@ -31,7 +31,7 @@ module GraphQL
31
31
  Schema.define(**kargs)
32
32
  end
33
33
 
34
- NullResolveType = -> (obj, ctx) {
34
+ NullResolveType = ->(obj, ctx) {
35
35
  raise(NotImplementedError, "This schema was loaded from string, so it can't resolve types for objects")
36
36
  }
37
37
 
@@ -18,7 +18,7 @@ module GraphQL
18
18
  # Return the GraphQL schema string for the introspection type system
19
19
  def print_introspection_schema
20
20
  query_root = ObjectType.define do
21
- name "Query"
21
+ name "Root"
22
22
  end
23
23
  schema = GraphQL::Schema.define(query: query_root)
24
24
  print_filtered_schema(schema, method(:is_spec_directive), method(:is_introspection_type))
@@ -33,11 +33,18 @@ module GraphQL
33
33
  types = schema.types.values.select{ |type| type_filter.call(type) }.sort_by(&:name)
34
34
  type_definitions = types.map{ |type| print_type(type) }
35
35
 
36
- [print_schema_definition(schema)].concat(directive_definitions)
36
+ [print_schema_definition(schema)].compact
37
+ .concat(directive_definitions)
37
38
  .concat(type_definitions).join("\n\n")
38
39
  end
39
40
 
40
41
  def print_schema_definition(schema)
42
+ if (schema.query.nil? || schema.query.name == 'Query') &&
43
+ (schema.mutation.nil? || schema.mutation.name == 'Mutation') &&
44
+ (schema.subscription.nil? || schema.subscription.name == 'Subscription')
45
+ return
46
+ end
47
+
41
48
  operations = [:query, :mutation, :subscription].map do |operation_type|
42
49
  object_type = schema.public_send(operation_type)
43
50
  " #{operation_type}: #{object_type.name}\n" if object_type
@@ -84,10 +91,32 @@ module GraphQL
84
91
  end
85
92
  end
86
93
 
94
+ module DescriptionPrinter
95
+ def print_description(definition, indentation='', first_in_block=true)
96
+ return '' unless definition.description
97
+
98
+ description = indentation != '' && !first_in_block ? "\n" : ""
99
+ description << GraphQL::Language::Comments.commentize(definition.description, indent: indentation)
100
+ end
101
+ end
102
+
87
103
  module ArgsPrinter
88
- def print_args(field)
104
+ include DescriptionPrinter
105
+ def print_args(field, indentation = '')
89
106
  return if field.arguments.empty?
90
- "(#{field.arguments.values.map{ |arg| print_input_value(arg) }.join(", ")})"
107
+
108
+ field_arguments = field.arguments.values
109
+
110
+ if field_arguments.all?{ |arg| !arg.description }
111
+ return "(#{field_arguments.map{ |arg| print_input_value(arg) }.join(", ")})"
112
+ end
113
+
114
+ out = "(\n"
115
+ out << field_arguments.map.with_index{ |arg, i|
116
+ "#{print_description(arg, " #{indentation}", i == 0)} #{indentation}"\
117
+ "#{print_input_value(arg)}"
118
+ }.join("\n")
119
+ out << "\n)"
91
120
  end
92
121
 
93
122
  def print_input_value(arg)
@@ -131,64 +160,90 @@ module GraphQL
131
160
  module FieldPrinter
132
161
  include DeprecatedPrinter
133
162
  include ArgsPrinter
163
+ include DescriptionPrinter
134
164
  def print_fields(type)
135
- type.all_fields.map{ |field|
136
- " #{field.name}#{print_args(field)}: #{field.type}#{print_deprecated(field)}"
165
+ type.all_fields.map.with_index{ |field, i|
166
+ "#{print_description(field, ' ', i == 0)}"\
167
+ " #{field.name}#{print_args(field, ' ')}: #{field.type}#{print_deprecated(field)}"
137
168
  }.join("\n")
138
169
  end
139
170
  end
140
171
 
141
172
  class DirectivePrinter
142
173
  extend ArgsPrinter
174
+ extend DescriptionPrinter
143
175
  def self.print(directive)
176
+ "#{print_description(directive)}"\
144
177
  "directive @#{directive.name}#{print_args(directive)} "\
145
178
  "on #{directive.locations.join(' | ')}"
146
179
  end
147
180
  end
148
181
 
149
182
  class ScalarPrinter
183
+ extend DescriptionPrinter
150
184
  def self.print(type)
185
+ "#{print_description(type)}"\
151
186
  "scalar #{type.name}"
152
187
  end
153
188
  end
154
189
 
155
190
  class ObjectPrinter
156
191
  extend FieldPrinter
192
+ extend DescriptionPrinter
157
193
  def self.print(type)
158
194
  if type.interfaces.any?
159
195
  implementations = " implements #{type.interfaces.map(&:to_s).join(", ")}"
160
196
  else
161
197
  implementations = nil
162
198
  end
163
- "type #{type.name}#{implementations} {\n#{print_fields(type)}\n}"
199
+
200
+ "#{print_description(type)}"\
201
+ "type #{type.name}#{implementations} {\n"\
202
+ "#{print_fields(type)}\n"\
203
+ "}"
164
204
  end
165
205
  end
166
206
 
167
207
  class InterfacePrinter
168
208
  extend FieldPrinter
209
+ extend DescriptionPrinter
169
210
  def self.print(type)
211
+ "#{print_description(type)}"\
170
212
  "interface #{type.name} {\n#{print_fields(type)}\n}"
171
213
  end
172
214
  end
173
215
 
174
216
  class UnionPrinter
217
+ extend DescriptionPrinter
175
218
  def self.print(type)
219
+ "#{print_description(type)}"\
176
220
  "union #{type.name} = #{type.possible_types.map(&:to_s).join(" | ")}"
177
221
  end
178
222
  end
179
223
 
180
224
  class EnumPrinter
181
225
  extend DeprecatedPrinter
226
+ extend DescriptionPrinter
182
227
  def self.print(type)
183
228
  values = type.values.values.map{ |v| " #{v.name}#{print_deprecated(v)}" }.join("\n")
229
+ values = type.values.values.map.with_index { |v, i|
230
+ "#{print_description(v, ' ', i == 0)}"\
231
+ " #{v.name}#{print_deprecated(v)}"
232
+ }.join("\n")
233
+ "#{print_description(type)}"\
184
234
  "enum #{type.name} {\n#{values}\n}"
185
235
  end
186
236
  end
187
237
 
188
238
  class InputObjectPrinter
189
239
  extend FieldPrinter
240
+ extend DescriptionPrinter
190
241
  def self.print(type)
191
- fields = type.input_fields.values.map{ |field| " #{print_input_value(field)}" }.join("\n")
242
+ fields = type.input_fields.values.map.with_index{ |field, i|
243
+ "#{print_description(field, " ", i == 0)}"\
244
+ " #{print_input_value(field)}"
245
+ }.join("\n")
246
+ "#{print_description(type)}"\
192
247
  "input #{type.name} {\n#{fields}\n}"
193
248
  end
194
249
  end
@@ -50,18 +50,18 @@ module GraphQL
50
50
  end
51
51
  err
52
52
  end
53
- end
54
53
 
55
- # This error is raised when a query exceeds `max_seconds`.
56
- # Since it's a child of {GraphQL::ExecutionError},
57
- # its message will be added to the response's `errors` key.
58
- #
59
- # To raise an error that will stop query resolution, use a custom block
60
- # to take this error and raise a new one which _doesn't_ descend from {GraphQL::ExecutionError},
61
- # such as `RuntimeError`.
62
- class GraphQL::Schema::TimeoutMiddleware::TimeoutError < GraphQL::ExecutionError
63
- def initialize(parent_type, field_defn)
64
- super("Timeout on #{parent_type.name}.#{field_defn.name}")
54
+ # This error is raised when a query exceeds `max_seconds`.
55
+ # Since it's a child of {GraphQL::ExecutionError},
56
+ # its message will be added to the response's `errors` key.
57
+ #
58
+ # To raise an error that will stop query resolution, use a custom block
59
+ # to take this error and raise a new one which _doesn't_ descend from {GraphQL::ExecutionError},
60
+ # such as `RuntimeError`.
61
+ class TimeoutError < GraphQL::ExecutionError
62
+ def initialize(parent_type, field_defn)
63
+ super("Timeout on #{parent_type.name}.#{field_defn.name}")
64
+ end
65
65
  end
66
66
  end
67
67
  end
@@ -24,7 +24,7 @@ module GraphQL
24
24
  # @return [Proc] A proc which will validate the input by calling `property_name` and asserting it is an instance of one of `allowed_classes`
25
25
  def self.assert_property(property_name, *allowed_classes)
26
26
  allowed_classes_message = allowed_classes.map(&:name).join(" or ")
27
- -> (obj) {
27
+ ->(obj) {
28
28
  property_value = obj.public_send(property_name)
29
29
  is_valid_value = allowed_classes.any? { |allowed_class| property_value.is_a?(allowed_class) }
30
30
  is_valid_value ? nil : "#{property_name} must return #{allowed_classes_message}, not #{property_value.class.name} (#{property_value.inspect})"
@@ -36,7 +36,7 @@ module GraphQL
36
36
  # @param to_class [Class] The class for values in the return value
37
37
  # @return [Proc] A proc to validate that validates the input by calling `property_name` and asserting that the return value is a Hash of `{from_class => to_class}` pairs
38
38
  def self.assert_property_mapping(property_name, from_class, to_class)
39
- -> (obj) {
39
+ ->(obj) {
40
40
  property_value = obj.public_send(property_name)
41
41
  error_message = nil
42
42
  if !property_value.is_a?(Hash)
@@ -56,7 +56,7 @@ module GraphQL
56
56
  # @param list_member_class [Class] The class which each member of the returned array should be an instance of
57
57
  # @return [Proc] A proc to validate the input by calling `property_name` and asserting that the return is an Array of `list_member_class` instances
58
58
  def self.assert_property_list_of(property_name, list_member_class)
59
- -> (obj) {
59
+ ->(obj) {
60
60
  property_value = obj.public_send(property_name)
61
61
  if !property_value.is_a?(Array)
62
62
  "#{property_name} must be an Array of #{list_member_class.name}, not a #{property_value.class.name} (#{property_value.inspect})"
@@ -72,7 +72,7 @@ module GraphQL
72
72
  end
73
73
 
74
74
  def self.assert_named_items_are_valid(item_name, get_items_proc)
75
- -> (type) {
75
+ ->(type) {
76
76
  items = get_items_proc.call(type)
77
77
  error_message = nil
78
78
  items.each do |item|
@@ -87,18 +87,18 @@ module GraphQL
87
87
  end
88
88
 
89
89
 
90
- FIELDS_ARE_VALID = Rules.assert_named_items_are_valid("field", -> (type) { type.all_fields })
90
+ FIELDS_ARE_VALID = Rules.assert_named_items_are_valid("field", ->(type) { type.all_fields })
91
91
 
92
- HAS_ONE_OR_MORE_POSSIBLE_TYPES = -> (type) {
92
+ HAS_ONE_OR_MORE_POSSIBLE_TYPES = ->(type) {
93
93
  type.possible_types.length >= 1 ? nil : "must have at least one possible type"
94
94
  }
95
95
 
96
96
  NAME_IS_STRING = Rules.assert_property(:name, String)
97
97
  DESCRIPTION_IS_STRING_OR_NIL = Rules.assert_property(:description, String, NilClass)
98
98
  ARGUMENTS_ARE_STRING_TO_ARGUMENT = Rules.assert_property_mapping(:arguments, String, GraphQL::Argument)
99
- ARGUMENTS_ARE_VALID = Rules.assert_named_items_are_valid("argument", -> (type) { type.arguments.values })
99
+ ARGUMENTS_ARE_VALID = Rules.assert_named_items_are_valid("argument", ->(type) { type.arguments.values })
100
100
 
101
- DEFAULT_VALUE_IS_VALID_FOR_TYPE = -> (type) {
101
+ DEFAULT_VALUE_IS_VALID_FOR_TYPE = ->(type) {
102
102
  if !type.default_value.nil?
103
103
  coerced_value = begin
104
104
  type.type.coerce_result(type.default_value)
@@ -114,7 +114,7 @@ module GraphQL
114
114
  end
115
115
  }
116
116
 
117
- TYPE_IS_VALID_INPUT_TYPE = -> (type) {
117
+ TYPE_IS_VALID_INPUT_TYPE = ->(type) {
118
118
  outer_type = type.type
119
119
  inner_type = outer_type.is_a?(GraphQL::BaseType) ? outer_type.unwrap : nil
120
120
 
@@ -126,7 +126,7 @@ module GraphQL
126
126
  end
127
127
  }
128
128
 
129
- SCHEMA_CAN_RESOLVE_TYPES = -> (schema) {
129
+ SCHEMA_CAN_RESOLVE_TYPES = ->(schema) {
130
130
  if schema.types.values.any? { |type| type.kind.resolves? } && schema.resolve_type_proc.nil?
131
131
  "schema contains Interfaces or Unions, so you must define a `resolve_type (obj, ctx) -> { ... }` function"
132
132
  else
@@ -134,7 +134,7 @@ module GraphQL
134
134
  end
135
135
  }
136
136
 
137
- SCHEMA_CAN_FETCH_IDS = -> (schema) {
137
+ SCHEMA_CAN_FETCH_IDS = ->(schema) {
138
138
  has_node_field = schema.query && schema.query.all_fields.any? { |f| f.metadata[:relay_node_field] }
139
139
  if has_node_field && schema.object_from_id_proc.nil?
140
140
  "schema contains `node(id:...)` field, so you must define a `object_from_id (id, ctx) -> { ... }` function"
@@ -143,7 +143,7 @@ module GraphQL
143
143
  end
144
144
  }
145
145
 
146
- SCHEMA_CAN_GENERATE_IDS = -> (schema) {
146
+ SCHEMA_CAN_GENERATE_IDS = ->(schema) {
147
147
  has_id_field = schema.types.values.any? { |t| t.kind.fields? && t.all_fields.any? { |f| f.resolve_proc.is_a?(GraphQL::Relay::GlobalIdResolve) } }
148
148
  if has_id_field && schema.id_from_object_proc.nil?
149
149
  "schema contains `global_id_field`, so you must define a `id_from_object (obj, type, ctx) -> { ... }` function"