graphql 1.13.17 → 2.0.20

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.

Potentially problematic release.


This version of graphql might be problematic. Click here for more details.

Files changed (260) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/install_generator.rb +1 -1
  3. data/lib/generators/graphql/relay.rb +3 -17
  4. data/lib/generators/graphql/templates/schema.erb +3 -0
  5. data/lib/graphql/analysis/ast/field_usage.rb +3 -1
  6. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
  7. data/lib/graphql/analysis/ast/query_complexity.rb +1 -1
  8. data/lib/graphql/analysis/ast/query_depth.rb +0 -1
  9. data/lib/graphql/analysis/ast/visitor.rb +43 -36
  10. data/lib/graphql/analysis/ast.rb +2 -12
  11. data/lib/graphql/analysis.rb +0 -7
  12. data/lib/graphql/backtrace/table.rb +2 -20
  13. data/lib/graphql/backtrace/tracer.rb +2 -3
  14. data/lib/graphql/backtrace.rb +2 -8
  15. data/lib/graphql/dataloader/null_dataloader.rb +3 -1
  16. data/lib/graphql/dataloader/source.rb +9 -0
  17. data/lib/graphql/dataloader.rb +4 -1
  18. data/lib/graphql/dig.rb +1 -1
  19. data/lib/graphql/execution/errors.rb +12 -82
  20. data/lib/graphql/execution/interpreter/resolve.rb +26 -0
  21. data/lib/graphql/execution/interpreter/runtime.rb +159 -120
  22. data/lib/graphql/execution/interpreter.rb +187 -78
  23. data/lib/graphql/execution/lazy.rb +7 -21
  24. data/lib/graphql/execution/lookahead.rb +44 -40
  25. data/lib/graphql/execution/multiplex.rb +3 -174
  26. data/lib/graphql/execution.rb +11 -4
  27. data/lib/graphql/introspection/directive_type.rb +2 -2
  28. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  29. data/lib/graphql/introspection/entry_points.rb +2 -15
  30. data/lib/graphql/introspection/field_type.rb +1 -1
  31. data/lib/graphql/introspection/schema_type.rb +2 -2
  32. data/lib/graphql/introspection/type_type.rb +13 -6
  33. data/lib/graphql/introspection.rb +4 -3
  34. data/lib/graphql/language/document_from_schema_definition.rb +18 -35
  35. data/lib/graphql/language/lexer.rb +216 -1488
  36. data/lib/graphql/language/nodes.rb +65 -39
  37. data/lib/graphql/language/parser.rb +376 -364
  38. data/lib/graphql/language/parser.y +49 -44
  39. data/lib/graphql/language/printer.rb +37 -21
  40. data/lib/graphql/language/visitor.rb +191 -83
  41. data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
  42. data/lib/graphql/pagination/array_connection.rb +4 -2
  43. data/lib/graphql/pagination/connection.rb +31 -4
  44. data/lib/graphql/pagination/connections.rb +3 -28
  45. data/lib/graphql/pagination/relation_connection.rb +2 -0
  46. data/lib/graphql/query/context.rb +155 -196
  47. data/lib/graphql/query/input_validation_result.rb +1 -1
  48. data/lib/graphql/query/null_context.rb +0 -3
  49. data/lib/graphql/query/validation_pipeline.rb +10 -34
  50. data/lib/graphql/query/variables.rb +7 -20
  51. data/lib/graphql/query.rb +32 -42
  52. data/lib/graphql/railtie.rb +0 -104
  53. data/lib/graphql/rake_task/validate.rb +1 -1
  54. data/lib/graphql/rake_task.rb +29 -1
  55. data/lib/graphql/relay/range_add.rb +9 -20
  56. data/lib/graphql/relay.rb +0 -15
  57. data/lib/graphql/schema/addition.rb +7 -9
  58. data/lib/graphql/schema/argument.rb +36 -43
  59. data/lib/graphql/schema/build_from_definition.rb +32 -18
  60. data/lib/graphql/schema/directive/one_of.rb +12 -0
  61. data/lib/graphql/schema/directive/transform.rb +1 -1
  62. data/lib/graphql/schema/directive.rb +12 -23
  63. data/lib/graphql/schema/enum.rb +28 -39
  64. data/lib/graphql/schema/enum_value.rb +5 -25
  65. data/lib/graphql/schema/field/connection_extension.rb +4 -0
  66. data/lib/graphql/schema/field.rb +237 -339
  67. data/lib/graphql/schema/input_object.rb +56 -67
  68. data/lib/graphql/schema/interface.rb +0 -35
  69. data/lib/graphql/schema/introspection_system.rb +3 -8
  70. data/lib/graphql/schema/late_bound_type.rb +8 -2
  71. data/lib/graphql/schema/list.rb +0 -6
  72. data/lib/graphql/schema/loader.rb +1 -2
  73. data/lib/graphql/schema/member/base_dsl_methods.rb +17 -19
  74. data/lib/graphql/schema/member/build_type.rb +5 -7
  75. data/lib/graphql/schema/member/has_arguments.rb +146 -55
  76. data/lib/graphql/schema/member/has_ast_node.rb +12 -0
  77. data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
  78. data/lib/graphql/schema/member/has_directives.rb +81 -59
  79. data/lib/graphql/schema/member/has_fields.rb +17 -4
  80. data/lib/graphql/schema/member/has_interfaces.rb +49 -10
  81. data/lib/graphql/schema/member/has_validators.rb +31 -5
  82. data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
  83. data/lib/graphql/schema/member/type_system_helpers.rb +17 -0
  84. data/lib/graphql/schema/member/validates_input.rb +1 -1
  85. data/lib/graphql/schema/member.rb +0 -6
  86. data/lib/graphql/schema/mutation.rb +0 -9
  87. data/lib/graphql/schema/non_null.rb +1 -7
  88. data/lib/graphql/schema/object.rb +15 -52
  89. data/lib/graphql/schema/relay_classic_mutation.rb +53 -42
  90. data/lib/graphql/schema/resolver/has_payload_type.rb +20 -10
  91. data/lib/graphql/schema/resolver.rb +41 -42
  92. data/lib/graphql/schema/scalar.rb +7 -22
  93. data/lib/graphql/schema/subscription.rb +0 -7
  94. data/lib/graphql/schema/timeout.rb +24 -28
  95. data/lib/graphql/schema/type_membership.rb +3 -0
  96. data/lib/graphql/schema/union.rb +10 -17
  97. data/lib/graphql/schema/warden.rb +34 -8
  98. data/lib/graphql/schema/wrapper.rb +0 -5
  99. data/lib/graphql/schema.rb +241 -973
  100. data/lib/graphql/static_validation/all_rules.rb +1 -0
  101. data/lib/graphql/static_validation/base_visitor.rb +4 -21
  102. data/lib/graphql/static_validation/definition_dependencies.rb +7 -1
  103. data/lib/graphql/static_validation/error.rb +2 -2
  104. data/lib/graphql/static_validation/literal_validator.rb +19 -1
  105. data/lib/graphql/static_validation/rules/directives_are_defined.rb +11 -5
  106. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +12 -12
  107. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  108. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  109. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +12 -6
  110. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +1 -1
  111. data/lib/graphql/static_validation/validator.rb +3 -25
  112. data/lib/graphql/static_validation.rb +0 -2
  113. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +7 -1
  114. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +38 -1
  115. data/lib/graphql/subscriptions/event.rb +3 -8
  116. data/lib/graphql/subscriptions/instrumentation.rb +0 -51
  117. data/lib/graphql/subscriptions.rb +32 -20
  118. data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
  119. data/lib/graphql/tracing/appoptics_trace.rb +231 -0
  120. data/lib/graphql/tracing/appsignal_trace.rb +71 -0
  121. data/lib/graphql/tracing/data_dog_trace.rb +148 -0
  122. data/lib/graphql/tracing/data_dog_tracing.rb +2 -0
  123. data/lib/graphql/tracing/new_relic_trace.rb +75 -0
  124. data/lib/graphql/tracing/notifications_trace.rb +41 -0
  125. data/lib/graphql/tracing/platform_trace.rb +107 -0
  126. data/lib/graphql/tracing/platform_tracing.rb +26 -40
  127. data/lib/graphql/tracing/prometheus_trace.rb +89 -0
  128. data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
  129. data/lib/graphql/tracing/scout_trace.rb +72 -0
  130. data/lib/graphql/tracing/statsd_trace.rb +56 -0
  131. data/lib/graphql/tracing.rb +136 -40
  132. data/lib/graphql/type_kinds.rb +6 -3
  133. data/lib/graphql/types/iso_8601_date.rb +4 -1
  134. data/lib/graphql/types/iso_8601_date_time.rb +4 -0
  135. data/lib/graphql/types/relay/base_connection.rb +16 -6
  136. data/lib/graphql/types/relay/connection_behaviors.rb +29 -27
  137. data/lib/graphql/types/relay/edge_behaviors.rb +16 -5
  138. data/lib/graphql/types/relay/node_behaviors.rb +12 -2
  139. data/lib/graphql/types/relay/page_info_behaviors.rb +7 -2
  140. data/lib/graphql/types/relay.rb +0 -3
  141. data/lib/graphql/types/string.rb +1 -1
  142. data/lib/graphql/version.rb +1 -1
  143. data/lib/graphql.rb +13 -74
  144. metadata +30 -133
  145. data/lib/graphql/analysis/analyze_query.rb +0 -98
  146. data/lib/graphql/analysis/field_usage.rb +0 -45
  147. data/lib/graphql/analysis/max_query_complexity.rb +0 -26
  148. data/lib/graphql/analysis/max_query_depth.rb +0 -26
  149. data/lib/graphql/analysis/query_complexity.rb +0 -88
  150. data/lib/graphql/analysis/query_depth.rb +0 -43
  151. data/lib/graphql/analysis/reducer_state.rb +0 -48
  152. data/lib/graphql/argument.rb +0 -131
  153. data/lib/graphql/authorization.rb +0 -82
  154. data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
  155. data/lib/graphql/backwards_compatibility.rb +0 -61
  156. data/lib/graphql/base_type.rb +0 -232
  157. data/lib/graphql/boolean_type.rb +0 -2
  158. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  159. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  160. data/lib/graphql/compatibility/execution_specification.rb +0 -436
  161. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  162. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
  163. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  164. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  165. data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
  166. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
  167. data/lib/graphql/compatibility.rb +0 -5
  168. data/lib/graphql/define/assign_argument.rb +0 -12
  169. data/lib/graphql/define/assign_connection.rb +0 -13
  170. data/lib/graphql/define/assign_enum_value.rb +0 -18
  171. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  172. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  173. data/lib/graphql/define/assign_object_field.rb +0 -42
  174. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  175. data/lib/graphql/define/instance_definable.rb +0 -255
  176. data/lib/graphql/define/no_definition_error.rb +0 -7
  177. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  178. data/lib/graphql/define/type_definer.rb +0 -31
  179. data/lib/graphql/define.rb +0 -31
  180. data/lib/graphql/deprecated_dsl.rb +0 -55
  181. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  182. data/lib/graphql/directive/include_directive.rb +0 -2
  183. data/lib/graphql/directive/skip_directive.rb +0 -2
  184. data/lib/graphql/directive.rb +0 -107
  185. data/lib/graphql/enum_type.rb +0 -133
  186. data/lib/graphql/execution/execute.rb +0 -333
  187. data/lib/graphql/execution/flatten.rb +0 -40
  188. data/lib/graphql/execution/instrumentation.rb +0 -92
  189. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  190. data/lib/graphql/execution/typecast.rb +0 -50
  191. data/lib/graphql/field/resolve.rb +0 -59
  192. data/lib/graphql/field.rb +0 -226
  193. data/lib/graphql/float_type.rb +0 -2
  194. data/lib/graphql/function.rb +0 -128
  195. data/lib/graphql/id_type.rb +0 -2
  196. data/lib/graphql/input_object_type.rb +0 -138
  197. data/lib/graphql/int_type.rb +0 -2
  198. data/lib/graphql/interface_type.rb +0 -72
  199. data/lib/graphql/internal_representation/document.rb +0 -27
  200. data/lib/graphql/internal_representation/node.rb +0 -206
  201. data/lib/graphql/internal_representation/print.rb +0 -51
  202. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  203. data/lib/graphql/internal_representation/scope.rb +0 -88
  204. data/lib/graphql/internal_representation/visit.rb +0 -36
  205. data/lib/graphql/internal_representation.rb +0 -7
  206. data/lib/graphql/language/lexer.rl +0 -260
  207. data/lib/graphql/list_type.rb +0 -80
  208. data/lib/graphql/non_null_type.rb +0 -71
  209. data/lib/graphql/object_type.rb +0 -130
  210. data/lib/graphql/query/arguments.rb +0 -189
  211. data/lib/graphql/query/arguments_cache.rb +0 -24
  212. data/lib/graphql/query/executor.rb +0 -52
  213. data/lib/graphql/query/literal_input.rb +0 -136
  214. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  215. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  216. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  217. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  218. data/lib/graphql/query/serial_execution.rb +0 -40
  219. data/lib/graphql/relay/array_connection.rb +0 -83
  220. data/lib/graphql/relay/base_connection.rb +0 -189
  221. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  222. data/lib/graphql/relay/connection_resolve.rb +0 -43
  223. data/lib/graphql/relay/connection_type.rb +0 -54
  224. data/lib/graphql/relay/edge.rb +0 -27
  225. data/lib/graphql/relay/edge_type.rb +0 -19
  226. data/lib/graphql/relay/edges_instrumentation.rb +0 -39
  227. data/lib/graphql/relay/global_id_resolve.rb +0 -17
  228. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  229. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  230. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  231. data/lib/graphql/relay/mutation/result.rb +0 -38
  232. data/lib/graphql/relay/mutation.rb +0 -106
  233. data/lib/graphql/relay/node.rb +0 -39
  234. data/lib/graphql/relay/page_info.rb +0 -7
  235. data/lib/graphql/relay/relation_connection.rb +0 -188
  236. data/lib/graphql/relay/type_extensions.rb +0 -32
  237. data/lib/graphql/scalar_type.rb +0 -91
  238. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  239. data/lib/graphql/schema/default_parse_error.rb +0 -10
  240. data/lib/graphql/schema/default_type_error.rb +0 -17
  241. data/lib/graphql/schema/member/accepts_definition.rb +0 -164
  242. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -58
  243. data/lib/graphql/schema/member/instrumentation.rb +0 -131
  244. data/lib/graphql/schema/middleware_chain.rb +0 -82
  245. data/lib/graphql/schema/possible_types.rb +0 -44
  246. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  247. data/lib/graphql/schema/timeout_middleware.rb +0 -88
  248. data/lib/graphql/schema/traversal.rb +0 -228
  249. data/lib/graphql/schema/validation.rb +0 -313
  250. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  251. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  252. data/lib/graphql/string_type.rb +0 -2
  253. data/lib/graphql/subscriptions/subscription_root.rb +0 -76
  254. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  255. data/lib/graphql/types/relay/default_relay.rb +0 -31
  256. data/lib/graphql/types/relay/node_field.rb +0 -24
  257. data/lib/graphql/types/relay/nodes_field.rb +0 -43
  258. data/lib/graphql/union_type.rb +0 -115
  259. data/lib/graphql/upgrader/member.rb +0 -937
  260. data/lib/graphql/upgrader/schema.rb +0 -38
