graphql 1.9.21 → 2.0.16

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 (403) 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 +45 -8
  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 +49 -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 +25 -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 +31 -2
  49. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
  50. data/lib/graphql/analysis/ast/query_complexity.rb +175 -68
  51. data/lib/graphql/analysis/ast/query_depth.rb +0 -1
  52. data/lib/graphql/analysis/ast/visitor.rb +17 -8
  53. data/lib/graphql/analysis/ast.rb +14 -14
  54. data/lib/graphql/analysis.rb +0 -7
  55. data/lib/graphql/backtrace/inspect_result.rb +0 -1
  56. data/lib/graphql/backtrace/table.rb +37 -16
  57. data/lib/graphql/backtrace/traced_error.rb +0 -1
  58. data/lib/graphql/backtrace/tracer.rb +39 -9
  59. data/lib/graphql/backtrace.rb +20 -17
  60. data/lib/graphql/dataloader/null_dataloader.rb +24 -0
  61. data/lib/graphql/dataloader/request.rb +19 -0
  62. data/lib/graphql/dataloader/request_all.rb +19 -0
  63. data/lib/graphql/dataloader/source.rb +164 -0
  64. data/lib/graphql/dataloader.rb +311 -0
  65. data/lib/graphql/date_encoding_error.rb +16 -0
  66. data/lib/graphql/deprecation.rb +9 -0
  67. data/lib/graphql/dig.rb +1 -1
  68. data/lib/graphql/execution/directive_checks.rb +2 -2
  69. data/lib/graphql/execution/errors.rb +77 -45
  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 +44 -25
  75. data/lib/graphql/execution/interpreter/runtime.rb +755 -395
  76. data/lib/graphql/execution/interpreter.rb +201 -74
  77. data/lib/graphql/execution/lazy/lazy_method_map.rb +4 -0
  78. data/lib/graphql/execution/lazy.rb +5 -9
  79. data/lib/graphql/execution/lookahead.rb +65 -136
  80. data/lib/graphql/execution/multiplex.rb +5 -152
  81. data/lib/graphql/execution.rb +11 -4
  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 +34 -17
  96. data/lib/graphql/introspection.rb +100 -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 +104 -68
  102. data/lib/graphql/language/lexer.rb +83 -40
  103. data/lib/graphql/language/lexer.rl +31 -9
  104. data/lib/graphql/language/nodes.rb +64 -93
  105. data/lib/graphql/language/parser.rb +940 -896
  106. data/lib/graphql/language/parser.y +130 -103
  107. data/lib/graphql/language/printer.rb +48 -23
  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 +79 -0
  115. data/lib/graphql/pagination/connection.rb +253 -0
  116. data/lib/graphql/pagination/connections.rb +135 -0
  117. data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
  118. data/lib/graphql/pagination/relation_connection.rb +228 -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 +172 -198
  123. data/lib/graphql/query/fingerprint.rb +26 -0
  124. data/lib/graphql/query/input_validation_result.rb +33 -7
  125. data/lib/graphql/query/null_context.rb +21 -8
  126. data/lib/graphql/query/validation_pipeline.rb +16 -38
  127. data/lib/graphql/query/variable_validation_error.rb +3 -3
  128. data/lib/graphql/query/variables.rb +39 -12
  129. data/lib/graphql/query.rb +74 -38
  130. data/lib/graphql/railtie.rb +6 -102
  131. data/lib/graphql/rake_task/validate.rb +4 -1
  132. data/lib/graphql/rake_task.rb +41 -10
  133. data/lib/graphql/relay/range_add.rb +17 -10
  134. data/lib/graphql/relay.rb +0 -15
  135. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  136. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  137. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  138. data/lib/graphql/rubocop.rb +4 -0
  139. data/lib/graphql/schema/addition.rb +245 -0
  140. data/lib/graphql/schema/argument.rb +286 -31
  141. data/lib/graphql/schema/base_64_encoder.rb +2 -0
  142. data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
  143. data/lib/graphql/schema/build_from_definition/resolve_map.rb +13 -5
  144. data/lib/graphql/schema/build_from_definition.rb +334 -220
  145. data/lib/graphql/schema/built_in_types.rb +5 -5
  146. data/lib/graphql/schema/directive/deprecated.rb +18 -0
  147. data/lib/graphql/schema/directive/feature.rb +1 -1
  148. data/lib/graphql/schema/directive/flagged.rb +57 -0
  149. data/lib/graphql/schema/directive/include.rb +2 -2
  150. data/lib/graphql/schema/directive/one_of.rb +12 -0
  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 +113 -22
  155. data/lib/graphql/schema/enum_value.rb +16 -21
  156. data/lib/graphql/schema/field/connection_extension.rb +50 -20
  157. data/lib/graphql/schema/field/scope_extension.rb +1 -1
  158. data/lib/graphql/schema/field.rb +491 -329
  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 +182 -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 +7 -2
  166. data/lib/graphql/schema/list.rb +61 -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 +24 -15
  170. data/lib/graphql/schema/member/has_arguments.rb +261 -24
  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 +113 -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/relay_shortcuts.rb +28 -2
  179. data/lib/graphql/schema/member/type_system_helpers.rb +3 -3
  180. data/lib/graphql/schema/member/validates_input.rb +33 -0
  181. data/lib/graphql/schema/member.rb +11 -6
  182. data/lib/graphql/schema/mutation.rb +4 -9
  183. data/lib/graphql/schema/non_null.rb +34 -4
  184. data/lib/graphql/schema/object.rb +38 -60
  185. data/lib/graphql/schema/printer.rb +16 -35
  186. data/lib/graphql/schema/relay_classic_mutation.rb +90 -43
  187. data/lib/graphql/schema/resolver/has_payload_type.rb +46 -6
  188. data/lib/graphql/schema/resolver.rb +146 -93
  189. data/lib/graphql/schema/scalar.rb +40 -15
  190. data/lib/graphql/schema/subscription.rb +55 -26
  191. data/lib/graphql/schema/timeout.rb +29 -15
  192. data/lib/graphql/schema/type_expression.rb +21 -13
  193. data/lib/graphql/schema/type_membership.rb +22 -5
  194. data/lib/graphql/schema/union.rb +48 -14
  195. data/lib/graphql/schema/unique_within_type.rb +1 -2
  196. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  197. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  198. data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
  199. data/lib/graphql/schema/validator/format_validator.rb +48 -0
  200. data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
  201. data/lib/graphql/schema/validator/length_validator.rb +59 -0
  202. data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
  203. data/lib/graphql/schema/validator/required_validator.rb +82 -0
  204. data/lib/graphql/schema/validator.rb +171 -0
  205. data/lib/graphql/schema/warden.rb +187 -33
  206. data/lib/graphql/schema/wrapper.rb +0 -5
  207. data/lib/graphql/schema.rb +773 -892
  208. data/lib/graphql/static_validation/all_rules.rb +3 -0
  209. data/lib/graphql/static_validation/base_visitor.rb +21 -31
  210. data/lib/graphql/static_validation/definition_dependencies.rb +7 -2
  211. data/lib/graphql/static_validation/error.rb +3 -1
  212. data/lib/graphql/static_validation/literal_validator.rb +55 -26
  213. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +45 -83
  214. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
  215. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +35 -26
  216. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
  217. data/lib/graphql/static_validation/rules/directives_are_defined.rb +12 -6
  218. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +14 -14
  219. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +4 -4
  220. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -5
  221. data/lib/graphql/static_validation/rules/fields_will_merge.rb +94 -51
  222. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
  223. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  224. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
  225. data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
  226. data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
  227. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  228. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  229. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  230. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  231. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -2
  232. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +9 -10
  233. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +13 -7
  234. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +12 -13
  235. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +19 -14
  236. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  237. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +5 -3
  238. data/lib/graphql/static_validation/type_stack.rb +2 -2
  239. data/lib/graphql/static_validation/validation_context.rb +13 -3
  240. data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
  241. data/lib/graphql/static_validation/validator.rb +31 -19
  242. data/lib/graphql/static_validation.rb +1 -2
  243. data/lib/graphql/string_encoding_error.rb +13 -3
  244. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +129 -22
  245. data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
  246. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +58 -0
  247. data/lib/graphql/subscriptions/event.rb +85 -31
  248. data/lib/graphql/subscriptions/instrumentation.rb +0 -47
  249. data/lib/graphql/subscriptions/serialize.rb +53 -6
  250. data/lib/graphql/subscriptions.rb +137 -57
  251. data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -17
  252. data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
  253. data/lib/graphql/tracing/appsignal_tracing.rb +23 -0
  254. data/lib/graphql/tracing/data_dog_tracing.rb +34 -2
  255. data/lib/graphql/tracing/new_relic_tracing.rb +9 -12
  256. data/lib/graphql/tracing/notifications_tracing.rb +59 -0
  257. data/lib/graphql/tracing/platform_tracing.rb +67 -38
  258. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
  259. data/lib/graphql/tracing/prometheus_tracing.rb +8 -0
  260. data/lib/graphql/tracing/scout_tracing.rb +19 -0
  261. data/lib/graphql/tracing/statsd_tracing.rb +42 -0
  262. data/lib/graphql/tracing.rb +15 -36
  263. data/lib/graphql/types/big_int.rb +5 -1
  264. data/lib/graphql/types/int.rb +10 -3
  265. data/lib/graphql/types/iso_8601_date.rb +20 -9
  266. data/lib/graphql/types/iso_8601_date_time.rb +36 -10
  267. data/lib/graphql/types/relay/base_connection.rb +18 -90
  268. data/lib/graphql/types/relay/base_edge.rb +2 -34
  269. data/lib/graphql/types/relay/connection_behaviors.rb +158 -0
  270. data/lib/graphql/types/relay/default_relay.rb +27 -0
  271. data/lib/graphql/types/relay/edge_behaviors.rb +65 -0
  272. data/lib/graphql/types/relay/has_node_field.rb +41 -0
  273. data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
  274. data/lib/graphql/types/relay/node.rb +2 -4
  275. data/lib/graphql/types/relay/node_behaviors.rb +19 -0
  276. data/lib/graphql/types/relay/page_info.rb +2 -14
  277. data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
  278. data/lib/graphql/types/relay.rb +11 -5
  279. data/lib/graphql/types/string.rb +8 -2
  280. data/lib/graphql/unauthorized_error.rb +2 -2
  281. data/lib/graphql/unresolved_type_error.rb +2 -2
  282. data/lib/graphql/version.rb +1 -1
  283. data/lib/graphql.rb +41 -58
  284. data/readme.md +3 -6
  285. metadata +103 -237
  286. data/lib/graphql/analysis/analyze_query.rb +0 -91
  287. data/lib/graphql/analysis/field_usage.rb +0 -45
  288. data/lib/graphql/analysis/max_query_complexity.rb +0 -26
  289. data/lib/graphql/analysis/max_query_depth.rb +0 -26
  290. data/lib/graphql/analysis/query_complexity.rb +0 -88
  291. data/lib/graphql/analysis/query_depth.rb +0 -43
  292. data/lib/graphql/analysis/reducer_state.rb +0 -48
  293. data/lib/graphql/argument.rb +0 -159
  294. data/lib/graphql/authorization.rb +0 -82
  295. data/lib/graphql/backwards_compatibility.rb +0 -60
  296. data/lib/graphql/base_type.rb +0 -226
  297. data/lib/graphql/boolean_type.rb +0 -2
  298. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  299. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  300. data/lib/graphql/compatibility/execution_specification.rb +0 -435
  301. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  302. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -213
  303. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -91
  304. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  305. data/lib/graphql/compatibility/query_parser_specification.rb +0 -264
  306. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -680
  307. data/lib/graphql/compatibility.rb +0 -5
  308. data/lib/graphql/define/assign_argument.rb +0 -12
  309. data/lib/graphql/define/assign_connection.rb +0 -13
  310. data/lib/graphql/define/assign_enum_value.rb +0 -18
  311. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  312. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  313. data/lib/graphql/define/assign_object_field.rb +0 -42
  314. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  315. data/lib/graphql/define/instance_definable.rb +0 -311
  316. data/lib/graphql/define/no_definition_error.rb +0 -7
  317. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  318. data/lib/graphql/define/type_definer.rb +0 -31
  319. data/lib/graphql/define.rb +0 -31
  320. data/lib/graphql/deprecated_dsl.rb +0 -42
  321. data/lib/graphql/directive/deprecated_directive.rb +0 -13
  322. data/lib/graphql/directive/include_directive.rb +0 -2
  323. data/lib/graphql/directive/skip_directive.rb +0 -2
  324. data/lib/graphql/directive.rb +0 -104
  325. data/lib/graphql/enum_type.rb +0 -193
  326. data/lib/graphql/execution/execute.rb +0 -326
  327. data/lib/graphql/execution/flatten.rb +0 -40
  328. data/lib/graphql/execution/instrumentation.rb +0 -92
  329. data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
  330. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  331. data/lib/graphql/execution/typecast.rb +0 -50
  332. data/lib/graphql/field/resolve.rb +0 -59
  333. data/lib/graphql/field.rb +0 -330
  334. data/lib/graphql/float_type.rb +0 -2
  335. data/lib/graphql/function.rb +0 -153
  336. data/lib/graphql/id_type.rb +0 -2
  337. data/lib/graphql/input_object_type.rb +0 -154
  338. data/lib/graphql/int_type.rb +0 -2
  339. data/lib/graphql/interface_type.rb +0 -86
  340. data/lib/graphql/internal_representation/document.rb +0 -27
  341. data/lib/graphql/internal_representation/node.rb +0 -206
  342. data/lib/graphql/internal_representation/print.rb +0 -51
  343. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  344. data/lib/graphql/internal_representation/scope.rb +0 -88
  345. data/lib/graphql/internal_representation/visit.rb +0 -36
  346. data/lib/graphql/internal_representation.rb +0 -7
  347. data/lib/graphql/list_type.rb +0 -80
  348. data/lib/graphql/literal_validation_error.rb +0 -6
  349. data/lib/graphql/non_null_type.rb +0 -81
  350. data/lib/graphql/object_type.rb +0 -141
  351. data/lib/graphql/query/arguments.rb +0 -187
  352. data/lib/graphql/query/arguments_cache.rb +0 -25
  353. data/lib/graphql/query/executor.rb +0 -53
  354. data/lib/graphql/query/literal_input.rb +0 -116
  355. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  356. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  357. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  358. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  359. data/lib/graphql/query/serial_execution.rb +0 -39
  360. data/lib/graphql/relay/array_connection.rb +0 -85
  361. data/lib/graphql/relay/base_connection.rb +0 -172
  362. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  363. data/lib/graphql/relay/connection_resolve.rb +0 -43
  364. data/lib/graphql/relay/connection_type.rb +0 -40
  365. data/lib/graphql/relay/edge.rb +0 -27
  366. data/lib/graphql/relay/edge_type.rb +0 -18
  367. data/lib/graphql/relay/edges_instrumentation.rb +0 -40
  368. data/lib/graphql/relay/global_id_resolve.rb +0 -18
  369. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  370. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  371. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  372. data/lib/graphql/relay/mutation/result.rb +0 -38
  373. data/lib/graphql/relay/mutation.rb +0 -190
  374. data/lib/graphql/relay/node.rb +0 -36
  375. data/lib/graphql/relay/page_info.rb +0 -7
  376. data/lib/graphql/relay/relation_connection.rb +0 -190
  377. data/lib/graphql/relay/type_extensions.rb +0 -30
  378. data/lib/graphql/scalar_type.rb +0 -133
  379. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  380. data/lib/graphql/schema/default_parse_error.rb +0 -10
  381. data/lib/graphql/schema/default_type_error.rb +0 -15
  382. data/lib/graphql/schema/member/accepts_definition.rb +0 -152
  383. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -26
  384. data/lib/graphql/schema/member/instrumentation.rb +0 -132
  385. data/lib/graphql/schema/middleware_chain.rb +0 -82
  386. data/lib/graphql/schema/possible_types.rb +0 -39
  387. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  388. data/lib/graphql/schema/timeout_middleware.rb +0 -86
  389. data/lib/graphql/schema/traversal.rb +0 -228
  390. data/lib/graphql/schema/validation.rb +0 -303
  391. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  392. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  393. data/lib/graphql/string_type.rb +0 -2
  394. data/lib/graphql/subscriptions/subscription_root.rb +0 -74
  395. data/lib/graphql/tracing/skylight_tracing.rb +0 -62
  396. data/lib/graphql/types/relay/base_field.rb +0 -22
  397. data/lib/graphql/types/relay/base_interface.rb +0 -29
  398. data/lib/graphql/types/relay/base_object.rb +0 -26
  399. data/lib/graphql/types/relay/node_field.rb +0 -43
  400. data/lib/graphql/types/relay/nodes_field.rb +0 -45
  401. data/lib/graphql/union_type.rb +0 -135
  402. data/lib/graphql/upgrader/member.rb +0 -936
  403. data/lib/graphql/upgrader/schema.rb +0 -37
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ class Subscriptions
5
+ # Detect whether the current operation:
6
+ # - Is a subscription operation
7
+ # - Is completely broadcastable
8
+ #
9
+ # Assign the result to `context.namespace(:subscriptions)[:subscription_broadcastable]`
10
+ # @api private
11
+ # @see Subscriptions#broadcastable? for a public API
12
+ class BroadcastAnalyzer < GraphQL::Analysis::AST::Analyzer
13
+ def initialize(subject)
14
+ super
15
+ @default_broadcastable = subject.schema.subscriptions.default_broadcastable
16
+ # Maybe this will get set to false while analyzing
17
+ @subscription_broadcastable = true
18
+ end
19
+
20
+ # Only analyze subscription operations
21
+ def analyze?
22
+ @query.subscription?
23
+ end
24
+
25
+ def on_enter_field(node, parent, visitor)
26
+ if (@subscription_broadcastable == false) || visitor.skipping?
27
+ return
28
+ end
29
+
30
+ current_field = visitor.field_definition
31
+ apply_broadcastable(current_field)
32
+
33
+ current_type = visitor.parent_type_definition
34
+ if current_type.kind.interface?
35
+ pt = @query.possible_types(current_type)
36
+ pt.each do |object_type|
37
+ ot_field = @query.get_field(object_type, current_field.graphql_name)
38
+ # Inherited fields would be exactly the same object;
39
+ # only check fields that are overrides of the inherited one
40
+ if ot_field && ot_field != current_field
41
+ apply_broadcastable(ot_field)
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ # Assign the result to context.
48
+ # (This method is allowed to return an error, but we don't need to)
49
+ # @return [void]
50
+ def result
51
+ query.context.namespace(:subscriptions)[:subscription_broadcastable] = @subscription_broadcastable
52
+ nil
53
+ end
54
+
55
+ private
56
+
57
+ # Modify `@subscription_broadcastable` based on `field_defn`'s configuration (and/or the default value)
58
+ def apply_broadcastable(field_defn)
59
+ current_field_broadcastable = field_defn.introspection? || field_defn.broadcastable?
60
+ case current_field_broadcastable
61
+ when nil
62
+ # If the value wasn't set, mix in the default value:
63
+ # - If the default is false and the current value is true, make it false
64
+ # - If the default is true and the current value is true, it stays true
65
+ # - If the default is false and the current value is false, keep it false
66
+ # - If the default is true and the current value is false, keep it false
67
+ @subscription_broadcastable = @subscription_broadcastable && @default_broadcastable
68
+ when false
69
+ # One non-broadcastable field is enough to make the whole subscription non-broadcastable
70
+ @subscription_broadcastable = false
71
+ when true
72
+ # Leave `@broadcastable_query` true if it's already true,
73
+ # but don't _set_ it to true if it was set to false by something else.
74
+ # Actually, just leave it!
75
+ else
76
+ raise ArgumentError, "Unexpected `.broadcastable?` value for #{field_defn.path}: #{current_field_broadcastable}"
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ class Subscriptions
4
+ class DefaultSubscriptionResolveExtension < GraphQL::Schema::FieldExtension
5
+ def resolve(context:, object:, arguments:)
6
+ has_override_implementation = @field.resolver ||
7
+ object.respond_to?(@field.resolver_method)
8
+
9
+ if !has_override_implementation
10
+ if context.query.subscription_update?
11
+ object.object
12
+ else
13
+ context.skip
14
+ end
15
+ else
16
+ yield(object, arguments)
17
+ end
18
+ end
19
+
20
+ def after_resolve(value:, context:, object:, arguments:, **rest)
21
+ if value.is_a?(GraphQL::ExecutionError)
22
+ value
23
+ elsif (events = context.namespace(:subscriptions)[:events])
24
+ # This is the first execution, so gather an Event
25
+ # for the backend to register:
26
+ event = Subscriptions::Event.new(
27
+ name: field.name,
28
+ arguments: arguments_without_field_extras(arguments: arguments),
29
+ context: context,
30
+ field: field,
31
+ )
32
+ events << event
33
+ value
34
+ elsif context.query.subscription_topic == Subscriptions::Event.serialize(
35
+ field.name,
36
+ arguments_without_field_extras(arguments: arguments),
37
+ field,
38
+ scope: (field.subscription_scope ? context[field.subscription_scope] : nil),
39
+ )
40
+ # This is a subscription update. The resolver returned `skip` if it should be skipped,
41
+ # or else it returned an object to resolve the update.
42
+ value
43
+ else
44
+ # This is a subscription update, but this event wasn't triggered.
45
+ context.skip
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def arguments_without_field_extras(arguments:)
52
+ arguments.dup.tap do |event_args|
53
+ field.extras.each { |k| event_args.delete(k) }
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -1,17 +1,15 @@
1
1
  # frozen_string_literal: true
