graphql 2.0.31 → 2.6.1

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 (316) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/detailed_trace_generator.rb +77 -0
  3. data/lib/generators/graphql/install/mutation_root_generator.rb +2 -2
  4. data/lib/generators/graphql/install/templates/base_mutation.erb +2 -0
  5. data/lib/generators/graphql/install/templates/mutation_type.erb +2 -0
  6. data/lib/generators/graphql/install_generator.rb +49 -0
  7. data/lib/generators/graphql/orm_mutations_base.rb +1 -1
  8. data/lib/generators/graphql/templates/base_argument.erb +2 -0
  9. data/lib/generators/graphql/templates/base_connection.erb +2 -0
  10. data/lib/generators/graphql/templates/base_edge.erb +2 -0
  11. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  12. data/lib/generators/graphql/templates/base_field.erb +2 -0
  13. data/lib/generators/graphql/templates/base_input_object.erb +2 -0
  14. data/lib/generators/graphql/templates/base_interface.erb +2 -0
  15. data/lib/generators/graphql/templates/base_object.erb +2 -0
  16. data/lib/generators/graphql/templates/base_resolver.erb +8 -0
  17. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  18. data/lib/generators/graphql/templates/base_union.erb +2 -0
  19. data/lib/generators/graphql/templates/create_graphql_detailed_traces.erb +10 -0
  20. data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
  21. data/lib/generators/graphql/templates/loader.erb +2 -0
  22. data/lib/generators/graphql/templates/mutation.erb +2 -0
  23. data/lib/generators/graphql/templates/node_type.erb +2 -0
  24. data/lib/generators/graphql/templates/query_type.erb +2 -0
  25. data/lib/generators/graphql/templates/schema.erb +5 -0
  26. data/lib/generators/graphql/type_generator.rb +1 -1
  27. data/lib/graphql/analysis/analyzer.rb +90 -0
  28. data/lib/graphql/analysis/field_usage.rb +82 -0
  29. data/lib/graphql/analysis/max_query_complexity.rb +20 -0
  30. data/lib/graphql/analysis/max_query_depth.rb +20 -0
  31. data/lib/graphql/analysis/query_complexity.rb +263 -0
  32. data/lib/graphql/analysis/query_depth.rb +58 -0
  33. data/lib/graphql/analysis/visitor.rb +280 -0
  34. data/lib/graphql/analysis.rb +102 -1
  35. data/lib/graphql/autoload.rb +38 -0
  36. data/lib/graphql/backtrace/table.rb +118 -55
  37. data/lib/graphql/backtrace.rb +1 -19
  38. data/lib/graphql/coercion_error.rb +1 -9
  39. data/lib/graphql/current.rb +57 -0
  40. data/lib/graphql/dashboard/application_controller.rb +41 -0
  41. data/lib/graphql/dashboard/detailed_traces.rb +47 -0
  42. data/lib/graphql/dashboard/installable.rb +22 -0
  43. data/lib/graphql/dashboard/landings_controller.rb +9 -0
  44. data/lib/graphql/dashboard/limiters.rb +93 -0
  45. data/lib/graphql/dashboard/operation_store.rb +199 -0
  46. data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.css +6 -0
  47. data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.js +7 -0
  48. data/lib/graphql/dashboard/statics/charts.min.css +1 -0
  49. data/lib/graphql/dashboard/statics/dashboard.css +30 -0
  50. data/lib/graphql/dashboard/statics/dashboard.js +143 -0
  51. data/lib/graphql/dashboard/statics/header-icon.png +0 -0
  52. data/lib/graphql/dashboard/statics/icon.png +0 -0
  53. data/lib/graphql/dashboard/statics_controller.rb +31 -0
  54. data/lib/graphql/dashboard/subscriptions.rb +97 -0
  55. data/lib/graphql/dashboard/views/graphql/dashboard/detailed_traces/traces/index.html.erb +45 -0
  56. data/lib/graphql/dashboard/views/graphql/dashboard/landings/show.html.erb +18 -0
  57. data/lib/graphql/dashboard/views/graphql/dashboard/limiters/limiters/show.html.erb +62 -0
  58. data/lib/graphql/dashboard/views/graphql/dashboard/not_installed.html.erb +18 -0
  59. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/_form.html.erb +24 -0
  60. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/edit.html.erb +21 -0
  61. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/index.html.erb +69 -0
  62. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/new.html.erb +7 -0
  63. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/index.html.erb +39 -0
  64. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/show.html.erb +32 -0
  65. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/index.html.erb +81 -0
  66. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/show.html.erb +71 -0
  67. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/subscriptions/show.html.erb +41 -0
  68. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/index.html.erb +55 -0
  69. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/show.html.erb +40 -0
  70. data/lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb +108 -0
  71. data/lib/graphql/dashboard.rb +96 -0
  72. data/lib/graphql/dataloader/active_record_association_source.rb +84 -0
  73. data/lib/graphql/dataloader/active_record_source.rb +47 -0
  74. data/lib/graphql/dataloader/async_dataloader.rb +112 -0
  75. data/lib/graphql/dataloader/null_dataloader.rb +55 -10
  76. data/lib/graphql/dataloader/request.rb +5 -0
  77. data/lib/graphql/dataloader/source.rb +35 -12
  78. data/lib/graphql/dataloader.rb +224 -149
  79. data/lib/graphql/date_encoding_error.rb +1 -1
  80. data/lib/graphql/dig.rb +2 -1
  81. data/lib/graphql/duration_encoding_error.rb +16 -0
  82. data/lib/graphql/execution/field_resolve_step.rb +631 -0
  83. data/lib/graphql/execution/finalize.rb +217 -0
  84. data/lib/graphql/execution/input_values.rb +261 -0
  85. data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
  86. data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
  87. data/lib/graphql/execution/interpreter/handles_raw_value.rb +6 -0
  88. data/lib/graphql/execution/interpreter/resolve.rb +23 -25
  89. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +228 -0
  90. data/lib/graphql/execution/interpreter/runtime.rb +365 -435
  91. data/lib/graphql/execution/interpreter.rb +87 -163
  92. data/lib/graphql/execution/lazy.rb +1 -1
  93. data/lib/graphql/execution/load_argument_step.rb +64 -0
  94. data/lib/graphql/execution/lookahead.rb +105 -31
  95. data/lib/graphql/execution/multiplex.rb +7 -6
  96. data/lib/graphql/execution/next.rb +90 -0
  97. data/lib/graphql/execution/prepare_object_step.rb +128 -0
  98. data/lib/graphql/execution/runner.rb +410 -0
  99. data/lib/graphql/execution/selections_step.rb +91 -0
  100. data/lib/graphql/execution.rb +8 -4
  101. data/lib/graphql/execution_error.rb +17 -10
  102. data/lib/graphql/introspection/directive_location_enum.rb +1 -1
  103. data/lib/graphql/introspection/directive_type.rb +7 -3
  104. data/lib/graphql/introspection/dynamic_fields.rb +5 -1
  105. data/lib/graphql/introspection/entry_points.rb +20 -6
  106. data/lib/graphql/introspection/enum_value_type.rb +5 -5
  107. data/lib/graphql/introspection/field_type.rb +13 -5
  108. data/lib/graphql/introspection/input_value_type.rb +21 -13
  109. data/lib/graphql/introspection/schema_type.rb +8 -11
  110. data/lib/graphql/introspection/type_type.rb +64 -28
  111. data/lib/graphql/invalid_name_error.rb +1 -1
  112. data/lib/graphql/invalid_null_error.rb +26 -17
  113. data/lib/graphql/language/block_string.rb +34 -18
  114. data/lib/graphql/language/cache.rb +13 -0
  115. data/lib/graphql/language/comment.rb +18 -0
  116. data/lib/graphql/language/definition_slice.rb +1 -1
  117. data/lib/graphql/language/document_from_schema_definition.rb +90 -61
  118. data/lib/graphql/language/lexer.rb +323 -193
  119. data/lib/graphql/language/nodes.rb +139 -77
  120. data/lib/graphql/language/parser.rb +807 -1985
  121. data/lib/graphql/language/printer.rb +324 -151
  122. data/lib/graphql/language/sanitized_printer.rb +21 -23
  123. data/lib/graphql/language/static_visitor.rb +171 -0
  124. data/lib/graphql/language/visitor.rb +62 -119
  125. data/lib/graphql/language.rb +71 -1
  126. data/lib/graphql/load_application_object_failed_error.rb +5 -1
  127. data/lib/graphql/pagination/array_connection.rb +6 -6
  128. data/lib/graphql/pagination/connection.rb +30 -1
  129. data/lib/graphql/pagination/connections.rb +32 -0
  130. data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
  131. data/lib/graphql/query/context/scoped_context.rb +101 -0
  132. data/lib/graphql/query/context.rb +88 -144
  133. data/lib/graphql/query/null_context.rb +15 -18
  134. data/lib/graphql/query/partial.rb +194 -0
  135. data/lib/graphql/query/validation_pipeline.rb +4 -4
  136. data/lib/graphql/query/variable_validation_error.rb +1 -1
  137. data/lib/graphql/query/variables.rb +3 -3
  138. data/lib/graphql/query.rb +135 -81
  139. data/lib/graphql/railtie.rb +16 -6
  140. data/lib/graphql/rake_task.rb +3 -12
  141. data/lib/graphql/rubocop/graphql/base_cop.rb +1 -1
  142. data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
  143. data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
  144. data/lib/graphql/rubocop.rb +2 -0
  145. data/lib/graphql/runtime_error.rb +6 -0
  146. data/lib/graphql/schema/addition.rb +26 -13
  147. data/lib/graphql/schema/always_visible.rb +7 -2
  148. data/lib/graphql/schema/argument.rb +78 -14
  149. data/lib/graphql/schema/base_64_encoder.rb +3 -5
  150. data/lib/graphql/schema/build_from_definition.rb +140 -66
  151. data/lib/graphql/schema/directive/flagged.rb +4 -2
  152. data/lib/graphql/schema/directive/one_of.rb +12 -0
  153. data/lib/graphql/schema/directive/specified_by.rb +14 -0
  154. data/lib/graphql/schema/directive.rb +78 -12
  155. data/lib/graphql/schema/enum.rb +110 -27
  156. data/lib/graphql/schema/enum_value.rb +11 -3
  157. data/lib/graphql/schema/field/connection_extension.rb +4 -51
  158. data/lib/graphql/schema/field/scope_extension.rb +19 -7
  159. data/lib/graphql/schema/field.rb +245 -119
  160. data/lib/graphql/schema/field_extension.rb +12 -9
  161. data/lib/graphql/schema/has_single_input_argument.rb +160 -0
  162. data/lib/graphql/schema/input_object.rb +123 -65
  163. data/lib/graphql/schema/interface.rb +60 -16
  164. data/lib/graphql/schema/introspection_system.rb +8 -17
  165. data/lib/graphql/schema/late_bound_type.rb +4 -0
  166. data/lib/graphql/schema/list.rb +8 -4
  167. data/lib/graphql/schema/loader.rb +3 -4
  168. data/lib/graphql/schema/member/base_dsl_methods.rb +18 -12
  169. data/lib/graphql/schema/member/has_arguments.rb +132 -100
  170. data/lib/graphql/schema/member/has_authorization.rb +35 -0
  171. data/lib/graphql/schema/member/has_dataloader.rb +99 -0
  172. data/lib/graphql/schema/member/has_deprecation_reason.rb +15 -0
  173. data/lib/graphql/schema/member/has_directives.rb +5 -5
  174. data/lib/graphql/schema/member/has_fields.rb +121 -17
  175. data/lib/graphql/schema/member/has_interfaces.rb +27 -13
  176. data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
  177. data/lib/graphql/schema/member/has_validators.rb +1 -1
  178. data/lib/graphql/schema/member/relay_shortcuts.rb +1 -1
  179. data/lib/graphql/schema/member/scoped.rb +19 -0
  180. data/lib/graphql/schema/member/type_system_helpers.rb +18 -5
  181. data/lib/graphql/schema/member/validates_input.rb +3 -3
  182. data/lib/graphql/schema/member.rb +6 -0
  183. data/lib/graphql/schema/mutation.rb +7 -0
  184. data/lib/graphql/schema/non_null.rb +1 -1
  185. data/lib/graphql/schema/object.rb +34 -8
  186. data/lib/graphql/schema/printer.rb +9 -7
  187. data/lib/graphql/schema/ractor_shareable.rb +79 -0
  188. data/lib/graphql/schema/relay_classic_mutation.rb +6 -129
  189. data/lib/graphql/schema/resolver.rb +128 -32
  190. data/lib/graphql/schema/scalar.rb +4 -9
  191. data/lib/graphql/schema/subscription.rb +63 -12
  192. data/lib/graphql/schema/timeout.rb +19 -2
  193. data/lib/graphql/schema/type_expression.rb +2 -2
  194. data/lib/graphql/schema/union.rb +2 -2
  195. data/lib/graphql/schema/unique_within_type.rb +1 -1
  196. data/lib/graphql/schema/validator/all_validator.rb +62 -0
  197. data/lib/graphql/schema/validator/required_validator.rb +92 -11
  198. data/lib/graphql/schema/validator.rb +3 -1
  199. data/lib/graphql/schema/visibility/migration.rb +188 -0
  200. data/lib/graphql/schema/visibility/profile.rb +464 -0
  201. data/lib/graphql/schema/visibility/visit.rb +190 -0
  202. data/lib/graphql/schema/visibility.rb +311 -0
  203. data/lib/graphql/schema/warden.rb +275 -103
  204. data/lib/graphql/schema/wrapper.rb +7 -1
  205. data/lib/graphql/schema.rb +954 -212
  206. data/lib/graphql/static_validation/all_rules.rb +3 -3
  207. data/lib/graphql/static_validation/base_visitor.rb +96 -71
  208. data/lib/graphql/static_validation/literal_validator.rb +6 -7
  209. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +2 -2
  210. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +18 -6
  211. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +6 -2
  212. data/lib/graphql/static_validation/rules/directives_are_defined.rb +6 -3
  213. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -0
  214. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +14 -3
  215. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +59 -15
  216. data/lib/graphql/static_validation/rules/fields_will_merge.rb +391 -262
  217. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +10 -2
  218. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +6 -6
  219. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +15 -2
  220. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  221. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
  222. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
  223. data/lib/graphql/static_validation/rules/not_single_subscription_error.rb +25 -0
  224. data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
  225. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +28 -8
  226. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +5 -5
  227. data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +26 -0
  228. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +7 -3
  229. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
  230. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
  231. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
  232. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +14 -2
  233. data/lib/graphql/static_validation/validation_context.rb +22 -6
  234. data/lib/graphql/static_validation/validator.rb +9 -1
  235. data/lib/graphql/static_validation.rb +0 -1
  236. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +8 -5
  237. data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
  238. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +45 -19
  239. data/lib/graphql/subscriptions/event.rb +22 -4
  240. data/lib/graphql/subscriptions/serialize.rb +3 -1
  241. data/lib/graphql/subscriptions.rb +56 -17
  242. data/lib/graphql/testing/helpers.rb +161 -0
  243. data/lib/graphql/testing/mock_action_cable.rb +111 -0
  244. data/lib/graphql/testing.rb +3 -0
  245. data/lib/graphql/tracing/active_support_notifications_trace.rb +14 -3
  246. data/lib/graphql/tracing/active_support_notifications_tracing.rb +1 -1
  247. data/lib/graphql/tracing/appoptics_trace.rb +11 -3
  248. data/lib/graphql/tracing/appoptics_tracing.rb +9 -2
  249. data/lib/graphql/tracing/appsignal_trace.rb +32 -55
  250. data/lib/graphql/tracing/appsignal_tracing.rb +2 -0
  251. data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
  252. data/lib/graphql/tracing/data_dog_trace.rb +46 -158
  253. data/lib/graphql/tracing/data_dog_tracing.rb +2 -0
  254. data/lib/graphql/tracing/detailed_trace/active_record_backend.rb +74 -0
  255. data/lib/graphql/tracing/detailed_trace/memory_backend.rb +60 -0
  256. data/lib/graphql/tracing/detailed_trace/redis_backend.rb +72 -0
  257. data/lib/graphql/tracing/detailed_trace.rb +156 -0
  258. data/lib/graphql/tracing/legacy_hooks_trace.rb +75 -0
  259. data/lib/graphql/tracing/legacy_trace.rb +4 -61
  260. data/lib/graphql/tracing/monitor_trace.rb +283 -0
  261. data/lib/graphql/tracing/new_relic_trace.rb +47 -54
  262. data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
  263. data/lib/graphql/tracing/notifications_trace.rb +184 -34
  264. data/lib/graphql/tracing/notifications_tracing.rb +2 -0
  265. data/lib/graphql/tracing/null_trace.rb +9 -0
  266. data/lib/graphql/tracing/perfetto_trace/trace.proto +141 -0
  267. data/lib/graphql/tracing/perfetto_trace/trace_pb.rb +33 -0
  268. data/lib/graphql/tracing/perfetto_trace.rb +864 -0
  269. data/lib/graphql/tracing/platform_trace.rb +5 -0
  270. data/lib/graphql/tracing/platform_tracing.rb +3 -1
  271. data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +5 -1
  272. data/lib/graphql/tracing/prometheus_trace.rb +72 -68
  273. data/lib/graphql/tracing/prometheus_tracing.rb +2 -0
  274. data/lib/graphql/tracing/scout_trace.rb +32 -55
  275. data/lib/graphql/tracing/scout_tracing.rb +2 -0
  276. data/lib/graphql/tracing/sentry_trace.rb +82 -0
  277. data/lib/graphql/tracing/statsd_trace.rb +33 -41
  278. data/lib/graphql/tracing/statsd_tracing.rb +2 -0
  279. data/lib/graphql/tracing/trace.rb +118 -1
  280. data/lib/graphql/tracing.rb +31 -28
  281. data/lib/graphql/type_kinds.rb +2 -1
  282. data/lib/graphql/types/iso_8601_duration.rb +77 -0
  283. data/lib/graphql/types/relay/connection_behaviors.rb +45 -3
  284. data/lib/graphql/types/relay/edge_behaviors.rb +19 -1
  285. data/lib/graphql/types/relay/has_node_field.rb +13 -8
  286. data/lib/graphql/types/relay/has_nodes_field.rb +13 -8
  287. data/lib/graphql/types/relay/node_behaviors.rb +13 -2
  288. data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
  289. data/lib/graphql/types.rb +18 -10
  290. data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
  291. data/lib/graphql/unauthorized_error.rb +9 -1
  292. data/lib/graphql/version.rb +1 -1
  293. data/lib/graphql.rb +69 -54
  294. data/readme.md +12 -2
  295. metadata +236 -40
  296. data/lib/graphql/analysis/ast/analyzer.rb +0 -84
  297. data/lib/graphql/analysis/ast/field_usage.rb +0 -57
  298. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -22
  299. data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
  300. data/lib/graphql/analysis/ast/query_complexity.rb +0 -230
  301. data/lib/graphql/analysis/ast/query_depth.rb +0 -55
  302. data/lib/graphql/analysis/ast/visitor.rb +0 -276
  303. data/lib/graphql/analysis/ast.rb +0 -81
  304. data/lib/graphql/backtrace/inspect_result.rb +0 -50
  305. data/lib/graphql/backtrace/trace.rb +0 -96
  306. data/lib/graphql/backtrace/tracer.rb +0 -80
  307. data/lib/graphql/deprecation.rb +0 -9
  308. data/lib/graphql/filter.rb +0 -59
  309. data/lib/graphql/language/parser.y +0 -560
  310. data/lib/graphql/language/token.rb +0 -34
  311. data/lib/graphql/schema/base_64_bp.rb +0 -26
  312. data/lib/graphql/schema/invalid_type_error.rb +0 -7
  313. data/lib/graphql/schema/null_mask.rb +0 -11
  314. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +0 -17
  315. data/lib/graphql/static_validation/type_stack.rb +0 -216
  316. data/lib/graphql/subscriptions/instrumentation.rb +0 -28
