graphql 1.13.12 → 2.0.21

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 (273) 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/trace.rb +96 -0
  14. data/lib/graphql/backtrace/tracer.rb +2 -3
  15. data/lib/graphql/backtrace.rb +7 -8
  16. data/lib/graphql/dataloader/null_dataloader.rb +3 -1
  17. data/lib/graphql/dataloader/source.rb +9 -0
  18. data/lib/graphql/dataloader.rb +4 -1
  19. data/lib/graphql/dig.rb +1 -1
  20. data/lib/graphql/execution/errors.rb +12 -82
  21. data/lib/graphql/execution/interpreter/arguments.rb +1 -1
  22. data/lib/graphql/execution/interpreter/arguments_cache.rb +2 -3
  23. data/lib/graphql/execution/interpreter/resolve.rb +26 -0
  24. data/lib/graphql/execution/interpreter/runtime.rb +300 -222
  25. data/lib/graphql/execution/interpreter.rb +187 -78
  26. data/lib/graphql/execution/lazy.rb +7 -21
  27. data/lib/graphql/execution/lookahead.rb +44 -40
  28. data/lib/graphql/execution/multiplex.rb +3 -174
  29. data/lib/graphql/execution.rb +11 -4
  30. data/lib/graphql/filter.rb +7 -2
  31. data/lib/graphql/introspection/directive_type.rb +2 -2
  32. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  33. data/lib/graphql/introspection/entry_points.rb +2 -15
  34. data/lib/graphql/introspection/field_type.rb +1 -1
  35. data/lib/graphql/introspection/schema_type.rb +2 -2
  36. data/lib/graphql/introspection/type_type.rb +13 -6
  37. data/lib/graphql/introspection.rb +4 -3
  38. data/lib/graphql/language/document_from_schema_definition.rb +43 -44
  39. data/lib/graphql/language/lexer.rb +216 -1488
  40. data/lib/graphql/language/nodes.rb +66 -40
  41. data/lib/graphql/language/parser.rb +539 -510
  42. data/lib/graphql/language/parser.y +53 -44
  43. data/lib/graphql/language/printer.rb +37 -21
  44. data/lib/graphql/language/visitor.rb +191 -83
  45. data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
  46. data/lib/graphql/pagination/array_connection.rb +4 -2
  47. data/lib/graphql/pagination/connection.rb +33 -6
  48. data/lib/graphql/pagination/connections.rb +3 -28
  49. data/lib/graphql/pagination/relation_connection.rb +2 -0
  50. data/lib/graphql/query/context.rb +156 -196
  51. data/lib/graphql/query/input_validation_result.rb +10 -1
  52. data/lib/graphql/query/null_context.rb +1 -4
  53. data/lib/graphql/query/validation_pipeline.rb +12 -37
  54. data/lib/graphql/query/variable_validation_error.rb +2 -2
  55. data/lib/graphql/query/variables.rb +35 -21
  56. data/lib/graphql/query.rb +39 -46
  57. data/lib/graphql/railtie.rb +0 -104
  58. data/lib/graphql/rake_task/validate.rb +1 -1
  59. data/lib/graphql/rake_task.rb +29 -1
  60. data/lib/graphql/relay/range_add.rb +9 -20
  61. data/lib/graphql/relay.rb +0 -15
  62. data/lib/graphql/schema/addition.rb +7 -9
  63. data/lib/graphql/schema/argument.rb +38 -47
  64. data/lib/graphql/schema/build_from_definition.rb +47 -21
  65. data/lib/graphql/schema/directive/one_of.rb +12 -0
  66. data/lib/graphql/schema/directive/transform.rb +1 -1
  67. data/lib/graphql/schema/directive.rb +12 -23
  68. data/lib/graphql/schema/enum.rb +29 -41
  69. data/lib/graphql/schema/enum_value.rb +2 -25
  70. data/lib/graphql/schema/field/connection_extension.rb +4 -0
  71. data/lib/graphql/schema/field.rb +256 -349
  72. data/lib/graphql/schema/field_extension.rb +1 -4
  73. data/lib/graphql/schema/find_inherited_value.rb +2 -7
  74. data/lib/graphql/schema/input_object.rb +57 -69
  75. data/lib/graphql/schema/interface.rb +0 -35
  76. data/lib/graphql/schema/introspection_system.rb +3 -8
  77. data/lib/graphql/schema/late_bound_type.rb +8 -2
  78. data/lib/graphql/schema/list.rb +18 -9
  79. data/lib/graphql/schema/loader.rb +1 -2
  80. data/lib/graphql/schema/member/base_dsl_methods.rb +17 -19
  81. data/lib/graphql/schema/member/build_type.rb +5 -7
  82. data/lib/graphql/schema/member/has_arguments.rb +147 -56
  83. data/lib/graphql/schema/member/has_ast_node.rb +12 -0
  84. data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
  85. data/lib/graphql/schema/member/has_directives.rb +81 -61
  86. data/lib/graphql/schema/member/has_fields.rb +97 -40
  87. data/lib/graphql/schema/member/has_interfaces.rb +49 -10
  88. data/lib/graphql/schema/member/has_validators.rb +32 -6
  89. data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
  90. data/lib/graphql/schema/member/type_system_helpers.rb +17 -0
  91. data/lib/graphql/schema/member/validates_input.rb +3 -3
  92. data/lib/graphql/schema/member.rb +0 -6
  93. data/lib/graphql/schema/mutation.rb +0 -9
  94. data/lib/graphql/schema/non_null.rb +3 -9
  95. data/lib/graphql/schema/object.rb +15 -52
  96. data/lib/graphql/schema/relay_classic_mutation.rb +53 -42
  97. data/lib/graphql/schema/resolver/has_payload_type.rb +20 -10
  98. data/lib/graphql/schema/resolver.rb +43 -44
  99. data/lib/graphql/schema/scalar.rb +8 -23
  100. data/lib/graphql/schema/subscription.rb +0 -7
  101. data/lib/graphql/schema/timeout.rb +24 -28
  102. data/lib/graphql/schema/type_membership.rb +3 -0
  103. data/lib/graphql/schema/union.rb +10 -17
  104. data/lib/graphql/schema/validator.rb +1 -1
  105. data/lib/graphql/schema/warden.rb +37 -9
  106. data/lib/graphql/schema/wrapper.rb +0 -5
  107. data/lib/graphql/schema.rb +265 -968
  108. data/lib/graphql/static_validation/all_rules.rb +1 -0
  109. data/lib/graphql/static_validation/base_visitor.rb +4 -21
  110. data/lib/graphql/static_validation/definition_dependencies.rb +7 -1
  111. data/lib/graphql/static_validation/error.rb +2 -2
  112. data/lib/graphql/static_validation/literal_validator.rb +19 -1
  113. data/lib/graphql/static_validation/rules/directives_are_defined.rb +11 -5
  114. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +12 -12
  115. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
  116. data/lib/graphql/static_validation/rules/fields_will_merge.rb +2 -2
  117. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  118. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  119. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +12 -6
  120. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +1 -1
  121. data/lib/graphql/static_validation/validator.rb +3 -25
  122. data/lib/graphql/static_validation.rb +0 -2
  123. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +7 -1
  124. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +38 -1
  125. data/lib/graphql/subscriptions/event.rb +3 -8
  126. data/lib/graphql/subscriptions/instrumentation.rb +0 -51
  127. data/lib/graphql/subscriptions.rb +32 -20
  128. data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
  129. data/lib/graphql/tracing/appoptics_trace.rb +231 -0
  130. data/lib/graphql/tracing/appsignal_trace.rb +77 -0
  131. data/lib/graphql/tracing/data_dog_trace.rb +148 -0
  132. data/lib/graphql/tracing/data_dog_tracing.rb +21 -2
  133. data/lib/graphql/tracing/legacy_trace.rb +65 -0
  134. data/lib/graphql/tracing/new_relic_trace.rb +75 -0
  135. data/lib/graphql/tracing/notifications_trace.rb +42 -0
  136. data/lib/graphql/tracing/platform_trace.rb +109 -0
  137. data/lib/graphql/tracing/platform_tracing.rb +33 -43
  138. data/lib/graphql/tracing/prometheus_trace.rb +89 -0
  139. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +1 -1
  140. data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
  141. data/lib/graphql/tracing/scout_trace.rb +72 -0
  142. data/lib/graphql/tracing/statsd_trace.rb +56 -0
  143. data/lib/graphql/tracing/trace.rb +75 -0
  144. data/lib/graphql/tracing.rb +16 -40
  145. data/lib/graphql/type_kinds.rb +6 -3
  146. data/lib/graphql/types/iso_8601_date.rb +4 -1
  147. data/lib/graphql/types/iso_8601_date_time.rb +4 -0
  148. data/lib/graphql/types/relay/base_connection.rb +16 -6
  149. data/lib/graphql/types/relay/connection_behaviors.rb +29 -27
  150. data/lib/graphql/types/relay/edge_behaviors.rb +16 -5
  151. data/lib/graphql/types/relay/node_behaviors.rb +12 -2
  152. data/lib/graphql/types/relay/page_info_behaviors.rb +7 -2
  153. data/lib/graphql/types/relay.rb +0 -3
  154. data/lib/graphql/types/string.rb +1 -1
  155. data/lib/graphql/version.rb +1 -1
  156. data/lib/graphql.rb +17 -74
  157. metadata +33 -133
  158. data/lib/graphql/analysis/analyze_query.rb +0 -98
  159. data/lib/graphql/analysis/field_usage.rb +0 -45
  160. data/lib/graphql/analysis/max_query_complexity.rb +0 -26
  161. data/lib/graphql/analysis/max_query_depth.rb +0 -26
  162. data/lib/graphql/analysis/query_complexity.rb +0 -88
  163. data/lib/graphql/analysis/query_depth.rb +0 -43
  164. data/lib/graphql/analysis/reducer_state.rb +0 -48
  165. data/lib/graphql/argument.rb +0 -131
  166. data/lib/graphql/authorization.rb +0 -82
  167. data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
  168. data/lib/graphql/backwards_compatibility.rb +0 -61
  169. data/lib/graphql/base_type.rb +0 -232
  170. data/lib/graphql/boolean_type.rb +0 -2
  171. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  172. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  173. data/lib/graphql/compatibility/execution_specification.rb +0 -436
  174. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  175. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
  176. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  177. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  178. data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
  179. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
  180. data/lib/graphql/compatibility.rb +0 -5
  181. data/lib/graphql/define/assign_argument.rb +0 -12
  182. data/lib/graphql/define/assign_connection.rb +0 -13
  183. data/lib/graphql/define/assign_enum_value.rb +0 -18
  184. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  185. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  186. data/lib/graphql/define/assign_object_field.rb +0 -42
  187. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  188. data/lib/graphql/define/instance_definable.rb +0 -255
  189. data/lib/graphql/define/no_definition_error.rb +0 -7
  190. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  191. data/lib/graphql/define/type_definer.rb +0 -31
  192. data/lib/graphql/define.rb +0 -31
  193. data/lib/graphql/deprecated_dsl.rb +0 -55
  194. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  195. data/lib/graphql/directive/include_directive.rb +0 -2
  196. data/lib/graphql/directive/skip_directive.rb +0 -2
  197. data/lib/graphql/directive.rb +0 -107
  198. data/lib/graphql/enum_type.rb +0 -133
  199. data/lib/graphql/execution/execute.rb +0 -333
  200. data/lib/graphql/execution/flatten.rb +0 -40
  201. data/lib/graphql/execution/instrumentation.rb +0 -92
  202. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  203. data/lib/graphql/execution/typecast.rb +0 -50
  204. data/lib/graphql/field/resolve.rb +0 -59
  205. data/lib/graphql/field.rb +0 -226
  206. data/lib/graphql/float_type.rb +0 -2
  207. data/lib/graphql/function.rb +0 -128
  208. data/lib/graphql/id_type.rb +0 -2
  209. data/lib/graphql/input_object_type.rb +0 -138
  210. data/lib/graphql/int_type.rb +0 -2
  211. data/lib/graphql/interface_type.rb +0 -72
  212. data/lib/graphql/internal_representation/document.rb +0 -27
  213. data/lib/graphql/internal_representation/node.rb +0 -206
  214. data/lib/graphql/internal_representation/print.rb +0 -51
  215. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  216. data/lib/graphql/internal_representation/scope.rb +0 -88
  217. data/lib/graphql/internal_representation/visit.rb +0 -36
  218. data/lib/graphql/internal_representation.rb +0 -7
  219. data/lib/graphql/language/lexer.rl +0 -260
  220. data/lib/graphql/list_type.rb +0 -80
  221. data/lib/graphql/non_null_type.rb +0 -71
  222. data/lib/graphql/object_type.rb +0 -130
  223. data/lib/graphql/query/arguments.rb +0 -189
  224. data/lib/graphql/query/arguments_cache.rb +0 -24
  225. data/lib/graphql/query/executor.rb +0 -52
  226. data/lib/graphql/query/literal_input.rb +0 -136
  227. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  228. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  229. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  230. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  231. data/lib/graphql/query/serial_execution.rb +0 -40
  232. data/lib/graphql/relay/array_connection.rb +0 -83
  233. data/lib/graphql/relay/base_connection.rb +0 -189
  234. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  235. data/lib/graphql/relay/connection_resolve.rb +0 -43
  236. data/lib/graphql/relay/connection_type.rb +0 -54
  237. data/lib/graphql/relay/edge.rb +0 -27
  238. data/lib/graphql/relay/edge_type.rb +0 -19
  239. data/lib/graphql/relay/edges_instrumentation.rb +0 -39
  240. data/lib/graphql/relay/global_id_resolve.rb +0 -17
  241. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  242. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  243. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  244. data/lib/graphql/relay/mutation/result.rb +0 -38
  245. data/lib/graphql/relay/mutation.rb +0 -106
  246. data/lib/graphql/relay/node.rb +0 -39
  247. data/lib/graphql/relay/page_info.rb +0 -7
  248. data/lib/graphql/relay/relation_connection.rb +0 -188
  249. data/lib/graphql/relay/type_extensions.rb +0 -32
  250. data/lib/graphql/scalar_type.rb +0 -91
  251. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  252. data/lib/graphql/schema/default_parse_error.rb +0 -10
  253. data/lib/graphql/schema/default_type_error.rb +0 -17
  254. data/lib/graphql/schema/member/accepts_definition.rb +0 -164
  255. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -58
  256. data/lib/graphql/schema/member/instrumentation.rb +0 -131
  257. data/lib/graphql/schema/middleware_chain.rb +0 -82
  258. data/lib/graphql/schema/possible_types.rb +0 -44
  259. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  260. data/lib/graphql/schema/timeout_middleware.rb +0 -88
  261. data/lib/graphql/schema/traversal.rb +0 -228
  262. data/lib/graphql/schema/validation.rb +0 -313
  263. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  264. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  265. data/lib/graphql/string_type.rb +0 -2
  266. data/lib/graphql/subscriptions/subscription_root.rb +0 -76
  267. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  268. data/lib/graphql/types/relay/default_relay.rb +0 -31
  269. data/lib/graphql/types/relay/node_field.rb +0 -24
  270. data/lib/graphql/types/relay/nodes_field.rb +0 -43
  271. data/lib/graphql/union_type.rb +0 -115
  272. data/lib/graphql/upgrader/member.rb +0 -937
  273. data/lib/graphql/upgrader/schema.rb +0 -38