@@ -2,8 +2,6 @@
2
2
  module GraphQL
3
3
  class Schema
4
4
  class Argument
5
- include GraphQL::Schema::Member::CachedGraphQLDefinition
6
- include GraphQL::Schema::Member::AcceptsDefinition
7
5
  include GraphQL::Schema::Member::HasPath
8
6
  include GraphQL::Schema::Member::HasAstNode
9
7
  include GraphQL::Schema::Member::HasDirectives
@@ -20,8 +18,14 @@ module GraphQL
20
18
  # @return [GraphQL::Schema::Field, Class] The field or input object this argument belongs to
21
19
  attr_reader :owner
22
20
 
23
- # @return [Symbol] A method to call to transform this value before sending it to field resolution method
24
- attr_reader :prepare
21
+ # @param new_prepare [Method, Proc]
22
+ # @return [Symbol] A method or proc to call to transform this value before sending it to field resolution method
23
+ def prepare(new_prepare = NO_DEFAULT)
24
+ if new_prepare != NO_DEFAULT
25
+ @prepare = new_prepare
26
+ end
27
+ @prepare
28
+ end
25
29
 
26
30
  # @return [Symbol] This argument's name in Ruby keyword arguments
27
31
  attr_reader :keyword
@@ -44,12 +48,11 @@ module GraphQL
44
48
  # @param prepare [Symbol] A method to call to transform this argument's valuebefore sending it to field resolution