2
- # test_via: ../subscriptions.rb
3
2
  module GraphQL
4
3
  class Subscriptions
5
4
  # This thing can be:
6
5
  # - Subscribed to by `subscription { ... }`
7
6
  # - Triggered by `MySchema.subscriber.trigger(name, arguments, obj)`
8
7
  #
9
- # An array of `Event`s are passed to `store.register(query, events)`.
10
8
  class Event
11
9
  # @return [String] Corresponds to the Subscription root field name
12
10
  attr_reader :name
13
11
 
14
- # @return [GraphQL::Query::Arguments]
12
+ # @return [GraphQL::Execution::Interpreter::Arguments]
15
13
  attr_reader :arguments
16
14
 
17
15
  # @return [GraphQL::Query::Context]
@@ -25,64 +23,120 @@ module GraphQL
25
23
  @arguments = arguments
26
24
  @context = context
27
25
  field ||= context.field
28
- scope_val = scope || (context && field.subscription_scope && context[field.subscription_scope])
26
+ scope_key = field.subscription_scope
27
+ scope_val = scope || (context && scope_key && context[scope_key])
28
+ if scope_key &&
29
+ (subscription = field.resolver) &&
30
+ (subscription.respond_to?(:subscription_scope_optional?)) &&
31
+ !subscription.subscription_scope_optional? &&
32
+ scope_val.nil?
33
+ raise Subscriptions::SubscriptionScopeMissingError, "#{field.path} (#{subscription}) requires a `scope:` value to trigger updates (Set `subscription_scope ..., optional: true` to disable this requirement)"
34
+ end
29
35
 
