graphql 1.9.21 → 2.0.0

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 (397) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/core.rb +21 -10
  3. data/lib/generators/graphql/enum_generator.rb +4 -10
  4. data/lib/generators/graphql/field_extractor.rb +31 -0
  5. data/lib/generators/graphql/input_generator.rb +50 -0
  6. data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
  7. data/lib/generators/graphql/{templates → install/templates}/base_mutation.erb +2 -0
  8. data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +2 -0
  9. data/lib/generators/graphql/install_generator.rb +44 -7
  10. data/lib/generators/graphql/interface_generator.rb +7 -7
  11. data/lib/generators/graphql/loader_generator.rb +1 -0
  12. data/lib/generators/graphql/mutation_create_generator.rb +22 -0
  13. data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
  14. data/lib/generators/graphql/mutation_generator.rb +6 -30
  15. data/lib/generators/graphql/mutation_update_generator.rb +22 -0
  16. data/lib/generators/graphql/object_generator.rb +28 -12
  17. data/lib/generators/graphql/orm_mutations_base.rb +40 -0
  18. data/lib/generators/graphql/relay.rb +63 -0
  19. data/lib/generators/graphql/relay_generator.rb +21 -0
  20. data/lib/generators/graphql/scalar_generator.rb +4 -2
  21. data/lib/generators/graphql/templates/base_argument.erb +2 -0
  22. data/lib/generators/graphql/templates/base_connection.erb +8 -0
  23. data/lib/generators/graphql/templates/base_edge.erb +8 -0
  24. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  25. data/lib/generators/graphql/templates/base_field.erb +2 -0
  26. data/lib/generators/graphql/templates/base_input_object.erb +2 -0
  27. data/lib/generators/graphql/templates/base_interface.erb +2 -0
  28. data/lib/generators/graphql/templates/base_object.erb +2 -0
  29. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  30. data/lib/generators/graphql/templates/base_union.erb +2 -0
  31. data/lib/generators/graphql/templates/enum.erb +7 -1
  32. data/lib/generators/graphql/templates/graphql_controller.erb +16 -12
  33. data/lib/generators/graphql/templates/input.erb +9 -0
  34. data/lib/generators/graphql/templates/interface.erb +6 -2
  35. data/lib/generators/graphql/templates/loader.erb +2 -0
  36. data/lib/generators/graphql/templates/mutation.erb +3 -1
  37. data/lib/generators/graphql/templates/mutation_create.erb +20 -0
  38. data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
  39. data/lib/generators/graphql/templates/mutation_update.erb +21 -0
  40. data/lib/generators/graphql/templates/node_type.erb +9 -0
  41. data/lib/generators/graphql/templates/object.erb +7 -3
  42. data/lib/generators/graphql/templates/query_type.erb +3 -3
  43. data/lib/generators/graphql/templates/scalar.erb +5 -1
  44. data/lib/generators/graphql/templates/schema.erb +22 -27
  45. data/lib/generators/graphql/templates/union.erb +6 -2
  46. data/lib/generators/graphql/type_generator.rb +47 -10
  47. data/lib/generators/graphql/union_generator.rb +5 -5
  48. data/lib/graphql/analysis/ast/field_usage.rb +29 -2
  49. data/lib/graphql/analysis/ast/query_complexity.rb +175 -68
  50. data/lib/graphql/analysis/ast/query_depth.rb +0 -1
  51. data/lib/graphql/analysis/ast/visitor.rb +17 -8
  52. data/lib/graphql/analysis/ast.rb +14 -14
  53. data/lib/graphql/analysis.rb +0 -7
  54. data/lib/graphql/backtrace/inspect_result.rb +0 -1
  55. data/lib/graphql/backtrace/table.rb +37 -16
  56. data/lib/graphql/backtrace/traced_error.rb +0 -1
  57. data/lib/graphql/backtrace/tracer.rb +39 -9
  58. data/lib/graphql/backtrace.rb +20 -17
  59. data/lib/graphql/dataloader/null_dataloader.rb +22 -0
  60. data/lib/graphql/dataloader/request.rb +19 -0
  61. data/lib/graphql/dataloader/request_all.rb +19 -0
  62. data/lib/graphql/dataloader/source.rb +155 -0
  63. data/lib/graphql/dataloader.rb +308 -0
  64. data/lib/graphql/date_encoding_error.rb +16 -0
  65. data/lib/graphql/deprecation.rb +9 -0
  66. data/lib/graphql/dig.rb +1 -1
  67. data/lib/graphql/execution/directive_checks.rb +2 -2
  68. data/lib/graphql/execution/errors.rb +108 -14
  69. data/lib/graphql/execution/instrumentation.rb +1 -1
  70. data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
  71. data/lib/graphql/execution/interpreter/arguments.rb +88 -0
  72. data/lib/graphql/execution/interpreter/arguments_cache.rb +105 -0
  73. data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
  74. data/lib/graphql/execution/interpreter/resolve.rb +37 -25
  75. data/lib/graphql/execution/interpreter/runtime.rb +715 -387
  76. data/lib/graphql/execution/interpreter.rb +32 -31
  77. data/lib/graphql/execution/lazy/lazy_method_map.rb +4 -0
  78. data/lib/graphql/execution/lazy.rb +5 -1
  79. data/lib/graphql/execution/lookahead.rb +32 -114
  80. data/lib/graphql/execution/multiplex.rb +60 -92
  81. data/lib/graphql/execution.rb +11 -3
  82. data/lib/graphql/filter.rb +1 -1
  83. data/lib/graphql/integer_decoding_error.rb +17 -0
  84. data/lib/graphql/integer_encoding_error.rb +18 -2
  85. data/lib/graphql/introspection/base_object.rb +2 -5
  86. data/lib/graphql/introspection/directive_location_enum.rb +2 -2
  87. data/lib/graphql/introspection/directive_type.rb +11 -5
  88. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  89. data/lib/graphql/introspection/entry_points.rb +5 -18
  90. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  91. data/lib/graphql/introspection/field_type.rb +9 -5
  92. data/lib/graphql/introspection/input_value_type.rb +41 -11
  93. data/lib/graphql/introspection/introspection_query.rb +6 -92
  94. data/lib/graphql/introspection/schema_type.rb +10 -10
  95. data/lib/graphql/introspection/type_type.rb +27 -17
  96. data/lib/graphql/introspection.rb +99 -0
  97. data/lib/graphql/invalid_null_error.rb +18 -0
  98. data/lib/graphql/language/block_string.rb +20 -5
  99. data/lib/graphql/language/cache.rb +37 -0
  100. data/lib/graphql/language/definition_slice.rb +21 -10
  101. data/lib/graphql/language/document_from_schema_definition.rb +99 -63
  102. data/lib/graphql/language/lexer.rb +53 -27
  103. data/lib/graphql/language/lexer.rl +5 -3
  104. data/lib/graphql/language/nodes.rb +64 -93
  105. data/lib/graphql/language/parser.rb +929 -896
  106. data/lib/graphql/language/parser.y +125 -102
  107. data/lib/graphql/language/printer.rb +11 -2
  108. data/lib/graphql/language/sanitized_printer.rb +222 -0
  109. data/lib/graphql/language/token.rb +0 -4
  110. data/lib/graphql/language/visitor.rb +2 -2
  111. data/lib/graphql/language.rb +3 -1
  112. data/lib/graphql/name_validator.rb +2 -7
  113. data/lib/graphql/pagination/active_record_relation_connection.rb +85 -0
  114. data/lib/graphql/pagination/array_connection.rb +77 -0
  115. data/lib/graphql/pagination/connection.rb +226 -0
  116. data/lib/graphql/pagination/connections.rb +134 -0
  117. data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
  118. data/lib/graphql/pagination/relation_connection.rb +226 -0
  119. data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
  120. data/lib/graphql/pagination.rb +6 -0
  121. data/lib/graphql/parse_error.rb +0 -1
  122. data/lib/graphql/query/context.rb +51 -190
  123. data/lib/graphql/query/fingerprint.rb +26 -0
  124. data/lib/graphql/query/input_validation_result.rb +23 -6
  125. data/lib/graphql/query/literal_input.rb +26 -11
  126. data/lib/graphql/query/null_context.rb +24 -8
  127. data/lib/graphql/query/validation_pipeline.rb +12 -38
  128. data/lib/graphql/query/variable_validation_error.rb +2 -2
  129. data/lib/graphql/query/variables.rb +26 -9
  130. data/lib/graphql/query.rb +62 -32
  131. data/lib/graphql/railtie.rb +6 -102
  132. data/lib/graphql/rake_task/validate.rb +3 -0
  133. data/lib/graphql/rake_task.rb +12 -9
  134. data/lib/graphql/relay/range_add.rb +23 -9
  135. data/lib/graphql/relay.rb +0 -15
  136. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  137. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  138. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  139. data/lib/graphql/rubocop.rb +4 -0
  140. data/lib/graphql/schema/addition.rb +240 -0
  141. data/lib/graphql/schema/argument.rb +262 -28
  142. data/lib/graphql/schema/base_64_encoder.rb +2 -0
  143. data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
  144. data/lib/graphql/schema/build_from_definition/resolve_map.rb +13 -5
  145. data/lib/graphql/schema/build_from_definition.rb +319 -220
  146. data/lib/graphql/schema/built_in_types.rb +5 -5
  147. data/lib/graphql/schema/directive/deprecated.rb +18 -0
  148. data/lib/graphql/schema/directive/feature.rb +1 -1
  149. data/lib/graphql/schema/directive/flagged.rb +57 -0
  150. data/lib/graphql/schema/directive/include.rb +2 -2
  151. data/lib/graphql/schema/directive/skip.rb +2 -2
  152. data/lib/graphql/schema/directive/transform.rb +14 -2
  153. data/lib/graphql/schema/directive.rb +117 -14
  154. data/lib/graphql/schema/enum.rb +115 -22
  155. data/lib/graphql/schema/enum_value.rb +16 -21
  156. data/lib/graphql/schema/field/connection_extension.rb +46 -20
  157. data/lib/graphql/schema/field/scope_extension.rb +1 -1
  158. data/lib/graphql/schema/field.rb +376 -291
  159. data/lib/graphql/schema/field_extension.rb +89 -2
  160. data/lib/graphql/schema/find_inherited_value.rb +17 -1
  161. data/lib/graphql/schema/finder.rb +16 -14
  162. data/lib/graphql/schema/input_object.rb +147 -60
  163. data/lib/graphql/schema/interface.rb +28 -43
  164. data/lib/graphql/schema/introspection_system.rb +101 -38
  165. data/lib/graphql/schema/late_bound_type.rb +3 -2
  166. data/lib/graphql/schema/list.rb +46 -3
  167. data/lib/graphql/schema/loader.rb +144 -102
  168. data/lib/graphql/schema/member/base_dsl_methods.rb +33 -32
  169. data/lib/graphql/schema/member/build_type.rb +23 -14
  170. data/lib/graphql/schema/member/has_arguments.rb +212 -23
  171. data/lib/graphql/schema/member/has_ast_node.rb +20 -0
  172. data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
  173. data/lib/graphql/schema/member/has_directives.rb +98 -0
  174. data/lib/graphql/schema/member/has_fields.rb +99 -34
  175. data/lib/graphql/schema/member/has_interfaces.rb +88 -0
  176. data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
  177. data/lib/graphql/schema/member/has_validators.rb +31 -0
  178. data/lib/graphql/schema/member/type_system_helpers.rb +3 -3
  179. data/lib/graphql/schema/member/validates_input.rb +33 -0
  180. data/lib/graphql/schema/member.rb +11 -6
  181. data/lib/graphql/schema/mutation.rb +4 -9
  182. data/lib/graphql/schema/non_null.rb +34 -4
  183. data/lib/graphql/schema/object.rb +38 -65
  184. data/lib/graphql/schema/printer.rb +16 -35
  185. data/lib/graphql/schema/relay_classic_mutation.rb +57 -32
  186. data/lib/graphql/schema/resolver/has_payload_type.rb +34 -4
  187. data/lib/graphql/schema/resolver.rb +133 -79
  188. data/lib/graphql/schema/scalar.rb +40 -15
  189. data/lib/graphql/schema/subscription.rb +57 -21
  190. data/lib/graphql/schema/timeout.rb +29 -15
  191. data/lib/graphql/schema/type_expression.rb +21 -13
  192. data/lib/graphql/schema/type_membership.rb +19 -5
  193. data/lib/graphql/schema/union.rb +39 -14
  194. data/lib/graphql/schema/unique_within_type.rb +1 -2
  195. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  196. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  197. data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
  198. data/lib/graphql/schema/validator/format_validator.rb +48 -0
  199. data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
  200. data/lib/graphql/schema/validator/length_validator.rb +59 -0
  201. data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
  202. data/lib/graphql/schema/validator/required_validator.rb +82 -0
  203. data/lib/graphql/schema/validator.rb +171 -0
  204. data/lib/graphql/schema/warden.rb +182 -32
  205. data/lib/graphql/schema/wrapper.rb +0 -5
  206. data/lib/graphql/schema.rb +687 -891
  207. data/lib/graphql/static_validation/all_rules.rb +2 -0
  208. data/lib/graphql/static_validation/base_visitor.rb +21 -31
  209. data/lib/graphql/static_validation/definition_dependencies.rb +0 -1
  210. data/lib/graphql/static_validation/error.rb +3 -1
  211. data/lib/graphql/static_validation/literal_validator.rb +51 -26
  212. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +45 -83
  213. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
  214. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +35 -26
  215. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
  216. data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
  217. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +14 -14
  218. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +4 -4
  219. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -5
  220. data/lib/graphql/static_validation/rules/fields_will_merge.rb +94 -51
  221. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
  222. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  223. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
  224. data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
  225. data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
  226. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  227. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  228. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -2
  229. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +9 -10
  230. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
  231. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +12 -13
  232. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +19 -14
  233. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  234. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +5 -3
  235. data/lib/graphql/static_validation/type_stack.rb +2 -2
  236. data/lib/graphql/static_validation/validation_context.rb +13 -3
  237. data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
  238. data/lib/graphql/static_validation/validator.rb +31 -19
  239. data/lib/graphql/static_validation.rb +1 -2
  240. data/lib/graphql/string_encoding_error.rb +13 -3
  241. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +123 -22
  242. data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
  243. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +58 -0
  244. data/lib/graphql/subscriptions/event.rb +85 -31
  245. data/lib/graphql/subscriptions/instrumentation.rb +0 -47
  246. data/lib/graphql/subscriptions/serialize.rb +53 -6
  247. data/lib/graphql/subscriptions.rb +111 -52
  248. data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -17
  249. data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
  250. data/lib/graphql/tracing/appsignal_tracing.rb +23 -0
  251. data/lib/graphql/tracing/data_dog_tracing.rb +14 -1
  252. data/lib/graphql/tracing/new_relic_tracing.rb +9 -12
  253. data/lib/graphql/tracing/notifications_tracing.rb +59 -0
  254. data/lib/graphql/tracing/platform_tracing.rb +57 -29
  255. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
  256. data/lib/graphql/tracing/prometheus_tracing.rb +8 -0
  257. data/lib/graphql/tracing/scout_tracing.rb +19 -0
  258. data/lib/graphql/tracing/statsd_tracing.rb +42 -0
  259. data/lib/graphql/tracing.rb +15 -36
  260. data/lib/graphql/types/big_int.rb +5 -1
  261. data/lib/graphql/types/int.rb +10 -3
  262. data/lib/graphql/types/iso_8601_date.rb +16 -8
  263. data/lib/graphql/types/iso_8601_date_time.rb +32 -10
  264. data/lib/graphql/types/relay/base_connection.rb +6 -88
  265. data/lib/graphql/types/relay/base_edge.rb +2 -34
  266. data/lib/graphql/types/relay/connection_behaviors.rb +170 -0
  267. data/lib/graphql/types/relay/default_relay.rb +21 -0
  268. data/lib/graphql/types/relay/edge_behaviors.rb +64 -0
  269. data/lib/graphql/types/relay/has_node_field.rb +41 -0
  270. data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
  271. data/lib/graphql/types/relay/node.rb +2 -4
  272. data/lib/graphql/types/relay/node_behaviors.rb +19 -0
  273. data/lib/graphql/types/relay/page_info.rb +2 -14
  274. data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
  275. data/lib/graphql/types/relay.rb +11 -5
  276. data/lib/graphql/types/string.rb +8 -2
  277. data/lib/graphql/unauthorized_error.rb +2 -2
  278. data/lib/graphql/unresolved_type_error.rb +2 -2
  279. data/lib/graphql/version.rb +1 -1
  280. data/lib/graphql.rb +41 -58
  281. data/readme.md +3 -6
  282. metadata +97 -231
  283. data/lib/graphql/analysis/analyze_query.rb +0 -91
  284. data/lib/graphql/analysis/field_usage.rb +0 -45
  285. data/lib/graphql/analysis/max_query_complexity.rb +0 -26
  286. data/lib/graphql/analysis/max_query_depth.rb +0 -26
  287. data/lib/graphql/analysis/query_complexity.rb +0 -88
  288. data/lib/graphql/analysis/query_depth.rb +0 -43
  289. data/lib/graphql/analysis/reducer_state.rb +0 -48
  290. data/lib/graphql/argument.rb +0 -159
  291. data/lib/graphql/authorization.rb +0 -82
  292. data/lib/graphql/backwards_compatibility.rb +0 -60
  293. data/lib/graphql/base_type.rb +0 -226
  294. data/lib/graphql/boolean_type.rb +0 -2
  295. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  296. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  297. data/lib/graphql/compatibility/execution_specification.rb +0 -435
  298. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  299. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -213
  300. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -91
  301. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  302. data/lib/graphql/compatibility/query_parser_specification.rb +0 -264
  303. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -680
  304. data/lib/graphql/compatibility.rb +0 -5
  305. data/lib/graphql/define/assign_argument.rb +0 -12
  306. data/lib/graphql/define/assign_connection.rb +0 -13
  307. data/lib/graphql/define/assign_enum_value.rb +0 -18
  308. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  309. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  310. data/lib/graphql/define/assign_object_field.rb +0 -42
  311. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  312. data/lib/graphql/define/instance_definable.rb +0 -311
  313. data/lib/graphql/define/no_definition_error.rb +0 -7
  314. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  315. data/lib/graphql/define/type_definer.rb +0 -31
  316. data/lib/graphql/define.rb +0 -31
  317. data/lib/graphql/deprecated_dsl.rb +0 -42
  318. data/lib/graphql/directive/deprecated_directive.rb +0 -13
  319. data/lib/graphql/directive/include_directive.rb +0 -2
  320. data/lib/graphql/directive/skip_directive.rb +0 -2
  321. data/lib/graphql/directive.rb +0 -104
  322. data/lib/graphql/enum_type.rb +0 -193
  323. data/lib/graphql/execution/execute.rb +0 -326
  324. data/lib/graphql/execution/flatten.rb +0 -40
  325. data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
  326. data/lib/graphql/execution/typecast.rb +0 -50
  327. data/lib/graphql/field/resolve.rb +0 -59
  328. data/lib/graphql/field.rb +0 -330
  329. data/lib/graphql/float_type.rb +0 -2
  330. data/lib/graphql/function.rb +0 -153
  331. data/lib/graphql/id_type.rb +0 -2
  332. data/lib/graphql/input_object_type.rb +0 -154
  333. data/lib/graphql/int_type.rb +0 -2
  334. data/lib/graphql/interface_type.rb +0 -86
  335. data/lib/graphql/internal_representation/document.rb +0 -27
  336. data/lib/graphql/internal_representation/node.rb +0 -206
  337. data/lib/graphql/internal_representation/print.rb +0 -51
  338. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  339. data/lib/graphql/internal_representation/scope.rb +0 -88
  340. data/lib/graphql/internal_representation/visit.rb +0 -36
  341. data/lib/graphql/internal_representation.rb +0 -7
  342. data/lib/graphql/list_type.rb +0 -80
  343. data/lib/graphql/literal_validation_error.rb +0 -6
  344. data/lib/graphql/non_null_type.rb +0 -81
  345. data/lib/graphql/object_type.rb +0 -141
  346. data/lib/graphql/query/arguments.rb +0 -187
  347. data/lib/graphql/query/arguments_cache.rb +0 -25
  348. data/lib/graphql/query/executor.rb +0 -53
  349. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  350. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  351. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  352. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  353. data/lib/graphql/query/serial_execution.rb +0 -39
  354. data/lib/graphql/relay/array_connection.rb +0 -85
  355. data/lib/graphql/relay/base_connection.rb +0 -172
  356. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  357. data/lib/graphql/relay/connection_resolve.rb +0 -43
  358. data/lib/graphql/relay/connection_type.rb +0 -40
  359. data/lib/graphql/relay/edge.rb +0 -27
  360. data/lib/graphql/relay/edge_type.rb +0 -18
  361. data/lib/graphql/relay/edges_instrumentation.rb +0 -40
  362. data/lib/graphql/relay/global_id_resolve.rb +0 -18
  363. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  364. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  365. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  366. data/lib/graphql/relay/mutation/result.rb +0 -38
  367. data/lib/graphql/relay/mutation.rb +0 -190
  368. data/lib/graphql/relay/node.rb +0 -36
  369. data/lib/graphql/relay/page_info.rb +0 -7
  370. data/lib/graphql/relay/relation_connection.rb +0 -190
  371. data/lib/graphql/relay/type_extensions.rb +0 -30
  372. data/lib/graphql/scalar_type.rb +0 -133
  373. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  374. data/lib/graphql/schema/default_parse_error.rb +0 -10
  375. data/lib/graphql/schema/default_type_error.rb +0 -15
  376. data/lib/graphql/schema/member/accepts_definition.rb +0 -152
  377. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -26
  378. data/lib/graphql/schema/member/instrumentation.rb +0 -132
  379. data/lib/graphql/schema/middleware_chain.rb +0 -82
  380. data/lib/graphql/schema/possible_types.rb +0 -39
  381. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  382. data/lib/graphql/schema/timeout_middleware.rb +0 -86
  383. data/lib/graphql/schema/traversal.rb +0 -228
  384. data/lib/graphql/schema/validation.rb +0 -303
  385. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  386. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  387. data/lib/graphql/string_type.rb +0 -2
  388. data/lib/graphql/subscriptions/subscription_root.rb +0 -74
  389. data/lib/graphql/tracing/skylight_tracing.rb +0 -62
  390. data/lib/graphql/types/relay/base_field.rb +0 -22
  391. data/lib/graphql/types/relay/base_interface.rb +0 -29
  392. data/lib/graphql/types/relay/base_object.rb +0 -26
  393. data/lib/graphql/types/relay/node_field.rb +0 -43
  394. data/lib/graphql/types/relay/nodes_field.rb +0 -45
  395. data/lib/graphql/union_type.rb +0 -135
  396. data/lib/graphql/upgrader/member.rb +0 -936
  397. data/lib/graphql/upgrader/schema.rb +0 -37