@@ -7,15 +7,21 @@ module GraphQL
7
7
  class << self
8
8
  # @see {Schema.from_definition}
9
9
  def from_definition(schema_superclass, definition_string, parser: GraphQL.default_parser, **kwargs)
10
+ if defined?(parser::SchemaParser)
11
+ parser = parser::SchemaParser
12
+ end
10
13
  from_document(schema_superclass, parser.parse(definition_string), **kwargs)
11
14
  end
12
15
 
13
16
  def from_definition_path(schema_superclass, definition_path, parser: GraphQL.default_parser, **kwargs)
17
+ if defined?(parser::SchemaParser)
18
+ parser = parser::SchemaParser
19
+ end
14
20
  from_document(schema_superclass, parser.parse_file(definition_path), **kwargs)
15
21
  end
16
22
 
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)
23
+ def from_document(schema_superclass, document, default_resolve:, using: {}, base_types: {}, relay: false)
24
+ Builder.build(schema_superclass, document, default_resolve: default_resolve || {}, relay: relay, using: using, base_types: base_types)
19
25
  end
20
26
  end
21
27
 
@@ -24,9 +30,18 @@ module GraphQL
24
30
  include GraphQL::EmptyObjects
25
31
  extend self
26
32
 
27
- def build(schema_superclass, document, default_resolve:, using: {}, relay:)
33
+ def build(schema_superclass, document, default_resolve:, using: {}, base_types: {}, relay:)
28
34
  raise InvalidDocumentError.new('Must provide a document ast.') if !document || !document.is_a?(GraphQL::Language::Nodes::Document)