@@ -2,16 +2,12 @@
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
10
8
  include GraphQL::Schema::Member::HasDeprecationReason
11
9
  include GraphQL::Schema::Member::HasValidators
12
- include GraphQL::Schema::FindInheritedValue::EmptyObjects
13
-
14
- NO_DEFAULT = :__no_default__
10
+ include GraphQL::EmptyObjects
15
11
 
16
12
  # @return [String] the GraphQL name for this argument, camelized unless `camelize: false` is provided
17
13
  attr_reader :name
@@ -20,8 +16,14 @@ module GraphQL
20
16
  # @return [GraphQL::Schema::Field, Class] The field or input object this argument belongs to
21
17
  attr_reader :owner
22
18
 
23
- # @return [Symbol] A method to call to transform this value before sending it to field resolution method
24
- attr_reader :prepare
19
+ # @param new_prepare [Method, Proc]
20
+ # @return [Symbol] A method or proc to call to transform this value before sending it to field resolution method
21
+ def prepare(new_prepare = NOT_CONFIGURED)
22
+ if new_prepare != NOT_CONFIGURED
23
+ @prepare = new_prepare
24
+ end
25
+ @prepare
26
+ end
25
27
 
26
28
  # @return [Symbol] This argument's name in Ruby keyword arguments
27
29
  attr_reader :keyword