@@ -1,35 +1,16 @@
1
1
  # frozen_string_literal: true
2
+ require "fiber"
3
+ require "graphql/execution/interpreter/argument_value"
4
+ require "graphql/execution/interpreter/arguments"
5
+ require "graphql/execution/interpreter/arguments_cache"
2
6
  require "graphql/execution/interpreter/execution_errors"
3
- require "graphql/execution/interpreter/hash_response"
4
7
  require "graphql/execution/interpreter/runtime"
5
8
  require "graphql/execution/interpreter/resolve"
9
+ require "graphql/execution/interpreter/handles_raw_value"
6
10
 
7
11
  module GraphQL
8
12
  module Execution
9
13
  class Interpreter
10
- def initialize
11
- end
12
-
13
- # Support `Executor` :S
14
- def execute(_operation, _root_type, query)
15
- runtime = evaluate(query)
16
- sync_lazies(query: query)
17
- runtime.final_value
18
- end
19
-
20
- def self.use(schema_defn)
21
- schema_defn.target.interpreter = true
22
- # Reach through the legacy objects for the actual class defn
23
- schema_class = schema_defn.target.class
24
- # This is not good, since both of these are holding state now,
25
- # we have to update both :(
26
- [schema_class, schema_defn].each do |schema_config|
27
- schema_config.query_execution_strategy(GraphQL::Execution::Interpreter)
28
- schema_config.mutation_execution_strategy(GraphQL::Execution::Interpreter)
29
- schema_config.subscription_execution_strategy(GraphQL::Execution::Interpreter)
30
- end
31
- end
32
-
33
14
  def self.begin_multiplex(multiplex)