29
35
 
36
+ base_types = {
37
+ object: GraphQL::Schema::Object,
38
+ interface: GraphQL::Schema::Interface,
39
+ union: GraphQL::Schema::Union,
40
+ scalar: GraphQL::Schema::Scalar,
41
+ enum: GraphQL::Schema::Enum,
42
+ input_object: GraphQL::Schema::InputObject,
43
+ }.merge!(base_types)
44
+
30
45
  if default_resolve.is_a?(Hash)
31
46
  default_resolve = ResolveMap.new(default_resolve)
32
47
  end
@@ -47,7 +62,7 @@ module GraphQL
47
62
  types[type_name] ||= begin
48
63
  defn = document.definitions.find { |d| d.respond_to?(:name) && d.name == type_name }
49
64
  if defn
50
- build_definition_from_node(defn, directive_type_resolver, default_resolve)
65
+ build_definition_from_node(defn, directive_type_resolver, default_resolve, base_types)
51
66
  elsif (built_in_defn = GraphQL::Schema::BUILT_IN_TYPES[type_name])
52
67
  built_in_defn
53
68
  else
@@ -71,14 +86,30 @@ module GraphQL
71
86
  case definition
72
87
  when GraphQL::Language::Nodes::SchemaDefinition, GraphQL::Language::Nodes::DirectiveDefinition