@@ -44,12 +46,11 @@ module GraphQL
44
46
  # @param prepare [Symbol] A method to call to transform this argument's valuebefore sending it to field resolution
45
47
  # @param camelize [Boolean] if true, the name will be camelized when building the schema
46
48
  # @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
49
  # @param directives [Hash{Class => Hash}]
49
50
  # @param deprecation_reason [String]
50
51
  # @param validates [Hash, nil] Options for building validators, if any should be applied
51
52
  # @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)
53
+ 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: NOT_CONFIGURED, 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
54
  arg_name ||= name
54
55
  @name = -(camelize ? Member::BuildType.camelize(arg_name.to_s) : arg_name.to_s)
55
56
  @type_expr = type_expr || type
@@ -70,7 +71,6 @@ module GraphQL
70
71
  @prepare = prepare
71
72
  @ast_node = ast_node
72
73
  @from_resolver = from_resolver
73
- @method_access = method_access
74
74
  self.deprecation_reason = deprecation_reason
75
75
 
76
76
  if directives
@@ -79,7 +79,10 @@ module GraphQL
79
79
  end
80
80
  end
81
81
 
82
- self.validates(validates)
82
+ if validates && !validates.empty?
83
+ self.validates(validates)
84
+ end
85
+
83
86
  if required == :nullable