34
15
  # Since this is basically the batching context,
35
16
  # share it for a whole multiplex
@@ -53,7 +34,7 @@ module GraphQL
53
34
 
54
35
  def self.finish_query(query, _multiplex)
55
36
  {
56
- "data" => query.context.namespace(:interpreter)[:runtime].final_value
37
+ "data" => query.context.namespace(:interpreter)[:runtime].final_result
57
38
  }
58
39
  end
59
40
 
@@ -63,10 +44,7 @@ module GraphQL
63
44
  # Although queries in a multiplex _share_ an Interpreter instance,
64
45
  # they also have another item of state, which is private to that query
65
46
  # in particular, assign it here:
66
- runtime = Runtime.new(
67
- query: query,
68
- response: HashResponse.new,
69
- )
47
+ runtime = Runtime.new(query: query)
70
48
  query.context.namespace(:interpreter)[:runtime] = runtime
71
49
 
72
50
  query.trace("execute_query", {query: query}) do
@@ -87,11 +65,34 @@ module GraphQL
87
65
  final_values = queries.map do |query|
88
66
  runtime = query.context.namespace(:interpreter)[:runtime]
89
67
  # it might not be present if the query has an error
90
- runtime ? runtime.final_value : nil
68
+ runtime ? runtime.final_result : nil
91
69
  end