73
88
  nil # already handled
74
- when GraphQL::Language::Nodes::SchemaExtension
89
+ when GraphQL::Language::Nodes::SchemaExtension,
90
+ GraphQL::Language::Nodes::ScalarTypeExtension,
91
+ GraphQL::Language::Nodes::ObjectTypeExtension,
92
+ GraphQL::Language::Nodes::InterfaceTypeExtension,
93
+ GraphQL::Language::Nodes::UnionTypeExtension,
94
+ GraphQL::Language::Nodes::EnumTypeExtension,
95
+ GraphQL::Language::Nodes::InputObjectTypeExtension
75
96
  schema_extensions ||= []
76
97
  schema_extensions << definition
77
98
  else
78
99
  # It's possible that this was already loaded by the directives
79
100
  prev_type = types[definition.name]
80
101
  if prev_type.nil? || prev_type.is_a?(Schema::LateBoundType)
81
- types[definition.name] = build_definition_from_node(definition, type_resolver, default_resolve)
102
+ if definition.is_a?(GraphQL::Language::Nodes::ObjectTypeDefinition) || definition.is_a?(Language::Nodes::InterfaceTypeDefinition)
103
+ interface_names = definition.interfaces.map(&:name)
104
+ transitive_names = interface_names.map { |n| document.definitions.find { |d| d.respond_to?(:name) && d.name == n }&.interfaces&.map(&:name) }
105
+ transitive_names.flatten!
106
+ transitive_names.compact!
107
+ if !(missing_transitive_interfaces = transitive_names - interface_names).empty?
108
+ raise GraphQL::Schema::InvalidDocumentError, "type #{definition.name} is missing one or more transitive interface names: #{missing_transitive_interfaces.join(", ")}. Add them to the type's `implements` list and try again."
109
+ end
110
+ end
111
+
112
+ types[definition.name] = build_definition_from_node(definition, type_resolver, default_resolve, base_types)
82
113
  end