84
87
  self.owner.validates(required: { argument: arg_name })
85
88
  end
@@ -97,12 +100,18 @@ module GraphQL
97
100
  "#<#{self.class} #{path}: #{type.to_type_signature}#{description ? " @description=#{description.inspect}" : ""}>"
98
101
  end
99
102
 
103
+ # @param default_value [Object] The value to use when the client doesn't provide one
100
104
  # @return [Object] the value used when the client doesn't provide a value for this argument
101
- attr_reader :default_value
105
+ def default_value(new_default_value = NOT_CONFIGURED)
106
+ if new_default_value != NOT_CONFIGURED
107
+ @default_value = new_default_value
108
+ end
109
+ @default_value
110
+ end
102
111
 
103
112
  # @return [Boolean] True if this argument has a default value
104
113
  def default_value?
105
- @default_value != NO_DEFAULT
114
+ @default_value != NOT_CONFIGURED
106
115
  end
107
116
 
108
117
  def replace_null_with_default?
@@ -138,10 +147,6 @@ module GraphQL
138
147
  true
139
148
  end
140
149
 
141
- def accessible?(context)
142
- true
143
- end
144
-
145
150
  def authorized?(obj, value, ctx)
146
151
  authorized_as_type?(obj, value, ctx, as_type: type)