92
70
  final_values.compact!
93
71
  tracer.trace("execute_query_lazy", {multiplex: multiplex, query: query}) do
94
- Interpreter::Resolve.resolve_all(final_values)
72
+ Interpreter::Resolve.resolve_all(final_values, multiplex.dataloader)
73
+ end
74
+ queries.each do |query|
75
+ runtime = query.context.namespace(:interpreter)[:runtime]
76
+ if runtime
77
+ runtime.delete_interpreter_context(:current_path)
78
+ runtime.delete_interpreter_context(:current_field)
79
+ runtime.delete_interpreter_context(:current_object)
80
+ runtime.delete_interpreter_context(:current_arguments)
81
+ end
82
+ end
83
+ nil
84
+ end
85
+
86
+ class ListResultFailedError < GraphQL::Error
87
+ def initialize(value:, path:, field:)
88
+ message = "Failed to build a GraphQL list result for field `#{field.path}` at path `#{path.join(".")}`.\n".dup
89
+
90
+ message << "Expected `#{value.inspect}` (#{value.class}) to implement `.each` to satisfy the GraphQL return type `#{field.type.to_type_signature}`.\n"
91
+
92
+ if field.connection?
93
+ message << "\nThis field was treated as a Relay-style connection; add `connection: false` to the `field(...)` to disable this behavior."
94
+ end
95
+ super(message)
95
96
  end