83
114
  end
84
115
  end
@@ -118,12 +149,43 @@ module GraphQL
118
149
 
119
150
  raise InvalidDocumentError.new('Must provide schema definition with query type or a type named Query.') unless query_root_type
120
151
 
152
+ schema_extensions&.each do |ext|
153
+ next if ext.is_a?(GraphQL::Language::Nodes::SchemaExtension)
154
+
155
+ built_type = types[ext.name]
156
+
157
+ case ext
158
+ when GraphQL::Language::Nodes::ScalarTypeExtension
159
+ build_directives(built_type, ext, type_resolver)
160
+ when GraphQL::Language::Nodes::ObjectTypeExtension
161
+ build_directives(built_type, ext, type_resolver)
162
+ build_fields(built_type, ext.fields, type_resolver, default_resolve: true)
163
+ build_interfaces(built_type, ext.interfaces, type_resolver)
164
+ when GraphQL::Language::Nodes::InterfaceTypeExtension
165
+ build_directives(built_type, ext, type_resolver)
166
+ build_fields(built_type, ext.fields, type_resolver, default_resolve: nil)
167
+ build_interfaces(built_type, ext.interfaces, type_resolver)
168
+ when GraphQL::Language::Nodes::UnionTypeExtension
169
+ build_directives(built_type, ext, type_resolver)
170
+ built_type.possible_types(*ext.types.map { |type_name| type_resolver.call(type_name) })
171
+ when GraphQL::Language::Nodes::EnumTypeExtension
172
+ build_directives(built_type, ext, type_resolver)
173
+ build_values(built_type, ext.values, type_resolver)
174
+ when GraphQL::Language::Nodes::InputObjectTypeExtension
175
+ build_directives(built_type, ext, type_resolver)
176
+ build_arguments(built_type, ext.fields, type_resolver)
177
+ end
178
+ end
179
+
121
180
  builder = self
122
181
 
182
+ found_types = types.values
183
+ object_types = found_types.select { |t| t.respond_to?(:kind) && t.kind.object? }
123
184
  schema_class = Class.new(schema_superclass) do
124
185
  begin
125
186
  # Add these first so that there's some chance of resolving late-bound types
126
- orphan_types types.values
187
+ add_type_and_traverse(found_types, root: false)
188
+ orphan_types(object_types)
127
189
  query query_root_type
128
190
  mutation mutation_root_type
129
191
  subscription subscription_root_type
@@ -133,6 +195,16 @@ module GraphQL
133
195
  raise InvalidDocumentError, "Type \"#{type_name}\" not found in document.", err_backtrace
134
196
  end
135
197
 
198
+ object_types.each do |t|
199
+ t.interfaces.each do |int_t|
200
+ if int_t.is_a?(LateBoundType)
201
+ int_t = types[int_t.graphql_name]
202
+ t.implements(int_t)
203
+ end
204
+ int_t.orphan_types(t)
205
+ end
206
+ end
207
+
136
208
  if default_resolve.respond_to?(:resolve_type)
137
209
  def self.resolve_type(*args)
138
210
  self.definition_default_resolve.resolve_type(*args)
@@ -173,11 +245,12 @@ module GraphQL
173
245
 
174
246
  def self.inherited(child_class)
175
247
  child_class.definition_default_resolve = self.definition_default_resolve
248
+ super
176
249
  end
177
250
  end
178
251
 
179
- if schema_extensions
180
- schema_extensions.each do |ext|
252
+ schema_extensions&.each do |ext|
253
+ if ext.is_a?(GraphQL::Language::Nodes::SchemaExtension)
181
254
  build_directives(schema_class, ext, type_resolver)
182
255
  end
183
256
  end
@@ -189,20 +262,22 @@ module GraphQL
189
262
  raise(GraphQL::RequiredImplementationMissingError, "Generated Schema cannot use Interface or Union types for execution. Implement resolve_type on your resolver.")
190
263
  }
191
264
 
192
- def build_definition_from_node(definition, type_resolver, default_resolve)
265
+ def build_definition_from_node(definition, type_resolver, default_resolve, base_types)
193
266
  case definition
194
267
  when GraphQL::Language::Nodes::EnumTypeDefinition
195
- build_enum_type(definition, type_resolver)
268
+ build_enum_type(definition, type_resolver, base_types[:enum])
196
269
  when GraphQL::Language::Nodes::ObjectTypeDefinition
197
- build_object_type(definition, type_resolver)
270
+ build_object_type(definition, type_resolver, base_types[:object])
198
271
  when GraphQL::Language::Nodes::InterfaceTypeDefinition
199
- build_interface_type(definition, type_resolver)
272
+ build_interface_type(definition, type_resolver, base_types[:interface])
200
273
  when GraphQL::Language::Nodes::UnionTypeDefinition
201
- build_union_type(definition, type_resolver)
274
+ build_union_type(definition, type_resolver, base_types[:union])
202
275
  when GraphQL::Language::Nodes::ScalarTypeDefinition
203
- build_scalar_type(definition, type_resolver, default_resolve: default_resolve)
276
+ build_scalar_type(definition, type_resolver, base_types[:scalar], default_resolve: default_resolve)
204
277
  when GraphQL::Language::Nodes::InputObjectTypeDefinition
205
- build_input_object_type(definition, type_resolver)
278
+ build_input_object_type(definition, type_resolver, base_types[:input_object])
279
+ when GraphQL::Language::Nodes::DirectiveDefinition
280
+ build_directive(definition, type_resolver)
206
281
  end