147
152
  end
@@ -169,26 +174,6 @@ module GraphQL
169
174
  true
170
175
  end
171
176
 
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
177
  def type=(new_type)
193
178
  validate_input_type(new_type)
194
179
  # This isn't true for LateBoundTypes, but we can assume those will
@@ -271,29 +256,35 @@ module GraphQL
271
256
  end
272
257
 
273
258
  loaded_value = nil
274
- coerced_value = context.schema.error_handler.with_error_handling(context) do
259
+ coerced_value = begin
275
260
  type.coerce_input(value, context)
261
+ rescue StandardError => err
262
+ context.schema.handle_or_reraise(context, err)
276
263
  end
277
264
 
278
265
  # If this isn't lazy, then the block returns eagerly and assigns the result here
279
266
  # If it _is_ lazy, then we write the lazy to the hash, then update it later
280
267
  argument_values[arg_key] = context.schema.after_lazy(coerced_value) do |resolved_coerced_value|
268
+ owner.validate_directive_argument(self, resolved_coerced_value)
269
+ prepared_value = begin
270
+ prepare_value(parent_object, resolved_coerced_value, context: context)
271
+ rescue StandardError => err
272
+ context.schema.handle_or_reraise(context, err)
273
+ end
274
+
281
275
  if loads && !from_resolver?