96
97
  end
97
98
  end
@@ -36,6 +36,10 @@ module GraphQL
36
36
  @storage.compute_if_absent(value.class) { find_superclass_method(value.class) }
37
37
  end
38
38
 
39
+ def each
40
+ @storage.each_pair { |k, v| yield(k, v) }
41
+ end
42
+
39
43
  protected
40
44
 
41
45
  attr_reader :storage
@@ -48,7 +48,11 @@ module GraphQL
48
48
  end
49
49
  end
50
50
 
51
- if @value.is_a?(StandardError)
51
+ # `SKIP` was made into a subclass of `GraphQL::Error` to improve runtime performance
52
+ # (fewer clauses in a hot `case` block), but now it requires special handling here.
53
+ # I think it's still worth it for the performance win, but if the number of special
54
+ # cases grows, then maybe it's worth rethinking somehow.
55
+ if @value.is_a?(StandardError) && @value != GraphQL::Execution::SKIP
52
56
  raise @value
53
57
  else
54
58
  @value
@@ -51,7 +51,17 @@ module GraphQL
51
51
 
52
52
  # @return [Hash<Symbol, Object>]
53
53
  def arguments
54
- @arguments ||= @field && ArgumentHelpers.arguments(@query, nil, @field, ast_nodes.first)
54
+ if defined?(@arguments)
55
+ @arguments
56
+ else
57
+ @arguments = if @field
58
+ @query.schema.after_lazy(@query.arguments_for(@ast_nodes.first, @field)) do |args|
59
+ args.is_a?(Execution::Interpreter::Arguments) ? args.keyword_arguments : args
60
+ end
61
+ else
62
+ nil
63
+ end
64
+ end
55
65
  end
56
66
 
57
67
  # True if this node has a selection on `field_name`.
@@ -81,7 +91,7 @@ module GraphQL
81
91
  def selection(field_name, selected_type: @selected_type, arguments: nil)
82
92
  next_field_name = normalize_name(field_name)
83
93
 
84
- next_field_defn = FieldHelpers.get_field(@query.schema, selected_type, next_field_name)
94
+ next_field_defn = @query.get_field(selected_type, next_field_name)
85
95
  if next_field_defn
86
96
  next_nodes = []
87
97
  @ast_nodes.each do |ast_node|
@@ -127,7 +137,7 @@ module GraphQL
127
137
 
128
138
  subselections_by_type.each do |type, ast_nodes_by_response_key|
129
139
  ast_nodes_by_response_key.each do |response_key, ast_nodes|
130
- field_defn = FieldHelpers.get_field(@query.schema, type, ast_nodes.first.name)
140
+ field_defn = @query.get_field(type, ast_nodes.first.name)
131
141
  lookahead = Lookahead.new(query: @query, ast_nodes: ast_nodes, field: field_defn, owner_type: type)
132
142
  subselections.push(lookahead)
133
143
  end
@@ -203,8 +213,22 @@ module GraphQL
203
213
  end
204
214
  end
205
215
 
216
+ def skipped_by_directive?(ast_selection)
217
+ ast_selection.directives.each do |directive|
218
+ dir_defn = @query.schema.directives.fetch(directive.name)
219
+ directive_class = dir_defn
220
+ if directive_class
221
+ dir_args = @query.arguments_for(directive, dir_defn)
222
+ return true unless directive_class.static_include?(dir_args, @query.context)
223
+ end
224
+ end
225
+ false
226
+ end
227
+
206
228
  def find_selections(subselections_by_type, selections_on_type, selected_type, ast_selections, arguments)
207
229
  ast_selections.each do |ast_selection|
230
+ next if skipped_by_directive?(ast_selection)
231
+
208
232
  case ast_selection
209
233
  when GraphQL::Language::Nodes::Field
210
234
  response_key = ast_selection.alias || ast_selection.name
@@ -213,7 +237,7 @@ module GraphQL
213
237
  elsif arguments.nil? || arguments.empty?
214
238
  selections_on_type[response_key] = [ast_selection]
215
239
  else
216
- field_defn = FieldHelpers.get_field(@query.schema, selected_type, ast_selection.name)
240
+ field_defn = @query.get_field(selected_type, ast_selection.name)
217
241
  if arguments_match?(arguments, field_defn, ast_selection)
218
242
  selections_on_type[response_key] = [ast_selection]
219
243
  end
@@ -223,14 +247,14 @@ module GraphQL
223
247
  subselections_on_type = selections_on_type
224
248
  if (t = ast_selection.type)
225
249
  # Assuming this is valid, that `t` will be found.
226
- on_type = @query.schema.types[t.name].metadata[:type_class]
250
+ on_type = @query.get_type(t.name)
227
251
  subselections_on_type = subselections_by_type[on_type] ||= {}