45
49
  # @param camelize [Boolean] if true, the name will be camelized when building the schema
46
50
  # @param from_resolver [Boolean] if true, a Resolver class defined this argument
47
- # @param method_access [Boolean] If false, don't build method access on legacy {Query::Arguments} instances.
48
51
  # @param directives [Hash{Class => Hash}]
49
52
  # @param deprecation_reason [String]
50
53
  # @param validates [Hash, nil] Options for building validators, if any should be applied
51
54
  # @param replace_null_with_default [Boolean] if `true`, incoming values of `null` will be replaced with the configured `default_value`
52
- def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value: NO_DEFAULT, as: nil, from_resolver: false, camelize: true, prepare: nil, method_access: true, owner:, validates: nil, directives: nil, deprecation_reason: nil, replace_null_with_default: false, &definition_block)
55
+ def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value: NO_DEFAULT, as: nil, from_resolver: false, camelize: true, prepare: nil, owner:, validates: nil, directives: nil, deprecation_reason: nil, replace_null_with_default: false, &definition_block)
53
56
  arg_name ||= name
54
57
  @name = -(camelize ? Member::BuildType.camelize(arg_name.to_s) : arg_name.to_s)
55
58
  @type_expr = type_expr || type
@@ -70,7 +73,6 @@ module GraphQL
70
73
  @prepare = prepare