30
- @topic = self.class.serialize(name, arguments, field, scope: scope_val)
36
+ @topic = self.class.serialize(name, arguments, field, scope: scope_val, context: context)
31
37
  end
32
38
 
33
39
  # @return [String] an identifier for this unit of subscription
34
- def self.serialize(name, arguments, field, scope:)
35
- normalized_args = case arguments
36
- when GraphQL::Query::Arguments
37
- arguments
38
- when Hash
39
- if field.is_a?(GraphQL::Schema::Field)
40
- stringify_args(field, arguments)
40
+ def self.serialize(_name, arguments, field, scope:, context: GraphQL::Query::NullContext)
41
+ subscription = field.resolver || GraphQL::Schema::Subscription
42
+ normalized_args = stringify_args(field, arguments.to_h, context)
43
+ subscription.topic_for(arguments: normalized_args, field: field, scope: scope)
44
+ end
45
+
46
+ # @return [String] a logical identifier for this event. (Stable when the query is broadcastable.)
47
+ def fingerprint
48
+ @fingerprint ||= begin
49
+ # When this query has been flagged as broadcastable,
50
+ # use a generalized, stable fingerprint so that
51
+ # duplicate subscriptions can be evaluated and distributed in bulk.
52
+ # (`@topic` includes field, args, and subscription scope already.)
53
+ if @context.namespace(:subscriptions)[:subscription_broadcastable]
54
+ "#{@topic}/#{@context.query.fingerprint}"
41
55
  else