228
252
  end
229
253
  find_selections(subselections_by_type, subselections_on_type, on_type, ast_selection.selections, arguments)
230
254
  when GraphQL::Language::Nodes::FragmentSpread
231
255
  frag_defn = @query.fragments[ast_selection.name] || raise("Invariant: Can't look ahead to nonexistent fragment #{ast_selection.name} (found: #{@query.fragments.keys})")
232
256
  # Again, assuming a valid AST
233
- on_type = @query.schema.types[frag_defn.type.name].metadata[:type_class]
257
+ on_type = @query.get_type(frag_defn.type.name)
234
258
  subselections_on_type = subselections_by_type[on_type] ||= {}
235
259
  find_selections(subselections_by_type, subselections_on_type, on_type, frag_defn.selections, arguments)
236
260
  else
@@ -242,6 +266,7 @@ module GraphQL
242
266
  # If a selection on `node` matches `field_name` (which is backed by `field_defn`)
243
267
  # and matches the `arguments:` constraints, then add that node to `matches`
244
268
  def find_selected_nodes(node, field_name, field_defn, arguments:, matches:)
269
+ return if skipped_by_directive?(node)
245
270
  case node
246
271
  when GraphQL::Language::Nodes::Field
247
272
  if node.name == field_name
@@ -263,120 +288,13 @@ module GraphQL
263
288
  end
264
289
 
265
290
  def arguments_match?(arguments, field_defn, field_node)
266
- query_kwargs = ArgumentHelpers.arguments(@query, nil, field_defn, field_node)
291
+ query_kwargs = @query.arguments_for(field_node, field_defn)
267
292
  arguments.all? do |arg_name, arg_value|
268
293
  arg_name = normalize_keyword(arg_name)
269
294
  # Make sure the constraint is present with a matching value
270
295
  query_kwargs.key?(arg_name) && query_kwargs[arg_name] == arg_value
271
296
  end
272
297
  end
273
-
274
- # TODO Dedup with interpreter
275
- module ArgumentHelpers
276
- module_function
277
-
278
- def arguments(query, graphql_object, arg_owner, ast_node)
279
- kwarg_arguments = {}
280
- arg_defns = arg_owner.arguments
281
- ast_node.arguments.each do |arg|
282
- arg_defn = arg_defns[arg.name] || raise("Invariant: missing argument definition for #{arg.name.inspect} in #{arg_defns.keys} from #{arg_owner}")
283
- # Need to distinguish between client-provided `nil`
284
- # and nothing-at-all
285
- is_present, value = arg_to_value(query, graphql_object, arg_defn.type, arg.value)
286
- if is_present
287
- # This doesn't apply to directives, which are legacy
288
- # Can remove this when Skip and Include use classes or something.
289
- if graphql_object
290
- value = arg_defn.prepare_value(graphql_object, value)
291
- end
292
- kwarg_arguments[arg_defn.keyword] = value
293
- end
294
- end
295
- arg_defns.each do |name, arg_defn|
296
- if arg_defn.default_value? && !kwarg_arguments.key?(arg_defn.keyword)
297
- kwarg_arguments[arg_defn.keyword] = arg_defn.default_value
298
- end
299
- end
300
- kwarg_arguments
301
- end
302
-
303
- # Get a Ruby-ready value from a client query.
304
- # @param graphql_object [Object] The owner of the field whose argument this is
305
- # @param arg_type [Class, GraphQL::Schema::NonNull, GraphQL::Schema::List]
306
- # @param ast_value [GraphQL::Language::Nodes::VariableIdentifier, String, Integer, Float, Boolean]
307
- # @return [Array(is_present, value)]
308
- def arg_to_value(query, graphql_object, arg_type, ast_value)
309
- if ast_value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
310
- # If it's not here, it will get added later
311
- if query.variables.key?(ast_value.name)
312
- return true, query.variables[ast_value.name]
313
- else
314
- return false, nil
315
- end
316
- elsif ast_value.is_a?(GraphQL::Language::Nodes::NullValue)
317
- return true, nil
318
- elsif arg_type.is_a?(GraphQL::Schema::NonNull)
319
- arg_to_value(query, graphql_object, arg_type.of_type, ast_value)
320
- elsif arg_type.is_a?(GraphQL::Schema::List)
321
- # Treat a single value like a list
322
- arg_value = Array(ast_value)
323
- list = []
324
- arg_value.map do |inner_v|
325
- _present, value = arg_to_value(query, graphql_object, arg_type.of_type, inner_v)
326
- list << value
327
- end
328
- return true, list
329
- elsif arg_type.is_a?(Class) && arg_type < GraphQL::Schema::InputObject
330
- # For these, `prepare` is applied during `#initialize`.
331
- # Pass `nil` so it will be skipped in `#arguments`.
332
- # What a mess.
333
- args = arguments(query, nil, arg_type, ast_value)
334
- # We're not tracking defaults_used, but for our purposes
335
- # we compare the value to the default value.
336
- return true, arg_type.new(ruby_kwargs: args, context: query.context, defaults_used: nil)
337
- else
338
- flat_value = flatten_ast_value(query, ast_value)
339
- return true, arg_type.coerce_input(flat_value, query.context)
340
- end
341
- end
342
-
343
- def flatten_ast_value(query, v)
344
- case v
345
- when GraphQL::Language::Nodes::Enum
346
- v.name
347
- when GraphQL::Language::Nodes::InputObject
348
- h = {}
349
- v.arguments.each do |arg|
350
- h[arg.name] = flatten_ast_value(query, arg.value)
351
- end
352
- h
353
- when Array
354
- v.map { |v2| flatten_ast_value(query, v2) }
355
- when GraphQL::Language::Nodes::VariableIdentifier
356
- flatten_ast_value(query.variables[v.name])
357
- else
358
- v
359
- end
360
- end
361
- end
362
-
363
- # TODO dedup with interpreter
364
- module FieldHelpers
365
- module_function
366
-
367
- def get_field(schema, owner_type, field_name)
368
- field_defn = owner_type.get_field(field_name)
369
- field_defn ||= if owner_type == schema.query.metadata[:type_class] && (entry_point_field = schema.introspection_system.entry_point(name: field_name))
370
- entry_point_field.metadata[:type_class]
371
- elsif (dynamic_field = schema.introspection_system.dynamic_field(name: field_name))
372
- dynamic_field.metadata[:type_class]
373
- else
374
- nil
375
- end
376
-
377
- field_defn
378
- end
379
- end
380
298
  end