71
74
  @ast_node = ast_node
72
75
  @from_resolver = from_resolver
73
- @method_access = method_access
74
76
  self.deprecation_reason = deprecation_reason
75
77
 
76
78
  if directives
@@ -79,7 +81,10 @@ module GraphQL
79
81
  end
80
82
  end
81
83
 
82
- self.validates(validates)
84
+ if validates && !validates.empty?
85
+ self.validates(validates)
86
+ end
87
+
83
88
  if required == :nullable
84
89
  self.owner.validates(required: { argument: arg_name })
85
90
  end
@@ -97,8 +102,14 @@ module GraphQL
97
102
  "#<#{self.class} #{path}: #{type.to_type_signature}#{description ? " @description=#{description.inspect}" : ""}>"
98
103
  end
99
104
 
105
+ # @param default_value [Object] The value to use when the client doesn't provide one
100
106
  # @return [Object] the value used when the client doesn't provide a value for this argument
101
- attr_reader :default_value
107
+ def default_value(new_default_value = NO_DEFAULT)
108
+ if new_default_value != NO_DEFAULT
109
+ @default_value = new_default_value
110
+ end
111
+ @default_value
112
+ end
102
113
 
103
114
  # @return [Boolean] True if this argument has a default value
104
115
  def default_value?
@@ -138,10 +149,6 @@ module GraphQL
138
149
  true
139
150
  end
140
151
 
141
- def accessible?(context)
142
- true
143
- end
144
-
145
152
  def authorized?(obj, value, ctx)
146
153
  authorized_as_type?(obj, value, ctx, as_type: type)
147
154
  end
@@ -169,26 +176,6 @@ module GraphQL
169
176
  true
170
177
  end
171
178
 
172
- prepend Schema::Member::CachedGraphQLDefinition::DeprecatedToGraphQL
173
-
174
- def to_graphql
175
- argument = GraphQL::Argument.new
176
- argument.name = @name
177
- argument.type = -> { type }
178
- argument.description = @description
179
- argument.metadata[:type_class] = self
180
- argument.as = @as
181
- argument.ast_node = ast_node
182
- argument.method_access = @method_access
183
- if NO_DEFAULT != @default_value
184
- argument.default_value = @default_value
185
- end
186
- if self.deprecation_reason
187
- argument.deprecation_reason = self.deprecation_reason
188
- end
189
- argument
190
- end
191
-
192
179
  def type=(new_type)
193
180
  validate_input_type(new_type)
194
181
  # This isn't true for LateBoundTypes, but we can assume those will