42
- GraphQL::Query::LiteralInput.from_arguments(
43
- arguments,
44
- field,
45
- nil,
46
- )
56
+ # not broadcastable, build a unique ID for this event
57
+ @context.schema.subscriptions.build_id
47
58
  end
48
- else
49
- raise ArgumentError, "Unexpected arguments: #{arguments}, must be Hash or GraphQL::Arguments"
50
59
  end
51
-
52
- sorted_h = normalized_args.to_h.sort.to_h
53
- Serialize.dump_recursive([scope, name, sorted_h])
54
60
  end
55
61
 
56
62
  class << self
57
63
  private
58
- def stringify_args(arg_owner, args)
64
+
65
+ # This method does not support cyclic references in the Hash,
66
+ # nor does it support Hashes whose keys are not sortable
67
+ # with respect to their peers ( cases where a <=> b might throw an error )
68
+ def deep_sort_hash_keys(hash_to_sort)
69
+ raise ArgumentError.new("Argument must be a Hash") unless hash_to_sort.is_a?(Hash)
70
+ hash_to_sort.keys.sort.map do |k|
71
+ if hash_to_sort[k].is_a?(Hash)
72
+ [k, deep_sort_hash_keys(hash_to_sort[k])]
73
+ elsif hash_to_sort[k].is_a?(Array)
74
+ [k, deep_sort_array_hashes(hash_to_sort[k])]
75
+ else
76
+ [k, hash_to_sort[k]]
77
+ end
78
+ end.to_h
79
+ end
80
+
81
+ def deep_sort_array_hashes(array_to_inspect)
82
+ raise ArgumentError.new("Argument must be an Array") unless array_to_inspect.is_a?(Array)
83
+ array_to_inspect.map do |v|
84
+ if v.is_a?(Hash)
85
+ deep_sort_hash_keys(v)
86
+ elsif v.is_a?(Array)
87
+ deep_sort_array_hashes(v)
88
+ else
89
+ v
90
+ end
91
+ end
92
+ end
93
+
94
+ def stringify_args(arg_owner, args, context)
95
+ arg_owner = arg_owner.respond_to?(:unwrap) ? arg_owner.unwrap : arg_owner # remove list and non-null wrappers
59
96
  case args