282
- loaded_value = context.query.with_error_handling do
283
- load_and_authorize_value(owner, coerced_value, context)
276
+ loaded_value = begin
277
+ load_and_authorize_value(owner, prepared_value, context)
278
+ rescue StandardError => err
279
+ context.schema.handle_or_reraise(context, err)
284
280
  end
285
281
  end
286
282
 
287
- maybe_loaded_value = loaded_value || resolved_coerced_value
283
+ maybe_loaded_value = loaded_value || prepared_value
288
284
  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
285
  # TODO code smell to access such a deeply-nested constant in a distant module
295
286
  argument_values[arg_key] = GraphQL::Execution::Interpreter::ArgumentValue.new(
296
- value: prepared_value,
287
+ value: resolved_loaded_value,
297
288
  definition: self,
298
289
  default_used: default_used,
299
290
  )
@@ -6,24 +6,25 @@ 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
 
22
22
  # @api private
23
23
  module Builder
24
+ include GraphQL::EmptyObjects
24
25
  extend self
25
26
 
26
- def build(document, default_resolve:, using: {}, relay:)
27
+ def build(schema_superclass, document, default_resolve:, using: {}, relay:)
27
28
  raise InvalidDocumentError.new('Must provide a document ast.') if !document || !document.is_a?(GraphQL::Language::Nodes::Document)
28
29
 
29
30
  if default_resolve.is_a?(Hash)
@@ -36,7 +37,7 @@ module GraphQL
36
37
  end
37
38
  schema_definition = schema_defns.first
38
39
  types = {}
39
- directives = {}
40
+ directives = schema_superclass.directives.dup
40
41
  type_resolver = build_resolve_type(types, directives, ->(type_name) { types[type_name] ||= Schema::LateBoundType.new(type_name)})
41
42
  # Make a different type resolver because we need to coerce directive arguments
42
43
  # _while_ building the schema.
@@ -55,21 +56,24 @@ module GraphQL
55
56
  end
56
57
  })
57
58
 
59
+ directives.merge!(GraphQL::Schema.default_directives)
58
60
  document.definitions.each do |definition|
59
61
  if definition.is_a?(GraphQL::Language::Nodes::DirectiveDefinition)
60
62
  directives[definition.name] = build_directive(definition, directive_type_resolver)
61
63
  end
62
64
  end