@@ -271,29 +258,35 @@ module GraphQL
271
258
  end
272
259
 
273
260
  loaded_value = nil
274
- coerced_value = context.schema.error_handler.with_error_handling(context) do
261
+ coerced_value = begin
275
262
  type.coerce_input(value, context)
263
+ rescue StandardError => err
264
+ context.schema.handle_or_reraise(context, err)
276
265
  end
277
266
 
278
267
  # If this isn't lazy, then the block returns eagerly and assigns the result here
279
268
  # If it _is_ lazy, then we write the lazy to the hash, then update it later
280
269
  argument_values[arg_key] = context.schema.after_lazy(coerced_value) do |resolved_coerced_value|
270
+ owner.validate_directive_argument(self, resolved_coerced_value)
271
+ prepared_value = begin
272
+ prepare_value(parent_object, resolved_coerced_value, context: context)
273
+ rescue StandardError => err
274
+ context.schema.handle_or_reraise(context, err)
275
+ end
276
+
281
277
  if loads && !from_resolver?
282
- loaded_value = context.query.with_error_handling do
283
- load_and_authorize_value(owner, coerced_value, context)
278
+ loaded_value = begin
279
+ load_and_authorize_value(owner, prepared_value, context)
280
+ rescue StandardError => err
281
+ context.schema.handle_or_reraise(context, err)
284
282
  end
285
283
  end
286
284
 
287
- maybe_loaded_value = loaded_value || resolved_coerced_value
285
+ maybe_loaded_value = loaded_value || prepared_value
288
286
  context.schema.after_lazy(maybe_loaded_value) do |resolved_loaded_value|
289
- owner.validate_directive_argument(self, resolved_loaded_value)
290
- prepared_value = context.schema.error_handler.with_error_handling(context) do
291
- prepare_value(parent_object, resolved_loaded_value, context: context)
292
- end
293
-
294
287
  # TODO code smell to access such a deeply-nested constant in a distant module
295
288
  argument_values[arg_key] = GraphQL::Execution::Interpreter::ArgumentValue.new(
296
- value: prepared_value,
289
+ value: resolved_loaded_value,
297
290
  definition: self,
298
291
  default_used: default_used,
299
292
  )
@@ -6,16 +6,16 @@ module GraphQL
6
6
  module BuildFromDefinition
7
7
  class << self
8
8
  # @see {Schema.from_definition}
9
- def from_definition(definition_string, parser: GraphQL.default_parser, **kwargs)
10
- from_document(parser.parse(definition_string), **kwargs)
9
+ def from_definition(schema_superclass, definition_string, parser: GraphQL.default_parser, **kwargs)
10
+ from_document(schema_superclass, parser.parse(definition_string), **kwargs)
11
11
  end
12
12
 
13
- def from_definition_path(definition_path, parser: GraphQL.default_parser, **kwargs)
14
- from_document(parser.parse_file(definition_path), **kwargs)
13
+ def from_definition_path(schema_superclass, definition_path, parser: GraphQL.default_parser, **kwargs)
14
+ from_document(schema_superclass, parser.parse_file(definition_path), **kwargs)
15
15
  end
16
16
 
17
- def from_document(document, default_resolve:, using: {}, relay: false)
18
- Builder.build(document, default_resolve: default_resolve || {}, relay: relay, using: using)
17
+ def from_document(schema_superclass, document, default_resolve:, using: {}, relay: false)
18
+ Builder.build(schema_superclass, document, default_resolve: default_resolve || {}, relay: relay, using: using)
19
19
  end
20
20
  end
21
21
 
@@ -23,7 +23,7 @@ module GraphQL
23
23
  module Builder
24
24
  extend self
25
25
 
26
- def build(document, default_resolve:, using: {}, relay:)
26
+ def build(schema_superclass, document, default_resolve:, using: {}, relay:)
27
27
  raise InvalidDocumentError.new('Must provide a document ast.') if !document || !document.is_a?(GraphQL::Language::Nodes::Document)
28
28
 
29
29
  if default_resolve.is_a?(Hash)
@@ -36,7 +36,7 @@ module GraphQL
36
36
  end
37
37
  schema_definition = schema_defns.first
38
38
  types = {}
39
- directives = {}
39
+ directives = schema_superclass.directives.dup
40
40
  type_resolver = build_resolve_type(types, directives, ->(type_name) { types[type_name] ||= Schema::LateBoundType.new(type_name)})
41
41
  # Make a different type resolver because we need to coerce directive arguments
42
42
  # _while_ building the schema.
@@ -55,21 +55,24 @@ module GraphQL
55
55
  end
56
56
  })
57
57
 
58
+ directives.merge!(GraphQL::Schema.default_directives)
58
59
  document.definitions.each do |definition|
59
60
  if definition.is_a?(GraphQL::Language::Nodes::DirectiveDefinition)
60
61
  directives[definition.name] = build_directive(definition, directive_type_resolver)
61
62
  end
62
63
  end
63
64
 
64
- directives = GraphQL::Schema.default_directives.merge(directives)
65
-
66
65
  # In case any directives referenced built-in types for their arguments:
67
66
  replace_late_bound_types_with_built_in(types)
68
67
 
68
+ schema_extensions = nil
69
69
  document.definitions.each do |definition|