207
282
  end
208
283
 
@@ -268,22 +343,26 @@ module GraphQL
268
343
  end
269
344
  end
270
345
 
271
- def build_enum_type(enum_type_definition, type_resolver)
346
+ def build_enum_type(enum_type_definition, type_resolver, base_type)
272
347
  builder = self
273
- Class.new(GraphQL::Schema::Enum) do
348
+ Class.new(base_type) do
274
349
  graphql_name(enum_type_definition.name)
275
350
  builder.build_directives(self, enum_type_definition, type_resolver)
276
351
  description(enum_type_definition.description)
277
352
  ast_node(enum_type_definition)
278
- enum_type_definition.values.each do |enum_value_definition|
279
- value(enum_value_definition.name,
280
- value: enum_value_definition.name,
281
- deprecation_reason: builder.build_deprecation_reason(enum_value_definition.directives),
282
- description: enum_value_definition.description,
283
- directives: builder.prepare_directives(enum_value_definition, type_resolver),
284
- ast_node: enum_value_definition,
285
- )
286
- end
353
+ builder.build_values(self, enum_type_definition.values, type_resolver)
354
+ end
355
+ end
356
+
357
+ def build_values(type_class, enum_value_definitions, type_resolver)
358
+ enum_value_definitions.each do |enum_value_definition|
359
+ type_class.value(enum_value_definition.name,
360
+ value: enum_value_definition.name,
361
+ deprecation_reason: build_deprecation_reason(enum_value_definition.directives),
362
+ description: enum_value_definition.description,
363
+ directives: prepare_directives(enum_value_definition, type_resolver),
364
+ ast_node: enum_value_definition,
365
+ )
287
366
  end
288
367
  end
289
368
 
@@ -297,9 +376,9 @@ module GraphQL
297
376
  reason.value
298
377
  end
299
378
 
300
- def build_scalar_type(scalar_type_definition, type_resolver, default_resolve:)
379
+ def build_scalar_type(scalar_type_definition, type_resolver, base_type, default_resolve:)
301
380
  builder = self
302
- Class.new(GraphQL::Schema::Scalar) do
381
+ Class.new(base_type) do
303
382
  graphql_name(scalar_type_definition.name)
304
383
  description(scalar_type_definition.description)
305
384
  ast_node(scalar_type_definition)
@@ -320,9 +399,9 @@ module GraphQL
320
399
  end
321
400
  end
322
401
 
323
- def build_union_type(union_type_definition, type_resolver)
402
+ def build_union_type(union_type_definition, type_resolver, base_type)
324
403
  builder = self
325
- Class.new(GraphQL::Schema::Union) do
404
+ Class.new(base_type) do
326
405
  graphql_name(union_type_definition.name)
327
406
  description(union_type_definition.description)
328
407
  possible_types(*union_type_definition.types.map { |type_name| type_resolver.call(type_name) })
@@ -331,27 +410,28 @@ module GraphQL
331
410
  end
332
411
  end
333
412
 
334
- def build_object_type(object_type_definition, type_resolver)
413
+ def build_object_type(object_type_definition, type_resolver, base_type)
335
414
  builder = self
336
415
 
337
- Class.new(GraphQL::Schema::Object) do
416
+ Class.new(base_type) do
338
417
  graphql_name(object_type_definition.name)
339
418
  description(object_type_definition.description)
340
419
  ast_node(object_type_definition)
341
420
  builder.build_directives(self, object_type_definition, type_resolver)
342
-
343
- object_type_definition.interfaces.each do |interface_name|
344
- interface_defn = type_resolver.call(interface_name)
345
- implements(interface_defn)
346
- end
347
-
421
+ builder.build_interfaces(self, object_type_definition.interfaces, type_resolver)
348
422
  builder.build_fields(self, object_type_definition.fields, type_resolver, default_resolve: true)
349
423
  end
350
424
  end
351
425
 
352
- def build_input_object_type(input_object_type_definition, type_resolver)
426
+ def build_interfaces(type_class, interface_names, type_resolver)
427
+ interface_names.each do |interface_name|
428
+ type_class.implements(type_resolver.call(interface_name))
429
+ end
430
+ end
431
+
432
+ def build_input_object_type(input_object_type_definition, type_resolver, base_type)
353
433
  builder = self
354
- Class.new(GraphQL::Schema::InputObject) do
434
+ Class.new(base_type) do
355
435
  graphql_name(input_object_type_definition.name)
356
436
  description(input_object_type_definition.description)
357
437
  ast_node(input_object_type_definition)
@@ -411,16 +491,13 @@ module GraphQL
411
491
  end
412
492
  end
413
493
 
414
- def build_interface_type(interface_type_definition, type_resolver)
494
+ def build_interface_type(interface_type_definition, type_resolver, base_type)
415
495
  builder = self
416
496
  Module.new do
417
- include GraphQL::Schema::Interface
497
+ include base_type
418
498
  graphql_name(interface_type_definition.name)
419
499
  description(interface_type_definition.description)
420
- interface_type_definition.interfaces.each do |interface_name|
421
- interface_defn = type_resolver.call(interface_name)
422
- implements(interface_defn)
423
- end
500
+ builder.build_interfaces(self, interface_type_definition.interfaces, type_resolver)
424
501
  ast_node(interface_type_definition)
425
502
  builder.build_directives(self, interface_type_definition, type_resolver)
426
503
 
@@ -432,14 +509,12 @@ module GraphQL
432
509
  builder = self
433
510
 
434
511
  field_definitions.each do |field_definition|
435
- type_name = resolve_type_name(field_definition.type)
436
512
  resolve_method_name = -"resolve_field_#{field_definition.name}"
437
513
  schema_field_defn = owner.field(
438
514
  field_definition.name,
439
515
  description: field_definition.description,
440
516
  type: type_resolver.call(field_definition.type),
441
517
  null: true,
442
- connection: type_name.end_with?("Connection"),
443
518
  connection_extension: nil,
444
519
  deprecation_reason: build_deprecation_reason(field_definition.directives),
445
520
  ast_node: field_definition,
@@ -447,23 +522,31 @@ module GraphQL
447
522
  camelize: false,
448
523
  directives: prepare_directives(field_definition, type_resolver),
449
524
  resolver_method: resolve_method_name,
525
+ resolve_batch: resolve_method_name,
450
526
  )