63
65
 
64
- directives = GraphQL::Schema.default_directives.merge(directives)
65
-
66
66
  # In case any directives referenced built-in types for their arguments:
67
67
  replace_late_bound_types_with_built_in(types)
68
68
 
69
+ schema_extensions = nil
69
70
  document.definitions.each do |definition|
70
71
  case definition
71
72
  when GraphQL::Language::Nodes::SchemaDefinition, GraphQL::Language::Nodes::DirectiveDefinition
72
73
  nil # already handled
74
+ when GraphQL::Language::Nodes::SchemaExtension
75
+ schema_extensions ||= []
76
+ schema_extensions << definition
73
77
  else
74
78
  # It's possible that this was already loaded by the directives
75
79
  prev_type = types[definition.name]
@@ -96,6 +100,16 @@ module GraphQL
96
100
  raise InvalidDocumentError.new("Specified subscription type \"#{schema_definition.subscription}\" not found in document.") unless types[schema_definition.subscription]
97
101
  subscription_root_type = types[schema_definition.subscription]
98
102
  end
103
+
104
+ if schema_definition.query.nil? &&
105
+ schema_definition.mutation.nil? &&
106
+ schema_definition.subscription.nil?
107
+ # This schema may have been given with directives only,
108
+ # check for defaults:
109
+ query_root_type = types['Query']
110
+ mutation_root_type = types['Mutation']
111
+ subscription_root_type = types['Subscription']
112
+ end
99
113
  else
100
114
  query_root_type = types['Query']
101
115
  mutation_root_type = types['Mutation']
@@ -104,7 +118,9 @@ module GraphQL
104
118
 
105
119
  raise InvalidDocumentError.new('Must provide schema definition with query type or a type named Query.') unless query_root_type
106
120
 
107
- Class.new(GraphQL::Schema) do
121
+ builder = self
122
+
123
+ schema_class = Class.new(schema_superclass) do
108
124
  begin
109
125
  # Add these first so that there's some chance of resolving late-bound types
110
126
  orphan_types types.values
@@ -131,6 +147,7 @@ module GraphQL
131
147
 
132
148
  if schema_definition
133
149
  ast_node(schema_definition)
150
+ builder.build_directives(self, schema_definition, type_resolver)
134
151
  end
135
152
 
136
153
  using.each do |plugin, options|
@@ -158,6 +175,14 @@ module GraphQL
158
175
  child_class.definition_default_resolve = self.definition_default_resolve
159
176
  end
160
177
  end
178
+
179
+ if schema_extensions
180
+ schema_extensions.each do |ext|
181
+ build_directives(schema_class, ext, type_resolver)
182
+ end
183
+ end
184
+
185
+ schema_class
161
186
  end
162
187
 