70
70
  case definition
71
71
  when GraphQL::Language::Nodes::SchemaDefinition, GraphQL::Language::Nodes::DirectiveDefinition
72
72
  nil # already handled
73
+ when GraphQL::Language::Nodes::SchemaExtension
74
+ schema_extensions ||= []
75
+ schema_extensions << definition
73
76
  else
74
77
  # It's possible that this was already loaded by the directives
75
78
  prev_type = types[definition.name]
@@ -104,7 +107,7 @@ module GraphQL
104
107
 
105
108
  raise InvalidDocumentError.new('Must provide schema definition with query type or a type named Query.') unless query_root_type
106
109
 
107
- Class.new(GraphQL::Schema) do
110
+ schema_class = Class.new(schema_superclass) do
108
111
  begin
109
112
  # Add these first so that there's some chance of resolving late-bound types
110
113
  orphan_types types.values
@@ -158,6 +161,14 @@ module GraphQL
158
161
  child_class.definition_default_resolve = self.definition_default_resolve
159
162
  end
160
163
  end
164
+
165
+ if schema_extensions
166
+ schema_extensions.each do |ext|
167
+ build_directives(schema_class, ext, type_resolver)
168
+ end
169
+ end
170
+
171
+ schema_class
161
172
  end
162
173
 
163
174
  NullResolveType = ->(type, obj, ctx) {
@@ -197,13 +208,18 @@ module GraphQL
197
208
 
198
209
  def build_directives(definition, ast_node, type_resolver)
199
210
  dirs = prepare_directives(ast_node, type_resolver)
200
- dirs.each do |dir_class, options|
201
- definition.directive(dir_class, **options)
211
+ dirs.each do |(dir_class, options)|
212
+ if definition.respond_to?(:schema_directive)
213
+ # it's a schema
214
+ definition.schema_directive(dir_class, **options)
215
+ else
216
+ definition.directive(dir_class, **options)
217
+ end
202
218
  end
203
219
  end
204
220
 
205
221
  def prepare_directives(ast_node, type_resolver)
206
- dirs = {}
222
+ dirs = []
207
223
  ast_node.directives.each do |dir_node|
208
224
  if dir_node.name == "deprecated"
209
225
  # This is handled using `deprecation_reason`
@@ -211,10 +227,10 @@ module GraphQL
211
227
  else
212
228
  dir_class = type_resolver.call(dir_node.name)
213
229
  if dir_class.nil?
214
- raise ArgumentError, "No definition for @#{dir_node.name} on #{ast_node.name} at #{ast_node.line}:#{ast_node.col}"
230
+ raise ArgumentError, "No definition for @#{dir_node.name} #{ast_node.respond_to?(:name) ? "on #{ast_node.name} " : ""}at #{ast_node.line}:#{ast_node.col}"
215
231
  end
216
232
  options = args_to_kwargs(dir_class, dir_node)
217
- dirs[dir_class] = options
233
+ dirs << [dir_class, options]
218
234
  end
219
235
  end
220
236
  dirs
@@ -365,7 +381,6 @@ module GraphQL
365
381
  deprecation_reason: builder.build_deprecation_reason(argument_defn.directives),
366
382
  ast_node: argument_defn,
367
383
  camelize: false,
368
- method_access: false,
369
384
  directives: prepare_directives(argument_defn, type_resolver),
370
385
  **default_value_kwargs
371
386
  )
@@ -391,7 +406,6 @@ module GraphQL
391
406
  graphql_name(interface_type_definition.name)
392
407
  description(interface_type_definition.description)
393
408
  interface_type_definition.interfaces.each do |interface_name|
394
- "Implements: #{interface_type_definition} -> #{interface_name}"
395
409
  interface_defn = type_resolver.call(interface_name)
396
410
  implements(interface_defn)
397
411
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ class Schema
4
+ class Directive < GraphQL::Schema::Member
5
+ class OneOf < GraphQL::Schema::Directive
6
+ description "Requires that exactly one field must be supplied and that field must not be `null`."
7
+ locations(GraphQL::Schema::Directive::INPUT_OBJECT)
8
+ default_directive true
9
+ end
10
+ end
11
+ end
12
+ end
@@ -39,7 +39,7 @@ module GraphQL
39
39
  transform_name = arguments[:by]
40
40
  if TRANSFORMS.include?(transform_name) && return_value.respond_to?(transform_name)
41
41
  return_value = return_value.public_send(transform_name)
42
- response = context.namespace(:interpreter)[:runtime].final_result
42
+ response = context.namespace(:interpreter_runtime)[:runtime].final_result
43
43
  *keys, last = path
44
44
  keys.each do |key|
45
45
  if response && (response = response[key])
@@ -8,7 +8,7 @@ module GraphQL
8
8
  # - {.resolve}: Wraps field resolution (so it should call `yield` to continue)
9
9
  class Directive < GraphQL::Schema::Member
10
10
  extend GraphQL::Schema::Member::HasArguments
11
- extend GraphQL::Schema::Member::AcceptsDefinition
11
+ extend GraphQL::Schema::Member::HasArguments::HasDirectiveArguments
12
12
 
13
13
  class << self
14
14
  # Directives aren't types, they don't have kinds.