451
527
 
452
528
  builder.build_arguments(schema_field_defn, field_definition.arguments, type_resolver)
453
529
 
454
530
  # Don't do this for interfaces
455
531
  if default_resolve
456
- owner.class_eval <<-RUBY, __FILE__, __LINE__
457
- # frozen_string_literal: true
458
- def #{resolve_method_name}(**args)
459
- field_instance = self.class.get_field("#{field_definition.name}")
460
- context.schema.definition_default_resolve.call(self.class, field_instance, object, args, context)
461
- end
462
- RUBY
532
+ define_field_resolve_method(owner, resolve_method_name, field_definition.name)
463
533
  end
464
534
  end
465
535
  end
466
536
 
537
+ def define_field_resolve_method(owner, method_name, field_name)
538
+ owner.define_method(method_name) { |**args|
539
+ field_instance = context.types.field(owner, field_name)
540
+ context.schema.definition_default_resolve.call(self.class, field_instance, object, args, context)
541
+ }
542
+ owner.define_singleton_method(method_name) { |objects, context, **args|
543
+ field_instance = context.types.field(owner, field_name)
544
+ objects.map do |object|
545
+ context.schema.definition_default_resolve.call(self, field_instance, object, args, context)
546
+ end
547
+ }
548
+ end
549
+
467
550
  def build_resolve_type(lookup_hash, directives, missing_type_handler)
468
551
  resolve_type_proc = nil
469
552
  resolve_type_proc = ->(ast_node) {
@@ -480,22 +563,13 @@ module GraphQL
480
563
  when GraphQL::Language::Nodes::ListType
481
564
  resolve_type_proc.call(ast_node.of_type).to_list_type
482
565
  when String
483
- directives[ast_node]
566
+ directives[ast_node] ||= missing_type_handler.call(ast_node)
484
567
  else
485
568
  raise "Unexpected ast_node: #{ast_node.inspect}"
486
569
  end
487
570
  }
488
571
  resolve_type_proc
489
572
  end
490
-
491
- def resolve_type_name(type)
492
- case type
493
- when GraphQL::Language::Nodes::TypeName
494
- return type.name
495
- else
496
- resolve_type_name(type.of_type)
497
- end
498
- end
499
573
  end
500
574
 
501
575
  private_constant :Builder
@@ -7,7 +7,7 @@ module GraphQL
7
7
  # In this case, the server hides types and fields _entirely_, unless the current context has certain `:flags` present.
8
8
  class Flagged < GraphQL::Schema::Directive
9
9
  def initialize(target, **options)
10
- if target.is_a?(Module) && !target.ancestors.include?(VisibleByFlag)
10
+ if target.is_a?(Module)
11
11
  # This is type class of some kind, `include` will put this module
12
12
  # in between the type class itself and its super class, so `super` will work fine
13
13
  target.include(VisibleByFlag)
@@ -37,6 +37,8 @@ module GraphQL
37
37
 
38
38
  argument :by, [String], "Flags to check for this schema member"
39
39
 
40
+ repeatable(true)
41
+
40
42
  module VisibleByFlag
41
43
  def self.included(schema_class)
42
44
  schema_class.extend(self)
@@ -45,7 +47,7 @@ module GraphQL
45
47
  def visible?(context)
46
48
  if dir = self.directives.find { |d| d.is_a?(Flagged) }
47
49
  relevant_flags = (f = context[:flags]) && dir.arguments[:by] & f # rubocop:disable Development/ContextIsPassedCop -- definition-related
48
- relevant_flags && relevant_flags.any? && super
50
+ relevant_flags && !relevant_flags.empty? && super
49
51
  else
50
52
  super
51
53
  end
@@ -6,6 +6,18 @@ module GraphQL
6
6
  description "Requires that exactly one field must be supplied and that field must not be `null`."
7
7
  locations(GraphQL::Schema::Directive::INPUT_OBJECT)
8
8
  default_directive true
9
+
10
+ def initialize(...)
11
+ super
12
+
13
+ owner.extend(IsOneOf)
14
+ end
15
+
16
+ module IsOneOf
17
+ def one_of?
18
+ true
19
+ end
20
+ end
9
21
  end
10
22
  end
11
23
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ class Schema
4
+ class Directive < GraphQL::Schema::Member
5
+ class SpecifiedBy < GraphQL::Schema::Directive
6
+ description "Exposes a URL that specifies the behavior of this scalar."
7
+ locations(GraphQL::Schema::Directive::SCALAR)
8
+ default_directive true
9
+
10
+ argument :url, String, description: "The URL that specifies the behavior of this scalar."
11
+ end
12
+ end
13
+ end
14
+ end
@@ -9,6 +9,7 @@ module GraphQL
9
9
  class Directive < GraphQL::Schema::Member
10
10
  extend GraphQL::Schema::Member::HasArguments
11
11
  extend GraphQL::Schema::Member::HasArguments::HasDirectiveArguments
12
+ extend GraphQL::Schema::Member::HasValidators
12
13
 
13
14
  class << self
14
15
  # Directives aren't types, they don't have kinds.
@@ -29,18 +30,26 @@ module GraphQL
29
30
  end
30
31
 
31
32
  def locations(*new_locations)
32
- if new_locations.any?
33
+ if !new_locations.empty?
34
+ is_runtime = false
33
35
  new_locations.each do |new_loc|
34
- if !LOCATIONS.include?(new_loc.to_sym)
36
+ loc_sym = new_loc.to_sym
37
+ if !LOCATIONS.include?(loc_sym)
35
38
  raise ArgumentError, "#{self} (#{self.graphql_name}) has an invalid directive location: `locations #{new_loc}` "
36
39
  end
40
+ is_runtime ||= RUNTIME_LOCATIONS.include?(loc_sym)
37
41
  end
38
42
  @locations = new_locations