163
188
  NullResolveType = ->(type, obj, ctx) {
@@ -197,13 +222,18 @@ module GraphQL
197
222
 
198
223
  def build_directives(definition, ast_node, type_resolver)
199
224
  dirs = prepare_directives(ast_node, type_resolver)
200
- dirs.each do |dir_class, options|
201
- definition.directive(dir_class, **options)
225
+ dirs.each do |(dir_class, options)|
226
+ if definition.respond_to?(:schema_directive)
227
+ # it's a schema
228
+ definition.schema_directive(dir_class, **options)
229
+ else
230
+ definition.directive(dir_class, **options)
231
+ end
202
232
  end
203
233
  end
204
234
 
205
235
  def prepare_directives(ast_node, type_resolver)
206
- dirs = {}
236
+ dirs = []
207
237
  ast_node.directives.each do |dir_node|
208
238
  if dir_node.name == "deprecated"
209
239
  # This is handled using `deprecation_reason`
@@ -211,10 +241,10 @@ module GraphQL
211
241
  else
212
242
  dir_class = type_resolver.call(dir_node.name)
213
243
  if dir_class.nil?
214
- raise ArgumentError, "No definition for @#{dir_node.name} on #{ast_node.name} at #{ast_node.line}:#{ast_node.col}"
244
+ 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
245
  end
216
246
  options = args_to_kwargs(dir_class, dir_node)
217
- dirs[dir_class] = options
247
+ dirs << [dir_class, options]
218
248
  end
219
249
  end
220
250
  dirs
@@ -345,8 +375,6 @@ module GraphQL
345
375
  end
346
376
  end
347
377
 
348
- NO_DEFAULT_VALUE = {}.freeze
349
-
350
378
  def build_arguments(type_class, arguments, type_resolver)
351
379
  builder = self
352
380
 
@@ -354,7 +382,7 @@ module GraphQL
354
382
  default_value_kwargs = if !argument_defn.default_value.nil?
355
383
  { default_value: builder.build_default_value(argument_defn.default_value) }
356
384
  else
357
- NO_DEFAULT_VALUE
385
+ EMPTY_HASH
358
386
  end
359
387
 
360
388
  type_class.argument(
@@ -365,7 +393,6 @@ module GraphQL
365
393
  deprecation_reason: builder.build_deprecation_reason(argument_defn.directives),
366
394
  ast_node: argument_defn,
367
395
  camelize: false,
368
- method_access: false,
369
396
  directives: prepare_directives(argument_defn, type_resolver),
370
397
  **default_value_kwargs
371
398
  )
@@ -391,7 +418,6 @@ module GraphQL
391
418
  graphql_name(interface_type_definition.name)
392
419
  description(interface_type_definition.description)
393
420
  interface_type_definition.interfaces.each do |interface_name|
394
- "Implements: #{interface_type_definition} -> #{interface_name}"
395
421
  interface_defn = type_resolver.call(interface_name)
396
422
  implements(interface_defn)
397
423
  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
@@ -139,17 +129,15 @@ module GraphQL
139
129
  GraphQL::TypeKinds::ENUM
140
130
  end
141
131
 
142
- def validate_non_null_input(value_name, ctx)
143
- result = GraphQL::Query::InputValidationResult.new
144
-
132
+ def validate_non_null_input(value_name, ctx, max_errors: nil)
145
133
  allowed_values = ctx.warden.enum_values(self)
146
134
  matching_value = allowed_values.find { |v| v.graphql_name == value_name }
147
135
 
148
136
  if matching_value.nil?
149
- 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
150
140
  end
151
-
152
- result
153
141
  end
154
142
 
155
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,8 +20,6 @@ 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
@@ -38,11 +30,11 @@ module GraphQL
38
30
  # @return [Class] The enum type that owns this value
39
31
  attr_reader :owner
40
32
 
41
- def initialize(graphql_name, desc = nil, owner:, ast_node: nil, directives: nil, description: nil, value: nil, deprecation_reason: nil, &block)
33
+ def initialize(graphql_name, desc = nil, owner:, ast_node: nil, directives: nil, description: nil, value: NOT_CONFIGURED, deprecation_reason: nil, &block)
42
34
  @graphql_name = graphql_name.to_s
43
35
  GraphQL::NameValidator.validate!(@graphql_name)
44
36
  @description = desc || description
45
- @value = value.nil? ? @graphql_name : value
37
+ @value = value === NOT_CONFIGURED ? @graphql_name : value
46
38
  if deprecation_reason
47
39
  self.deprecation_reason = deprecation_reason
48
40
  end
@@ -73,26 +65,11 @@ module GraphQL
73
65
  @value
74
66
  end
75
67
 
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
68
  def inspect
91
69
  "#<#{self.class} #{path} @value=#{@value.inspect}#{description ? " @description=#{description.inspect}" : ""}>"
92
70
  end
93
71
 
94
72
  def visible?(_ctx); true; end
95
- def accessible?(_ctx); true; end
96
73
  def authorized?(_ctx); true; end
97
74
  end
98
75
  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
  )