@@ -22,9 +22,9 @@ module GraphQL
22
22
  # but downcase the first letter.
23
23
  def default_graphql_name
24
24
  @default_graphql_name ||= begin
25
- camelized_name = super
25
+ camelized_name = super.dup
26
26
  camelized_name[0] = camelized_name[0].downcase
27
- camelized_name
27
+ -camelized_name
28
28
  end
29
29
  end
30
30
 
@@ -55,26 +55,6 @@ module GraphQL
55
55
  default_directive
56
56
  end
57
57
 
58
- prepend Schema::Member::CachedGraphQLDefinition::DeprecatedToGraphQL
59
-
60
- def to_graphql
61
- defn = GraphQL::Directive.new
62
- defn.name = self.graphql_name
63
- defn.description = self.description
64
- defn.locations = self.locations
65
- defn.default_directive = self.default_directive
66
- defn.ast_node = ast_node
67
- defn.metadata[:type_class] = self
68
- all_argument_definitions.each do |arg_defn|
69
- arg_graphql = arg_defn.to_graphql(silence_deprecation_warning: true)
70
- defn.arguments[arg_graphql.name] = arg_graphql # rubocop:disable Development/ContextIsPassedCop -- legacy-related
71
- end
72
- # Make a reference to a classic-style Arguments class
73
- defn.arguments_class = GraphQL::Query::Arguments.construct_arguments_class(defn)
74
-
75
- defn
76
- end
77
-
78
58
  # If false, this part of the query won't be evaluated
79
59
  def include?(_object, arguments, context)
80
60
  static_include?(arguments, context)
@@ -114,6 +94,15 @@ module GraphQL
114
94
  def repeatable(new_value)
115
95
  @repeatable = new_value
116
96
  end
97
+
98
+ private
99
+
100
+ def inherited(subclass)
101
+ super
102
+ subclass.class_eval do
103
+ @default_graphql_name ||= nil
104
+ end
105
+ end
117
106
  end
118
107
 
119
108
  # @return [GraphQL::Schema::Field, GraphQL::Schema::Argument, Class, Module]
@@ -1,29 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphQL
4
- # Extend this class to define GraphQL enums in your schema.
5
- #
6
- # By default, GraphQL enum values are translated into Ruby strings.
7
- # You can provide a custom value with the `value:` keyword.
8
- #
9
- # @example
10
- # # equivalent to
11
- # # enum PizzaTopping {
12
- # # MUSHROOMS
13
- # # ONIONS
14
- # # PEPPERS
15
- # # }
16
- # class PizzaTopping < GraphQL::Enum
17
- # value :MUSHROOMS
18
- # value :ONIONS
19
- # value :PEPPERS
20
- # end
21
4
  class Schema
5
+ # Extend this class to define GraphQL enums in your schema.
6
+ #
7
+ # By default, GraphQL enum values are translated into Ruby strings.
8
+ # You can provide a custom value with the `value:` keyword.
9
+ #
10
+ # @example
11
+ # # equivalent to
12
+ # # enum PizzaTopping {
13
+ # # MUSHROOMS
14
+ # # ONIONS
15
+ # # PEPPERS
16
+ # # }
17
+ # class PizzaTopping < GraphQL::Enum
18
+ # value :MUSHROOMS
19
+ # value :ONIONS
20
+ # value :PEPPERS
21
+ # end
22
22
  class Enum < GraphQL::Schema::Member
23
- extend GraphQL::Schema::Member::AcceptsDefinition
24
23
  extend GraphQL::Schema::Member::ValidatesInput
25
24
 
26
- class UnresolvedValueError < GraphQL::EnumType::UnresolvedValueError
25
+ class UnresolvedValueError < GraphQL::Error
27
26
  def initialize(value:, enum:, context:)
28
27
  fix_message = ", but this isn't a valid value for `#{enum.graphql_name}`. Update the field or resolver to return one of `#{enum.graphql_name}`'s values instead."
29
28
  message = if (cp = context[:current_path]) && (cf = context[:current_field])
@@ -35,6 +34,13 @@ module GraphQL
35
34
  end
36
35
  end
37
36
 
37
+ class MissingValuesError < GraphQL::Error
38
+ def initialize(enum_type)
39
+ @enum_type = enum_type
40
+ super("Enum types require at least one value, but #{enum_type.graphql_name} didn't provide any for this query. Make sure at least one value is defined and visible for this query.")
41
+ end
42
+ end
43
+
38
44
  class << self
39
45
  # Define a value for this enum
40
46
  # @param graphql_name [String, Symbol] the GraphQL value for this, usually `SCREAMING_CASE`
@@ -108,22 +114,6 @@ module GraphQL
108
114
  enum_values(context).each_with_object({}) { |val, obj| obj[val.graphql_name] = val }
109
115
  end
110
116
 
111
- prepend Schema::Member::CachedGraphQLDefinition::DeprecatedToGraphQL
112
-
113
- # @return [GraphQL::EnumType]
114
- def to_graphql
115
- enum_type = GraphQL::EnumType.new
116
- enum_type.name = graphql_name
117
- enum_type.description = description
118
- enum_type.introspection = introspection
119
- enum_type.ast_node = ast_node
120
- values.each do |name, val|
121
- enum_type.add_value(val.deprecated_to_graphql)
122
- end
123
- enum_type.metadata[:type_class] = self
124
- enum_type
125
- end
126
-
127
117
  # @return [Class] for handling `value(...)` inputs and building `GraphQL::Enum::EnumValue`s out of them