43
+ @is_runtime = is_runtime
39
44
  else
40
45
  @locations ||= (superclass.respond_to?(:locations) ? superclass.locations : [])
41
46
  end
42
47
  end
43
48
 
49
+ def runtime?
50
+ @is_runtime
51
+ end
52
+
44
53
  def default_directive(new_default_directive = nil)
45
54
  if new_default_directive != nil
46
55
  @default_directive = new_default_directive
@@ -75,6 +84,10 @@ module GraphQL
75
84
  yield
76
85
  end
77
86
 
87
+ def validate!(arguments, context)
88
+ Schema::Validator.validate!(validators, self, context, arguments)
89
+ end
90
+
78
91
  def on_field?
79
92
  locations.include?(FIELD)
80
93
  end
@@ -99,8 +112,12 @@ module GraphQL
99
112
 
100
113
  def inherited(subclass)
101
114
  super
102
- subclass.class_eval do
115
+ parent_class = self
116
+ subclass.class_exec do
103
117
  @default_graphql_name ||= nil
118
+ @locations = parent_class.locations
119
+ @is_runtime = parent_class.runtime?
120
+ @repeatable = false
104
121
  end
105
122
  end
106
123
  end
@@ -111,6 +128,9 @@ module GraphQL
111
128
  # @return [GraphQL::Interpreter::Arguments]
112
129
  attr_reader :arguments
113
130
 
131
+ class InvalidArgumentError < GraphQL::Error
132
+ end
133
+
114
134
  def initialize(owner, **arguments)
115
135
  @owner = owner
116
136
  assert_valid_owner
@@ -119,7 +139,49 @@ module GraphQL
119
139
  # - lazy resolution
120
140
  # Probably, those won't be needed here, since these are configuration arguments,
121
141
  # not runtime arguments.
122
- @arguments = self.class.coerce_arguments(nil, arguments, Query::NullContext)
142
+ context = Query::NullContext.instance
143
+ self.class.all_argument_definitions.each do |arg_defn|
144
+ keyword = arg_defn.keyword
145
+ arg_type = arg_defn.type
146
+ if arguments.key?(keyword)
147
+ value = arguments[keyword]
148
+ # This is a Ruby-land value; convert it to graphql for validation
149
+ graphql_value = begin
150
+ coerce_value = value
151
+ if arg_type.list? && (!coerce_value.nil?) && (!coerce_value.is_a?(Array))
152
+ # When validating inputs, GraphQL accepts a single item
153
+ # and implicitly converts it to a one-item list.
154
+ # However, we're using result coercion here to go from Ruby value
155
+ # to GraphQL value, so it doesn't have that feature.
156
+ # Keep the GraphQL-type behavior but implement it manually:
157
+ wrap_type = arg_type
158
+ while wrap_type.list?
159
+ if wrap_type.non_null?
160
+ wrap_type = wrap_type.of_type
161
+ end
162
+ wrap_type = wrap_type.of_type
163
+ coerce_value = [coerce_value]
164
+ end
165
+ end
166
+ arg_type.coerce_isolated_result(coerce_value)
167
+ rescue GraphQL::Schema::Enum::UnresolvedValueError
168
+ # Let validation handle this
169
+ value
170
+ end
171
+ else
172
+ value = graphql_value = nil
173
+ end
174
+
175
+ result = arg_type.validate_input(graphql_value, context)
176
+ if !result.valid?
177
+ raise InvalidArgumentError, "@#{graphql_name}.#{arg_defn.graphql_name} on #{owner.path} is invalid (#{value.inspect}): #{result.problems.first["explanation"]}"
178
+ end
179
+ end
180
+ self.class.validate!(arguments, context)
181
+ @arguments = self.class.coerce_arguments(nil, arguments, context)
182
+ if @arguments.is_a?(GraphQL::ExecutionError)
183
+ raise @arguments
184
+ end
123
185
  end
124
186
 
125
187
  def graphql_name
@@ -127,13 +189,16 @@ module GraphQL
127
189
  end
128
190
 
129
191
  LOCATIONS = [
130
- QUERY = :QUERY,
131
- MUTATION = :MUTATION,
132
- SUBSCRIPTION = :SUBSCRIPTION,
133
- FIELD = :FIELD,
134
- FRAGMENT_DEFINITION = :FRAGMENT_DEFINITION,
135
- FRAGMENT_SPREAD = :FRAGMENT_SPREAD,
136
- INLINE_FRAGMENT = :INLINE_FRAGMENT,
192
+ *(RUNTIME_LOCATIONS = [
193
+ QUERY = :QUERY,
194
+ MUTATION = :MUTATION,
195
+ SUBSCRIPTION = :SUBSCRIPTION,
196
+ FIELD = :FIELD,
197
+ FRAGMENT_DEFINITION = :FRAGMENT_DEFINITION,
198
+ FRAGMENT_SPREAD = :FRAGMENT_SPREAD,
199
+ INLINE_FRAGMENT = :INLINE_FRAGMENT,
200
+ VARIABLE_DEFINITION = :VARIABLE_DEFINITION,
201
+ ]),
137
202
  SCHEMA = :SCHEMA,
138
203
  SCALAR = :SCALAR,
139
204
  OBJECT = :OBJECT,
@@ -145,7 +210,6 @@ module GraphQL
145
210
  ENUM_VALUE = :ENUM_VALUE,
146
211
  INPUT_OBJECT = :INPUT_OBJECT,
147
212
  INPUT_FIELD_DEFINITION = :INPUT_FIELD_DEFINITION,
148
- VARIABLE_DEFINITION = :VARIABLE_DEFINITION,
149
213
  ]
150
214
 
151
215
  DEFAULT_DEPRECATION_REASON = 'No longer supported'
@@ -188,6 +252,8 @@ module GraphQL
188
252
  assert_has_location(SCALAR)
189
253
  elsif @owner < GraphQL::Schema
190
254
  assert_has_location(SCHEMA)
255
+ elsif @owner < GraphQL::Schema::Resolver
256
+ assert_has_location(FIELD_DEFINITION)
191
257
  else
192
258
  raise "Unexpected directive owner class: #{@owner}"
193
259
  end