60
97
  when Hash
61
98
  next_args = {}
62
99
  args.each do |k, v|
63
100
  arg_name = k.to_s
64
101
  camelized_arg_name = GraphQL::Schema::Member::BuildType.camelize(arg_name)
65
- arg_defn = get_arg_definition(arg_owner, camelized_arg_name)
102
+ arg_defn = get_arg_definition(arg_owner, camelized_arg_name, context)
66
103
 
67
104
  if arg_defn
68
105
  normalized_arg_name = camelized_arg_name
69
106
  else
70
107
  normalized_arg_name = arg_name
71
- arg_defn = get_arg_definition(arg_owner, normalized_arg_name)
108
+ arg_defn = get_arg_definition(arg_owner, normalized_arg_name, context)
109
+ end
110
+ arg_base_type = arg_defn.type.unwrap
111
+ # In the case where the value being emitted is seen as a "JSON"
112
+ # type, treat the value as one atomic unit of serialization
113
+ is_json_definition = arg_base_type && arg_base_type <= GraphQL::Types::JSON
114
+ if is_json_definition
115
+ sorted_value = if v.is_a?(Hash)
116
+ deep_sort_hash_keys(v)
117
+ elsif v.is_a?(Array)
118
+ deep_sort_array_hashes(v)
119
+ else
120
+ v
121
+ end
122
+ next_args[normalized_arg_name] = sorted_value.respond_to?(:to_json) ? sorted_value.to_json : sorted_value
123
+ else
124
+ next_args[normalized_arg_name] = stringify_args(arg_base_type, v, context)
72
125
  end