128
118
  def enum_value_class(new_enum_value_class = nil)
129
119
  if new_enum_value_class
@@ -140,15 +130,14 @@ module GraphQL
140
130
  end
141
131
 
142
132
  def validate_non_null_input(value_name, ctx, max_errors: nil)
143
- result = GraphQL::Query::InputValidationResult.new
144
133
  allowed_values = ctx.warden.enum_values(self)
145
134
  matching_value = allowed_values.find { |v| v.graphql_name == value_name }
146
135
 
147
136
  if matching_value.nil?
148
- result.add_problem("Expected #{GraphQL::Language.serialize(value_name)} to be one of: #{allowed_values.map(&:graphql_name).join(', ')}")
137
+ GraphQL::Query::InputValidationResult.from_problem("Expected #{GraphQL::Language.serialize(value_name)} to be one of: #{allowed_values.map(&:graphql_name).join(', ')}")
138
+ else
139
+ nil
149
140
  end
150
-
151
- result
152
141
  end
153
142
 
154
143
  def coerce_result(value, ctx)
@@ -13,12 +13,6 @@ module GraphQL
13
13
  # # arguments to `value(...)` in Enum classes are passed here
14
14
  # super
15
15
  # end
16
- #
17
- # def to_graphql
18
- # enum_value = super
19
- # # customize the derived GraphQL::EnumValue here
20
- # enum_value
21
- # end
22
16
  # end
23
17
  #
24
18
  # class BaseEnum < GraphQL::Schema::Enum
@@ -26,23 +20,24 @@ module GraphQL
26
20
  # enum_value_class CustomEnumValue
27
21
  # end
28
22
  class EnumValue < GraphQL::Schema::Member
29
- include GraphQL::Schema::Member::CachedGraphQLDefinition
30
- include GraphQL::Schema::Member::AcceptsDefinition
31
23
  include GraphQL::Schema::Member::HasPath
32
24
  include GraphQL::Schema::Member::HasAstNode
33
25
  include GraphQL::Schema::Member::HasDirectives
34
26
  include GraphQL::Schema::Member::HasDeprecationReason
35
27
 
28
+ UNDEFINED_VALUE = Object.new.freeze
29
+ private_constant :UNDEFINED_VALUE
30
+
36
31
  attr_reader :graphql_name
37
32
 
38
33
  # @return [Class] The enum type that owns this value
39
34
  attr_reader :owner
40
35
 
41
- def initialize(graphql_name, desc = nil, owner:, ast_node: nil, directives: nil, description: nil, value: nil, deprecation_reason: nil, &block)
36
+ def initialize(graphql_name, desc = nil, owner:, ast_node: nil, directives: nil, description: nil, value: UNDEFINED_VALUE, deprecation_reason: nil, &block)
42
37
  @graphql_name = graphql_name.to_s
43
38
  GraphQL::NameValidator.validate!(@graphql_name)
44
39
  @description = desc || description
45
- @value = value.nil? ? @graphql_name : value
40
+ @value = value === UNDEFINED_VALUE ? @graphql_name : value
46
41
  if deprecation_reason
47
42
  self.deprecation_reason = deprecation_reason
48
43
  end
@@ -73,26 +68,11 @@ module GraphQL
73
68
  @value
74
69
  end
75
70
 
76
- prepend Schema::Member::CachedGraphQLDefinition::DeprecatedToGraphQL
77
-
78
- # @return [GraphQL::EnumType::EnumValue] A runtime-ready object derived from this object
79
- def to_graphql
80
- enum_value = GraphQL::EnumType::EnumValue.new
81
- enum_value.name = @graphql_name
82
- enum_value.description = @description
83
- enum_value.value = @value
84
- enum_value.deprecation_reason = self.deprecation_reason
85
- enum_value.metadata[:type_class] = self
86
- enum_value.ast_node = ast_node
87
- enum_value
88
- end
89
-
90
71
  def inspect
91
72
  "#<#{self.class} #{path} @value=#{@value.inspect}#{description ? " @description=#{description.inspect}" : ""}>"
92
73
  end
93
74
 
94
75
  def visible?(_ctx); true; end
95
- def accessible?(_ctx); true; end
96
76
  def authorized?(_ctx); true; end
97
77
  end
98
78
  end
@@ -47,6 +47,9 @@ module GraphQL
47
47
  if field.has_max_page_size? && !value.has_max_page_size_override?
48
48
  value.max_page_size = field.max_page_size
49
49
  end
50
+ if field.has_default_page_size? && !value.has_default_page_size_override?
51
+ value.default_page_size = field.default_page_size
52
+ end
50
53
  if context.schema.new_connections? && (custom_t = context.schema.connections.edge_class_for_field(@field))
51
54
  value.edge_class = custom_t
52
55
  end
@@ -64,6 +67,7 @@ module GraphQL
64
67
  original_arguments,
65
68
  field: field,
66
69
  max_page_size: field.max_page_size,
70
+ default_page_size: field.default_page_size,
67
71
  parent: object,
68
72
  context: context,
69
73
  )