graphql 0.19.3 → 0.19.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 (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"