73
-
74
- next_args[normalized_arg_name] = stringify_args(arg_defn[1].type, v)
75
126
  end
76
- next_args
127
+ # Make sure they're deeply sorted
128
+ next_args.sort.to_h
77
129
  when Array
78
- args.map { |a| stringify_args(arg_owner, a) }
130
+ args.map { |a| stringify_args(arg_owner, a, context) }
131
+ when GraphQL::Schema::InputObject
132
+ stringify_args(arg_owner, args.to_h, context)
79
133
  else
80
134
  args
81
135
  end
82
136
  end
83
137
 
84
- def get_arg_definition(arg_owner, arg_name)
85
- arg_owner.arguments.find { |k, v| k == arg_name || v.keyword.to_s == arg_name }
138
+ def get_arg_definition(arg_owner, arg_name, context)
139
+ arg_owner.get_argument(arg_name, context) || arg_owner.arguments(context).each_value.find { |v| v.keyword.to_s == arg_name }
86
140
  end
87
141
  end
88
142
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # test_via: ../subscriptions.rb
3
2
  module GraphQL
4
3
  class Subscriptions
5
4
  # Wrap the root fields of the subscription type with special logic for:
@@ -10,16 +9,6 @@ module GraphQL
10
9
  @schema = schema
11
10
  end