381
299
  end
382
300
  end
@@ -29,13 +29,14 @@ module GraphQL
29
29
 
30
30
  include Tracing::Traceable
31
31
 
32
- attr_reader :context, :queries, :schema, :max_complexity
32
+ attr_reader :context, :queries, :schema, :max_complexity, :dataloader
33
33
  def initialize(schema:, queries:, context:, max_complexity:)
34
34
  @schema = schema
35
35
  @queries = queries
36
+ @queries.each { |q| q.multiplex = self }
36
37
  @context = context
37
- # TODO remove support for global tracers
38
- @tracers = schema.tracers + GraphQL::Tracing.tracers + (context[:tracers] || [])
38
+ @dataloader = @context[:dataloader] ||= @schema.dataloader_class.new
39
+ @tracers = schema.tracers + (context[:tracers] || [])
39
40
  # Support `context: {backtrace: true}`
40
41
  if context[:backtrace] && !@tracers.include?(GraphQL::Backtrace::Tracer)
41
42
  @tracers << GraphQL::Backtrace::Tracer
@@ -44,79 +45,88 @@ module GraphQL
44
45
  end
45
46
 
46
47
  class << self
47
- def run_all(schema, query_options, **kwargs)
48
- queries = query_options.map { |opts| GraphQL::Query.new(schema, nil, **opts) }
49
- run_queries(schema, queries, **kwargs)
50
- end
51
-
52
48
  # @param schema [GraphQL::Schema]
53
- # @param queries [Array<GraphQL::Query>]
49
+ # @param queries [Array<GraphQL::Query, Hash>]
54
50
  # @param context [Hash]
55
51
  # @param max_complexity [Integer, nil]
56
52
  # @return [Array<Hash>] One result per query
57
- def run_queries(schema, queries, context: {}, max_complexity: schema.max_complexity)
58
- multiplex = self.new(schema: schema, queries: queries, context: context, max_complexity: max_complexity)
59
- multiplex.trace("execute_multiplex", { multiplex: multiplex }) do
60
- if supports_multiplexing?(schema)
61
- instrument_and_analyze(multiplex) do
62
- run_as_multiplex(multiplex)
63
- end
53
+ def run_all(schema, query_options, context: {}, max_complexity: schema.max_complexity)
54
+ queries = query_options.map do |opts|
55
+ case opts
56
+ when Hash
57
+ GraphQL::Query.new(schema, nil, **opts)
58
+ when GraphQL::Query
59
+ opts
64
60
  else
65
- if queries.length != 1
66
- raise ArgumentError, "Multiplexing doesn't support custom execution strategies, run one query at a time instead"
67
- else
68
- instrument_and_analyze(multiplex) do
69
- [run_one_legacy(schema, queries.first)]
70
- end
71
- end
61
+ raise "Expected Hash or GraphQL::Query, not #{opts.class} (#{opts.inspect})"
72
62
  end
73
63
  end
74
- end
75
64
 
76
- private
65
+ multiplex = self.new(schema: schema, queries: queries, context: context, max_complexity: max_complexity)
66
+ multiplex.trace("execute_multiplex", { multiplex: multiplex }) do
67
+ GraphQL::Execution::Instrumentation.apply_instrumenters(multiplex) do
68
+ schema = multiplex.schema
69
+ multiplex_analyzers = schema.multiplex_analyzers
70
+ if multiplex.max_complexity
71
+ multiplex_analyzers += [GraphQL::Analysis::AST::MaxQueryComplexity]
72
+ end
77
73
 
78
- def run_as_multiplex(multiplex)
74
+ schema.analysis_engine.analyze_multiplex(multiplex, multiplex_analyzers)
79
75
 
80
- multiplex.schema.query_execution_strategy.begin_multiplex(multiplex)
81
- queries = multiplex.queries
82
- # Do as much eager evaluation of the query as possible
83
- results = queries.map do |query|
84
- begin_query(query, multiplex)
85
- end
76
+ begin
77
+ multiplex.schema.query_execution_strategy.begin_multiplex(multiplex)
78
+ # Do as much eager evaluation of the query as possible
79
+ results = []
80
+ queries.each_with_index do |query, idx|
81
+ multiplex.dataloader.append_job { begin_query(results, idx, query, multiplex) }
82
+ end
83
+
84
+ multiplex.dataloader.run
86
85
 
87
- # Then, work through lazy results in a breadth-first way
88
- multiplex.schema.query_execution_strategy.finish_multiplex(results, multiplex)
86
+ # Then, work through lazy results in a breadth-first way
87
+ multiplex.dataloader.append_job {
88
+ multiplex.schema.query_execution_strategy.finish_multiplex(results, multiplex)
89
+ }
90
+ multiplex.dataloader.run
91
+
92
+ # Then, find all errors and assign the result to the query object
93
+ results.each_with_index do |data_result, idx|
94
+ query = queries[idx]
95
+ finish_query(data_result, query, multiplex)
96
+ # Get the Query::Result, not the Hash
97
+ results[idx] = query.result
98
+ end
89
99
 
90
- # Then, find all errors and assign the result to the query object
91
- results.each_with_index.map do |data_result, idx|
92
- query = queries[idx]
93
- finish_query(data_result, query, multiplex)
94
- # Get the Query::Result, not the Hash
95
- query.result
100
+ results
101
+ rescue Exception
102
+ # TODO rescue at a higher level so it will catch errors in analysis, too
103
+ # Assign values here so that the query's `@executed` becomes true
104
+ queries.map { |q| q.result_values ||= {} }
105
+ raise
106
+ end
107
+ end
96
108
  end
97
- rescue Exception
98
- # Assign values here so that the query's `@executed` becomes true
99
- queries.map { |q| q.result_values ||= {} }
100
- raise
101
109
  end
102
110
 
103
111
  # @param query [GraphQL::Query]
104
- # @return [Hash] The initial result (may not be finished if there are lazy values)
105
- def begin_query(query, multiplex)
112
+ def begin_query(results, idx, query, multiplex)
106
113
  operation = query.selected_operation
107
- if operation.nil? || !query.valid? || query.context.errors.any?
114
+ result = if operation.nil? || !query.valid? || query.context.errors.any?
108
115
  NO_OPERATION
109
116
  else
110
117
  begin
111
- # These were checked to be the same in `#supports_multiplexing?`
112
118
  query.schema.query_execution_strategy.begin_query(query, multiplex)
113
119
  rescue GraphQL::ExecutionError => err
114
120
  query.context.errors << err