12
11
 
13
- def instrument(type, field)
14
- if type == @schema.subscription
15
- # This is a root field of `subscription`
16
- subscribing_resolve_proc = SubscriptionRegistrationResolve.new(field.resolve_proc)
17
- field.redefine(resolve: subscribing_resolve_proc)
18
- else
19
- field
20
- end
21
- end
22
-
23
12
  # If needed, prepare to gather events which this query subscribes to
24
13
  def before_query(query)
25
14
  if query.subscription? && !query.subscription_update?
@@ -34,42 +23,6 @@ module GraphQL
34
23
  @schema.subscriptions.write_subscription(query, events)
35
24
  end
36
25
  end
37
-
38
- private
39
-
40
- class SubscriptionRegistrationResolve
41
- def initialize(inner_proc)
42
- @inner_proc = inner_proc
43
- end
44
-
45
- # Wrap the proc with subscription registration logic
46
- def call(obj, args, ctx)
47
- @inner_proc.call(obj, args, ctx) if @inner_proc && !@inner_proc.is_a?(GraphQL::Field::Resolve::BuiltInResolve)
48
-
49
- events = ctx.namespace(:subscriptions)[:events]
50
-
51
- if events
52
- # This is the first execution, so gather an Event
53
- # for the backend to register:
54
- events << Subscriptions::Event.new(
55
- name: ctx.field.name,
56
- arguments: args,
57
- context: ctx,
58
- )
59
- ctx.skip
60
- elsif ctx.irep_node.subscription_topic == ctx.query.subscription_topic
61
- # The root object is _already_ the subscription update:
62
- if obj.is_a?(GraphQL::Schema::Object)
63
- obj.object
64
- else
65
- obj
66
- end
67
- else
68
- # This is a subscription update, but this event wasn't triggered.
69
- ctx.skip
70
- end
71
- end
72
- end
73
26
  end
74
27
  end
75
28
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # test_via: ../subscriptions.rb
3
2
  require "set"
4
3
  module GraphQL
5
4
  class Subscriptions
@@ -9,6 +8,9 @@ module GraphQL
9
8
  GLOBALID_KEY = "__gid__"