115
121
  NO_OPERATION
116
122
  end
117
123
  end
124
+ results[idx] = result
125
+ nil
118
126
  end
119
127
 
128
+ private
129
+
120
130
  # @param data_result [Hash] The result for the "data" key, if any
121
131
  # @param query [GraphQL::Query] The query which was run
122
132
  # @return [Hash] final result of this query, including all values and errors
@@ -140,50 +150,8 @@ module GraphQL
140
150
 
141
151
  result
142
152
  end
143
- end
144
-
145
- # use the old `query_execution_strategy` etc to run this query
146
- def run_one_legacy(schema, query)
147
- query.result_values = if !query.valid?
148
- all_errors = query.validation_errors + query.analysis_errors + query.context.errors
149
- if all_errors.any?
150
- { "errors" => all_errors.map(&:to_h) }
151
- else
152
- nil
153
- end
154
- else
155
- GraphQL::Query::Executor.new(query).result
156
- end
157
- end
158
-
159
- DEFAULT_STRATEGIES = [
160
- GraphQL::Execution::Execute,
161
- GraphQL::Execution::Interpreter
162
- ]
163
- # @return [Boolean] True if the schema is only using one strategy, and it's one that supports multiplexing.
164
- def supports_multiplexing?(schema)
165
- schema_strategies = [schema.query_execution_strategy, schema.mutation_execution_strategy, schema.subscription_execution_strategy]
166
- schema_strategies.uniq!
167
- schema_strategies.size == 1 && DEFAULT_STRATEGIES.include?(schema_strategies.first)
168
- end
169
-
170
- # Apply multiplex & query instrumentation to `queries`.
171
- #
172
- # It yields when the queries should be executed, then runs teardown.
173
- def instrument_and_analyze(multiplex)
174
- GraphQL::Execution::Instrumentation.apply_instrumenters(multiplex) do
175
- schema = multiplex.schema
176
- multiplex_analyzers = schema.multiplex_analyzers
177
- if multiplex.max_complexity
178
- multiplex_analyzers += if schema.using_ast_analysis?
179
- [GraphQL::Analysis::AST::MaxQueryComplexity]
180
- else
181
- [GraphQL::Analysis::MaxQueryComplexity.new(multiplex.max_complexity)]
182
- end
183
- end
184
-
185
- schema.analysis_engine.analyze_multiplex(multiplex, multiplex_analyzers)
186
- yield
153
+ if query.context.namespace?(:__query_result_extensions__)
154
+ query.result_values["extensions"] = query.context.namespace(:__query_result_extensions__)
187
155
  end
188
156
  end
189
157
  end
@@ -1,11 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
  require "graphql/execution/directive_checks"
3
- require "graphql/execution/execute"
4
- require "graphql/execution/flatten"
5
3
  require "graphql/execution/instrumentation"
6
4
  require "graphql/execution/interpreter"
7
5
  require "graphql/execution/lazy"
8
6
  require "graphql/execution/lookahead"
9
7
  require "graphql/execution/multiplex"
10
- require "graphql/execution/typecast"
11
8
  require "graphql/execution/errors"
9
+
10
+ module GraphQL
11
+ module Execution
12
+ # @api private
13
+ class Skip < GraphQL::Error; end
14
+
15
+ # Just a singleton for implementing {Query::Context#skip}
16
+ # @api private
17
+ SKIP = Skip.new
18
+ end
19
+ end
@@ -33,7 +33,7 @@ module GraphQL
33
33
  end
34
34
 
35
35
  def self.build(onlies)
36
- case onlies
36
+ case onlies.size
37
37
  when 0
38
38
  nil
39
39
  when 1
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ # This error is raised when `Types::Int` is given an input value outside of 32-bit integer range.
4
+ #
5
+ # For really big integer values, consider `GraphQL::Types::BigInt`
6
+ #
7
+ # @see GraphQL::Types::Int which raises this error
8
+ class IntegerDecodingError < GraphQL::RuntimeTypeError
9
+ # The value which couldn't be decoded
10
+ attr_reader :integer_value
11
+
12
+ def initialize(value)
13
+ @integer_value = value
14
+ super("Integer out of bounds: #{value}. \nConsider using GraphQL::Types::BigInt instead.")
15
+ end
16
+ end
17
+ end
@@ -12,9 +12,25 @@ module GraphQL
12
12
  # The value which couldn't be encoded
13
13
  attr_reader :integer_value
14
14
 
15
- def initialize(value)
15
+ # @return [GraphQL::Schema::Field] The field that returned a too-big integer
16
+ attr_reader :field
17
+
18
+ # @return [Array<String, Integer>] Where the field appeared in the GraphQL response
19
+ attr_reader :path
20
+
21
+ def initialize(value, context:)
16
22
  @integer_value = value
17
- super("Integer out of bounds: #{value}. \nConsider using ID or GraphQL::Types::BigInt instead.")
23
+ @field = context[:current_field]
24
+ @path = context[:current_path]
25
+ message = "Integer out of bounds: #{value}".dup
26
+ if @path
27
+ message << " @ #{@path.join(".")}"
28
+ end
29
+ if @field
30
+ message << " (#{@field.path})"
31
+ end
32
+ message << ". Consider using ID or GraphQL::Types::BigInt instead."
33
+ super(message)
18
34
  end
19
35
  end
20
36
  end
@@ -2,15 +2,12 @@
2
2
  module GraphQL
3
3
  module Introspection
4
4
  class BaseObject < GraphQL::Schema::Object
5
+ introspection(true)
6
+
5
7
  def self.field(*args, **kwargs, &block)
6
8
  kwargs[:introspection] = true
7
9
  super(*args, **kwargs, &block)
8
10
  end
9
-
10
- def self.inherited(child_class)
11
- child_class.introspection(true)
12
- super
13
- end
14
11
  end
15
12
  end
16
13
  end
@@ -6,8 +6,8 @@ module GraphQL
6
6
  description "A Directive can be adjacent to many parts of the GraphQL language, "\
7
7
  "a __DirectiveLocation describes one such possible adjacencies."
8
8
 
9
- GraphQL::Directive::LOCATIONS.each do |location|
10
- value(location.to_s, GraphQL::Directive::LOCATION_DESCRIPTIONS[location], value: location)
9
+ GraphQL::Schema::Directive::LOCATIONS.each do |location|
10
+ value(location.to_s, GraphQL::Schema::Directive::LOCATION_DESCRIPTIONS[location], value: location)
11
11
  end
12
12
  introspection true
13
13
  end