10
9
  SYMBOL_KEY = "__sym__"
11
10
  SYMBOL_KEYS_KEY = "__sym_keys__"
11
+ TIMESTAMP_KEY = "__timestamp__"
12
+ TIMESTAMP_FORMAT = "%Y-%m-%d %H:%M:%S.%N%z" # eg '2020-01-01 23:59:59.123456789+05:00'
13
+ OPEN_STRUCT_KEY = "__ostruct__"
12
14
 
13
15
  module_function
14
16
 
@@ -53,12 +55,40 @@ module GraphQL
53
55
  # @return [Object] An object that load Global::Identification recursive
54
56
  def load_value(value)
55
57
  if value.is_a?(Array)
56
- value.map{|item| load_value(item)}
58
+ is_gids = (v1 = value[0]).is_a?(Hash) && v1.size == 1 && v1[GLOBALID_KEY]
59
+ if is_gids
60
+ # Assume it's an array of global IDs
61
+ ids = value.map { |v| v[GLOBALID_KEY] }
62
+ GlobalID::Locator.locate_many(ids)
63
+ else
64
+ value.map { |item| load_value(item) }
65
+ end
57
66
  elsif value.is_a?(Hash)
58
- if value.size == 1 && value.key?(GLOBALID_KEY)
59
- GlobalID::Locator.locate(value[GLOBALID_KEY])
60
- elsif value.size == 1 && value.key?(SYMBOL_KEY)
61
- value[SYMBOL_KEY].to_sym
67
+ if value.size == 1
68
+ case value.keys.first # there's only 1 key
69
+ when GLOBALID_KEY
70
+ GlobalID::Locator.locate(value[GLOBALID_KEY])
71
+ when SYMBOL_KEY
72
+ value[SYMBOL_KEY].to_sym
73
+ when TIMESTAMP_KEY
74
+ timestamp_class_name, *timestamp_args = value[TIMESTAMP_KEY]
75
+ timestamp_class = Object.const_get(timestamp_class_name)
76
+ if defined?(ActiveSupport::TimeWithZone) && timestamp_class <= ActiveSupport::TimeWithZone
77
+ zone_name, timestamp_s = timestamp_args
78
+ zone = ActiveSupport::TimeZone[zone_name]
79
+ raise "Zone #{zone_name} not found, unable to deserialize" unless zone
80
+ zone.strptime(timestamp_s, TIMESTAMP_FORMAT)
81
+ else
82
+ timestamp_s = timestamp_args.first
83
+ timestamp_class.strptime(timestamp_s, TIMESTAMP_FORMAT)
84
+ end
85
+ when OPEN_STRUCT_KEY
86
+ ostruct_values = load_value(value[OPEN_STRUCT_KEY])
87
+ OpenStruct.new(ostruct_values)
88
+ else
89
+ key = value.keys.first
90
+ { key => load_value(value[key]) }
91
+ end
62
92
  else
63
93
  loaded_h = {}
64
94
  sym_keys = value.fetch(SYMBOL_KEYS_KEY, [])
@@ -101,6 +131,23 @@ module GraphQL
101
131
  { SYMBOL_KEY => obj.to_s }
102
132
  elsif obj.respond_to?(:to_gid_param)
103
133
  {GLOBALID_KEY => obj.to_gid_param}
134
+ elsif defined?(ActiveSupport::TimeWithZone) && obj.is_a?(ActiveSupport::TimeWithZone) && obj.class.name != Time.name
135
+ # This handles a case where Rails prior to 7 would
136
+ # make the class ActiveSupport::TimeWithZone return "Time" for
137
+ # its name. In Rails 7, it will now return "ActiveSupport::TimeWithZone",
138
+ # which happens to be incompatible with expectations we have
139
+ # with what a Time class supports ( notably, strptime in `load_value` ).
140
+ #
141
+ # This now passes along the name of the zone, such that a future deserialization
142
+ # of this string will use the correct time zone from the ActiveSupport TimeZone
143
+ # list to produce the time.
144
+ #
145
+ { TIMESTAMP_KEY => [obj.class.name, obj.time_zone.name, obj.strftime(TIMESTAMP_FORMAT)] }
146
+ elsif obj.is_a?(Date) || obj.is_a?(Time)
147
+ # DateTime extends Date; for TimeWithZone, call `.utc` first.
148
+ { TIMESTAMP_KEY => [obj.class.name, obj.strftime(TIMESTAMP_FORMAT)] }
149
+ elsif obj.is_a?(OpenStruct)
150
+ { OPEN_STRUCT_KEY => dump_value(obj.to_h) }
104
151
  else
105
152
  obj
106
153
  end