graphql 1.13.24 → 2.5.11

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 (427) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/install/mutation_root_generator.rb +2 -2
  3. data/lib/generators/graphql/install/templates/base_mutation.erb +2 -0
  4. data/lib/generators/graphql/install/templates/mutation_type.erb +2 -0
  5. data/lib/generators/graphql/install_generator.rb +50 -1
  6. data/lib/generators/graphql/mutation_delete_generator.rb +1 -1
  7. data/lib/generators/graphql/mutation_update_generator.rb +1 -1
  8. data/lib/generators/graphql/orm_mutations_base.rb +1 -1
  9. data/lib/generators/graphql/relay.rb +21 -18
  10. data/lib/generators/graphql/templates/base_argument.erb +2 -0
  11. data/lib/generators/graphql/templates/base_connection.erb +2 -0
  12. data/lib/generators/graphql/templates/base_edge.erb +2 -0
  13. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  14. data/lib/generators/graphql/templates/base_field.erb +2 -0
  15. data/lib/generators/graphql/templates/base_input_object.erb +2 -0
  16. data/lib/generators/graphql/templates/base_interface.erb +2 -0
  17. data/lib/generators/graphql/templates/base_object.erb +2 -0
  18. data/lib/generators/graphql/templates/base_resolver.erb +8 -0
  19. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  20. data/lib/generators/graphql/templates/base_union.erb +2 -0
  21. data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
  22. data/lib/generators/graphql/templates/loader.erb +2 -0
  23. data/lib/generators/graphql/templates/mutation.erb +2 -0
  24. data/lib/generators/graphql/templates/node_type.erb +2 -0
  25. data/lib/generators/graphql/templates/query_type.erb +2 -0
  26. data/lib/generators/graphql/templates/schema.erb +8 -0
  27. data/lib/generators/graphql/type_generator.rb +1 -1
  28. data/lib/graphql/analysis/analyzer.rb +90 -0
  29. data/lib/graphql/analysis/field_usage.rb +65 -28
  30. data/lib/graphql/analysis/max_query_complexity.rb +11 -17
  31. data/lib/graphql/analysis/max_query_depth.rb +13 -19
  32. data/lib/graphql/analysis/query_complexity.rb +236 -61
  33. data/lib/graphql/analysis/query_depth.rb +38 -23
  34. data/lib/graphql/analysis/visitor.rb +280 -0
  35. data/lib/graphql/analysis.rb +93 -6
  36. data/lib/graphql/autoload.rb +38 -0
  37. data/lib/graphql/backtrace/table.rb +118 -73
  38. data/lib/graphql/backtrace.rb +2 -25
  39. data/lib/graphql/coercion_error.rb +1 -9
  40. data/lib/graphql/current.rb +57 -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/limiters.rb +93 -0
  44. data/lib/graphql/dashboard/operation_store.rb +199 -0
  45. data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.css +6 -0
  46. data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.js +7 -0
  47. data/lib/graphql/dashboard/statics/charts.min.css +1 -0
  48. data/lib/graphql/dashboard/statics/dashboard.css +30 -0
  49. data/lib/graphql/dashboard/statics/dashboard.js +143 -0
  50. data/lib/graphql/dashboard/statics/header-icon.png +0 -0
  51. data/lib/graphql/dashboard/statics/icon.png +0 -0
  52. data/lib/graphql/dashboard/subscriptions.rb +96 -0
  53. data/lib/graphql/dashboard/views/graphql/dashboard/detailed_traces/traces/index.html.erb +45 -0
  54. data/lib/graphql/dashboard/views/graphql/dashboard/landings/show.html.erb +18 -0
  55. data/lib/graphql/dashboard/views/graphql/dashboard/limiters/limiters/show.html.erb +62 -0
  56. data/lib/graphql/dashboard/views/graphql/dashboard/not_installed.html.erb +18 -0
  57. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/_form.html.erb +23 -0
  58. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/edit.html.erb +21 -0
  59. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/index.html.erb +69 -0
  60. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/new.html.erb +7 -0
  61. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/index.html.erb +39 -0
  62. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/show.html.erb +32 -0
  63. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/index.html.erb +81 -0
  64. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/show.html.erb +71 -0
  65. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/subscriptions/show.html.erb +41 -0
  66. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/index.html.erb +55 -0
  67. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/show.html.erb +40 -0
  68. data/lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb +108 -0
  69. data/lib/graphql/dashboard.rb +158 -0
  70. data/lib/graphql/dataloader/active_record_association_source.rb +84 -0
  71. data/lib/graphql/dataloader/active_record_source.rb +47 -0
  72. data/lib/graphql/dataloader/async_dataloader.rb +101 -0
  73. data/lib/graphql/dataloader/null_dataloader.rb +11 -2
  74. data/lib/graphql/dataloader/request.rb +5 -0
  75. data/lib/graphql/dataloader/source.rb +103 -47
  76. data/lib/graphql/dataloader.rb +174 -148
  77. data/lib/graphql/dig.rb +3 -2
  78. data/lib/graphql/duration_encoding_error.rb +16 -0
  79. data/lib/graphql/execution/errors.rb +12 -82
  80. data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
  81. data/lib/graphql/execution/interpreter/arguments.rb +1 -1
  82. data/lib/graphql/execution/interpreter/arguments_cache.rb +30 -35
  83. data/lib/graphql/execution/interpreter/resolve.rb +32 -2
  84. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +215 -0
  85. data/lib/graphql/execution/interpreter/runtime.rb +525 -502
  86. data/lib/graphql/execution/interpreter.rb +127 -81
  87. data/lib/graphql/execution/lazy.rb +7 -21
  88. data/lib/graphql/execution/lookahead.rb +133 -55
  89. data/lib/graphql/execution/multiplex.rb +6 -176
  90. data/lib/graphql/execution.rb +11 -4
  91. data/lib/graphql/introspection/directive_location_enum.rb +1 -1
  92. data/lib/graphql/introspection/directive_type.rb +1 -1
  93. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  94. data/lib/graphql/introspection/entry_points.rb +10 -17
  95. data/lib/graphql/introspection/field_type.rb +1 -1
  96. data/lib/graphql/introspection/schema_type.rb +8 -11
  97. data/lib/graphql/introspection/type_type.rb +13 -6
  98. data/lib/graphql/introspection.rb +4 -3
  99. data/lib/graphql/invalid_name_error.rb +1 -1
  100. data/lib/graphql/invalid_null_error.rb +20 -17
  101. data/lib/graphql/language/block_string.rb +34 -18
  102. data/lib/graphql/language/cache.rb +13 -0
  103. data/lib/graphql/language/comment.rb +18 -0
  104. data/lib/graphql/language/definition_slice.rb +1 -1
  105. data/lib/graphql/language/document_from_schema_definition.rb +114 -80
  106. data/lib/graphql/language/lexer.rb +375 -1489
  107. data/lib/graphql/language/nodes.rb +189 -104
  108. data/lib/graphql/language/parser.rb +807 -1941
  109. data/lib/graphql/language/printer.rb +366 -163
  110. data/lib/graphql/language/sanitized_printer.rb +21 -23
  111. data/lib/graphql/language/static_visitor.rb +171 -0
  112. data/lib/graphql/language/visitor.rb +189 -138
  113. data/lib/graphql/language.rb +62 -1
  114. data/lib/graphql/load_application_object_failed_error.rb +5 -1
  115. data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
  116. data/lib/graphql/pagination/array_connection.rb +8 -6
  117. data/lib/graphql/pagination/connection.rb +61 -7
  118. data/lib/graphql/pagination/connections.rb +3 -28
  119. data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
  120. data/lib/graphql/pagination/relation_connection.rb +2 -0
  121. data/lib/graphql/query/context/scoped_context.rb +101 -0
  122. data/lib/graphql/query/context.rb +131 -225
  123. data/lib/graphql/query/input_validation_result.rb +1 -1
  124. data/lib/graphql/query/null_context.rb +11 -33
  125. data/lib/graphql/query/partial.rb +179 -0
  126. data/lib/graphql/query/validation_pipeline.rb +14 -37
  127. data/lib/graphql/query/variable_validation_error.rb +1 -1
  128. data/lib/graphql/query/variables.rb +6 -19
  129. data/lib/graphql/query.rb +162 -98
  130. data/lib/graphql/railtie.rb +15 -109
  131. data/lib/graphql/rake_task/validate.rb +1 -1
  132. data/lib/graphql/rake_task.rb +30 -11
  133. data/lib/graphql/relay/range_add.rb +9 -20
  134. data/lib/graphql/relay.rb +0 -15
  135. data/lib/graphql/rubocop/graphql/base_cop.rb +1 -1
  136. data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
  137. data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
  138. data/lib/graphql/rubocop.rb +2 -0
  139. data/lib/graphql/schema/addition.rb +70 -33
  140. data/lib/graphql/schema/always_visible.rb +15 -0
  141. data/lib/graphql/schema/argument.rb +104 -59
  142. data/lib/graphql/schema/base_64_encoder.rb +3 -5
  143. data/lib/graphql/schema/build_from_definition.rb +154 -74
  144. data/lib/graphql/schema/directive/flagged.rb +4 -2
  145. data/lib/graphql/schema/directive/one_of.rb +24 -0
  146. data/lib/graphql/schema/directive/specified_by.rb +14 -0
  147. data/lib/graphql/schema/directive/transform.rb +1 -1
  148. data/lib/graphql/schema/directive.rb +47 -24
  149. data/lib/graphql/schema/enum.rb +137 -65
  150. data/lib/graphql/schema/enum_value.rb +11 -26
  151. data/lib/graphql/schema/field/connection_extension.rb +6 -16
  152. data/lib/graphql/schema/field/scope_extension.rb +8 -1
  153. data/lib/graphql/schema/field.rb +399 -404
  154. data/lib/graphql/schema/field_extension.rb +2 -5
  155. data/lib/graphql/schema/find_inherited_value.rb +2 -7
  156. data/lib/graphql/schema/has_single_input_argument.rb +160 -0
  157. data/lib/graphql/schema/input_object.rb +144 -99
  158. data/lib/graphql/schema/interface.rb +34 -51
  159. data/lib/graphql/schema/introspection_system.rb +12 -26
  160. data/lib/graphql/schema/late_bound_type.rb +12 -2
  161. data/lib/graphql/schema/list.rb +3 -9
  162. data/lib/graphql/schema/loader.rb +4 -6
  163. data/lib/graphql/schema/member/base_dsl_methods.rb +32 -18
  164. data/lib/graphql/schema/member/build_type.rb +15 -9
  165. data/lib/graphql/schema/member/has_arguments.rb +192 -96
  166. data/lib/graphql/schema/member/has_ast_node.rb +12 -0
  167. data/lib/graphql/schema/member/has_dataloader.rb +62 -0
  168. data/lib/graphql/schema/member/has_deprecation_reason.rb +18 -4
  169. data/lib/graphql/schema/member/has_directives.rb +81 -61
  170. data/lib/graphql/schema/member/has_fields.rb +119 -39
  171. data/lib/graphql/schema/member/has_interfaces.rb +66 -23
  172. data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
  173. data/lib/graphql/schema/member/has_validators.rb +32 -6
  174. data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
  175. data/lib/graphql/schema/member/scoped.rb +19 -0
  176. data/lib/graphql/schema/member/type_system_helpers.rb +32 -2
  177. data/lib/graphql/schema/member/validates_input.rb +4 -4
  178. data/lib/graphql/schema/member.rb +1 -6
  179. data/lib/graphql/schema/mutation.rb +7 -9
  180. data/lib/graphql/schema/non_null.rb +1 -7
  181. data/lib/graphql/schema/object.rb +42 -49
  182. data/lib/graphql/schema/printer.rb +12 -8
  183. data/lib/graphql/schema/ractor_shareable.rb +79 -0
  184. data/lib/graphql/schema/relay_classic_mutation.rb +12 -124
  185. data/lib/graphql/schema/resolver/has_payload_type.rb +20 -10
  186. data/lib/graphql/schema/resolver.rb +96 -81
  187. data/lib/graphql/schema/scalar.rb +10 -30
  188. data/lib/graphql/schema/subscription.rb +60 -14
  189. data/lib/graphql/schema/timeout.rb +44 -31
  190. data/lib/graphql/schema/type_expression.rb +2 -2
  191. data/lib/graphql/schema/type_membership.rb +3 -0
  192. data/lib/graphql/schema/union.rb +12 -19
  193. data/lib/graphql/schema/unique_within_type.rb +1 -1
  194. data/lib/graphql/schema/validator/all_validator.rb +62 -0
  195. data/lib/graphql/schema/validator/required_validator.rb +60 -10
  196. data/lib/graphql/schema/validator.rb +5 -3
  197. data/lib/graphql/schema/visibility/migration.rb +188 -0
  198. data/lib/graphql/schema/visibility/profile.rb +445 -0
  199. data/lib/graphql/schema/visibility/visit.rb +190 -0
  200. data/lib/graphql/schema/visibility.rb +311 -0
  201. data/lib/graphql/schema/warden.rb +318 -94
  202. data/lib/graphql/schema/wrapper.rb +0 -5
  203. data/lib/graphql/schema.rb +1148 -1085
  204. data/lib/graphql/static_validation/all_rules.rb +4 -3
  205. data/lib/graphql/static_validation/base_visitor.rb +11 -27
  206. data/lib/graphql/static_validation/definition_dependencies.rb +7 -1
  207. data/lib/graphql/static_validation/error.rb +2 -2
  208. data/lib/graphql/static_validation/literal_validator.rb +24 -7
  209. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  210. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +1 -1
  211. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -2
  212. data/lib/graphql/static_validation/rules/directives_are_defined.rb +13 -7
  213. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +14 -12
  214. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +12 -2
  215. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +48 -6
  216. data/lib/graphql/static_validation/rules/fields_will_merge.rb +90 -27
  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 +3 -3
  219. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +12 -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/one_of_input_objects_are_valid.rb +66 -0
  225. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  226. data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
  227. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +5 -5
  228. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +5 -5
  229. data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +26 -0
  230. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +19 -9
  231. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
  232. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
  233. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
  234. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +11 -2
  235. data/lib/graphql/static_validation/validation_context.rb +21 -5
  236. data/lib/graphql/static_validation/validator.rb +12 -26
  237. data/lib/graphql/static_validation.rb +0 -3
  238. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +14 -6
  239. data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
  240. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +40 -1
  241. data/lib/graphql/subscriptions/event.rb +24 -12
  242. data/lib/graphql/subscriptions/serialize.rb +3 -1
  243. data/lib/graphql/subscriptions.rb +48 -32
  244. data/lib/graphql/testing/helpers.rb +158 -0
  245. data/lib/graphql/testing.rb +2 -0
  246. data/lib/graphql/tracing/active_support_notifications_trace.rb +27 -0
  247. data/lib/graphql/tracing/active_support_notifications_tracing.rb +1 -1
  248. data/lib/graphql/tracing/appoptics_trace.rb +259 -0
  249. data/lib/graphql/tracing/appoptics_tracing.rb +9 -2
  250. data/lib/graphql/tracing/appsignal_trace.rb +54 -0
  251. data/lib/graphql/tracing/appsignal_tracing.rb +2 -0
  252. data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
  253. data/lib/graphql/tracing/data_dog_trace.rb +71 -0
  254. data/lib/graphql/tracing/data_dog_tracing.rb +3 -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 +93 -0
  258. data/lib/graphql/{execution/instrumentation.rb → tracing/legacy_hooks_trace.rb} +11 -28
  259. data/lib/graphql/tracing/legacy_trace.rb +12 -0
  260. data/lib/graphql/tracing/monitor_trace.rb +283 -0
  261. data/lib/graphql/tracing/new_relic_trace.rb +68 -0
  262. data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
  263. data/lib/graphql/tracing/notifications_trace.rb +195 -0
  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 +734 -0
  269. data/lib/graphql/tracing/platform_trace.rb +123 -0
  270. data/lib/graphql/tracing/platform_tracing.rb +28 -41
  271. data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +6 -2
  272. data/lib/graphql/tracing/prometheus_trace.rb +93 -0
  273. data/lib/graphql/tracing/prometheus_tracing.rb +5 -3
  274. data/lib/graphql/tracing/scout_trace.rb +49 -0
  275. data/lib/graphql/tracing/scout_tracing.rb +2 -0
  276. data/lib/graphql/tracing/sentry_trace.rb +80 -0
  277. data/lib/graphql/tracing/statsd_trace.rb +48 -0
  278. data/lib/graphql/tracing/statsd_tracing.rb +2 -0
  279. data/lib/graphql/tracing/trace.rb +186 -0
  280. data/lib/graphql/tracing.rb +32 -52
  281. data/lib/graphql/type_kinds.rb +8 -4
  282. data/lib/graphql/types/iso_8601_date.rb +4 -1
  283. data/lib/graphql/types/iso_8601_date_time.rb +4 -0
  284. data/lib/graphql/types/iso_8601_duration.rb +77 -0
  285. data/lib/graphql/types/relay/base_connection.rb +16 -6
  286. data/lib/graphql/types/relay/connection_behaviors.rb +65 -23
  287. data/lib/graphql/types/relay/edge_behaviors.rb +33 -5
  288. data/lib/graphql/types/relay/node_behaviors.rb +12 -2
  289. data/lib/graphql/types/relay/page_info_behaviors.rb +11 -2
  290. data/lib/graphql/types/relay.rb +0 -3
  291. data/lib/graphql/types/string.rb +1 -1
  292. data/lib/graphql/types.rb +18 -10
  293. data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
  294. data/lib/graphql/version.rb +1 -1
  295. data/lib/graphql.rb +76 -123
  296. data/readme.md +13 -3
  297. metadata +225 -142
  298. data/lib/graphql/analysis/analyze_query.rb +0 -98
  299. data/lib/graphql/analysis/ast/analyzer.rb +0 -84
  300. data/lib/graphql/analysis/ast/field_usage.rb +0 -55
  301. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -23
  302. data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
  303. data/lib/graphql/analysis/ast/query_complexity.rb +0 -230
  304. data/lib/graphql/analysis/ast/query_depth.rb +0 -56
  305. data/lib/graphql/analysis/ast/visitor.rb +0 -269
  306. data/lib/graphql/analysis/ast.rb +0 -91
  307. data/lib/graphql/analysis/reducer_state.rb +0 -48
  308. data/lib/graphql/argument.rb +0 -131
  309. data/lib/graphql/authorization.rb +0 -82
  310. data/lib/graphql/backtrace/inspect_result.rb +0 -50
  311. data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
  312. data/lib/graphql/backtrace/tracer.rb +0 -81
  313. data/lib/graphql/backwards_compatibility.rb +0 -61
  314. data/lib/graphql/base_type.rb +0 -232
  315. data/lib/graphql/boolean_type.rb +0 -2
  316. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  317. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  318. data/lib/graphql/compatibility/execution_specification.rb +0 -436
  319. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  320. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
  321. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  322. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  323. data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
  324. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
  325. data/lib/graphql/compatibility.rb +0 -5
  326. data/lib/graphql/define/assign_argument.rb +0 -12
  327. data/lib/graphql/define/assign_connection.rb +0 -13
  328. data/lib/graphql/define/assign_enum_value.rb +0 -18
  329. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  330. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  331. data/lib/graphql/define/assign_object_field.rb +0 -42
  332. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  333. data/lib/graphql/define/instance_definable.rb +0 -255
  334. data/lib/graphql/define/no_definition_error.rb +0 -7
  335. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  336. data/lib/graphql/define/type_definer.rb +0 -31
  337. data/lib/graphql/define.rb +0 -31
  338. data/lib/graphql/deprecated_dsl.rb +0 -55
  339. data/lib/graphql/deprecation.rb +0 -9
  340. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  341. data/lib/graphql/directive/include_directive.rb +0 -2
  342. data/lib/graphql/directive/skip_directive.rb +0 -2
  343. data/lib/graphql/directive.rb +0 -107
  344. data/lib/graphql/enum_type.rb +0 -133
  345. data/lib/graphql/execution/execute.rb +0 -333
  346. data/lib/graphql/execution/flatten.rb +0 -40
  347. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  348. data/lib/graphql/execution/typecast.rb +0 -50
  349. data/lib/graphql/field/resolve.rb +0 -59
  350. data/lib/graphql/field.rb +0 -226
  351. data/lib/graphql/filter.rb +0 -53
  352. data/lib/graphql/float_type.rb +0 -2
  353. data/lib/graphql/function.rb +0 -128
  354. data/lib/graphql/id_type.rb +0 -2
  355. data/lib/graphql/input_object_type.rb +0 -138
  356. data/lib/graphql/int_type.rb +0 -2
  357. data/lib/graphql/interface_type.rb +0 -72
  358. data/lib/graphql/internal_representation/document.rb +0 -27
  359. data/lib/graphql/internal_representation/node.rb +0 -206
  360. data/lib/graphql/internal_representation/print.rb +0 -51
  361. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  362. data/lib/graphql/internal_representation/scope.rb +0 -88
  363. data/lib/graphql/internal_representation/visit.rb +0 -36
  364. data/lib/graphql/internal_representation.rb +0 -7
  365. data/lib/graphql/language/lexer.rl +0 -260
  366. data/lib/graphql/language/parser.y +0 -550
  367. data/lib/graphql/language/token.rb +0 -34
  368. data/lib/graphql/list_type.rb +0 -80
  369. data/lib/graphql/non_null_type.rb +0 -71
  370. data/lib/graphql/object_type.rb +0 -130
  371. data/lib/graphql/query/arguments.rb +0 -189
  372. data/lib/graphql/query/arguments_cache.rb +0 -24
  373. data/lib/graphql/query/executor.rb +0 -52
  374. data/lib/graphql/query/literal_input.rb +0 -136
  375. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  376. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  377. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  378. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  379. data/lib/graphql/query/serial_execution.rb +0 -40
  380. data/lib/graphql/relay/array_connection.rb +0 -83
  381. data/lib/graphql/relay/base_connection.rb +0 -189
  382. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  383. data/lib/graphql/relay/connection_resolve.rb +0 -43
  384. data/lib/graphql/relay/connection_type.rb +0 -54
  385. data/lib/graphql/relay/edge.rb +0 -27
  386. data/lib/graphql/relay/edge_type.rb +0 -19
  387. data/lib/graphql/relay/edges_instrumentation.rb +0 -39
  388. data/lib/graphql/relay/global_id_resolve.rb +0 -17
  389. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  390. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  391. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  392. data/lib/graphql/relay/mutation/result.rb +0 -38
  393. data/lib/graphql/relay/mutation.rb +0 -106
  394. data/lib/graphql/relay/node.rb +0 -39
  395. data/lib/graphql/relay/page_info.rb +0 -7
  396. data/lib/graphql/relay/relation_connection.rb +0 -188
  397. data/lib/graphql/relay/type_extensions.rb +0 -32
  398. data/lib/graphql/scalar_type.rb +0 -91
  399. data/lib/graphql/schema/base_64_bp.rb +0 -26
  400. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  401. data/lib/graphql/schema/default_parse_error.rb +0 -10
  402. data/lib/graphql/schema/default_type_error.rb +0 -17
  403. data/lib/graphql/schema/invalid_type_error.rb +0 -7
  404. data/lib/graphql/schema/member/accepts_definition.rb +0 -164
  405. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -58
  406. data/lib/graphql/schema/member/instrumentation.rb +0 -131
  407. data/lib/graphql/schema/middleware_chain.rb +0 -82
  408. data/lib/graphql/schema/null_mask.rb +0 -11
  409. data/lib/graphql/schema/possible_types.rb +0 -44
  410. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  411. data/lib/graphql/schema/timeout_middleware.rb +0 -88
  412. data/lib/graphql/schema/traversal.rb +0 -228
  413. data/lib/graphql/schema/validation.rb +0 -313
  414. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  415. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  416. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +0 -17
  417. data/lib/graphql/static_validation/type_stack.rb +0 -216
  418. data/lib/graphql/string_type.rb +0 -2
  419. data/lib/graphql/subscriptions/instrumentation.rb +0 -79
  420. data/lib/graphql/subscriptions/subscription_root.rb +0 -76
  421. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  422. data/lib/graphql/types/relay/default_relay.rb +0 -31
  423. data/lib/graphql/types/relay/node_field.rb +0 -24
  424. data/lib/graphql/types/relay/nodes_field.rb +0 -43
  425. data/lib/graphql/union_type.rb +0 -115
  426. data/lib/graphql/upgrader/member.rb +0 -937
  427. data/lib/graphql/upgrader/schema.rb +0 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e6d252cf12d6c3f2ccd6f20a139e0c2f3c460a6c25b8c1cb663e3cacf5e12855
4
- data.tar.gz: 0d6eda9b7e23c0c58677b44ed1de968c6d60acd4a5f5a49883935ea6e326d691
3
+ metadata.gz: 5c2ef756861a779063236ee9f8745d30ae3494138674239c8f638556d7f5105e
4
+ data.tar.gz: 23592e61f76acb0be2a4c60d953a829e8f1d46534633513ac44797a5d3386d2a
5
5
  SHA512:
6
- metadata.gz: 302f1e1fe6e7a31ede6c3eb4e3f63f3a2818b47286e4b2482e5109b47c8fcd1e229815c964fdd11ceed8084db4ccac9578f8374e53b2080bbb8cc03473a50ffb
7
- data.tar.gz: 85daddd620840df2718f2730b475f3c2f9df7b318145044c7fb1aada43c4dee1a00c503440953d8711e58265a7f6eb768f58ac8d1af60fe6e50bf7078d7c86b5
6
+ metadata.gz: 5c8db1d976343d569aa1fec1cee02de2c72947e0937fcd9917f8f6e078204efd373d244954e9e03b8dc7fd20066dcf7533bf4b52c706dba0f5640b60ae0465f0
7
+ data.tar.gz: 38422c543b159cc7243ac4dcc9139ed95b2583cab7942c60e4c557b89d6a4ffaa8fb1df94286fa3fbe4b918f5c116364d5fbe5c2afa611ba9d46d7ac56c18e61
@@ -9,7 +9,7 @@ module Graphql
9
9
  class MutationRootGenerator < Rails::Generators::Base
10
10
  include Core
11
11
 
12
- desc "Create mutation base type, mutation root tipe, and adds the latter to the schema"
12
+ desc "Create mutation base type, mutation root type, and adds the latter to the schema"
13
13
  source_root File.expand_path('../templates', __FILE__)
14
14
 
15
15
  class_option :schema,
@@ -31,4 +31,4 @@ module Graphql
31
31
  end
32
32
  end
33
33
  end
34
- end
34
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  module Mutations
3
5
  class BaseMutation < GraphQL::Schema::RelayClassicMutation
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  module Types
3
5
  class MutationType < Types::BaseObject
@@ -45,9 +45,16 @@ module Graphql
45
45
  # post "/graphql", to: "graphql#execute"
46
46
  # ```
47
47
  #
48
+ # Add ActiveRecord::QueryLogs metadata:
49
+ # ```ruby
50
+ # current_graphql_operation: -> { GraphQL::Current.operation_name },
51
+ # current_graphql_field: -> { GraphQL::Current.field&.path },
52
+ # current_dataloader_source: -> { GraphQL::Current.dataloader_source_class },
53
+ # ```
54
+ #
48
55
  # Accept a `--batch` option which adds `GraphQL::Batch` setup.
49
56
  #
50
- # Use `--no-graphiql` to skip `graphiql-rails` installation.
57
+ # Use `--skip-graphiql` to skip `graphiql-rails` installation.
51
58
  #
52
59
  # TODO: also add base classes
53
60
  class InstallGenerator < Rails::Generators::Base
@@ -92,6 +99,11 @@ module Graphql
92
99
  default: false,
93
100
  desc: "Use GraphQL Playground over Graphiql as IDE"
94
101
 
102
+ class_option :skip_query_logs,
103
+ type: :boolean,
104
+ default: false,
105
+ desc: "Skip ActiveRecord::QueryLogs hooks in config/application.rb"
106
+
95
107
  # These two options are taken from Rails' own generators'
96
108
  class_option :api,
97
109
  type: :boolean,
@@ -105,6 +117,9 @@ module Graphql
105
117
  template("#{base_type}.erb", "#{options[:directory]}/types/#{base_type}.rb")
106
118
  end
107
119
 
120
+ # All resolvers are defined as living in their own module, including this class.
121
+ template("base_resolver.erb", "#{options[:directory]}/resolvers/base_resolver.rb")
122
+
108
123
  # Note: You can't have a schema without the query type, otherwise introspection breaks
109
124
  template("query_type.erb", "#{options[:directory]}/types/query_type.rb")
110
125
  insert_root_type('query', 'QueryType')
@@ -177,6 +192,40 @@ RUBY
177
192
  install_relay
178
193
  end
179
194
 
195
+ if !options[:skip_query_logs]
196
+ config_file = "config/application.rb"
197
+ current_app_rb = File.read(Rails.root.join(config_file))
198
+ existing_log_tags_pattern = /config.active_record.query_log_tags = \[\n?(\s*:[a-z_]+,?\s*\n?|\s*#[^\]]*\n)*/m
199
+ existing_log_tags = existing_log_tags_pattern.match(current_app_rb)
200
+ if existing_log_tags && behavior == :invoke
201
+ code = <<-RUBY
202
+ # GraphQL-Ruby query log tags:
203
+ current_graphql_operation: -> { GraphQL::Current.operation_name },
204
+ current_graphql_field: -> { GraphQL::Current.field&.path },
205
+ current_dataloader_source: -> { GraphQL::Current.dataloader_source_class },
206
+ RUBY
207
+ if !existing_log_tags.to_s.end_with?(",")
208
+ code = ",\n#{code} "
209
+ end
210
+ # Try to insert this code _after_ any plain symbol entries in the array of query log tags:
211
+ after_code = existing_log_tags_pattern
212
+ else
213
+ code = <<-RUBY
214
+ config.active_record.query_log_tags_enabled = true
215
+ config.active_record.query_log_tags = [
216
+ # Rails query log tags:
217
+ :application, :controller, :action, :job,
218
+ # GraphQL-Ruby query log tags:
219
+ current_graphql_operation: -> { GraphQL::Current.operation_name },
220
+ current_graphql_field: -> { GraphQL::Current.field&.path },
221
+ current_dataloader_source: -> { GraphQL::Current.dataloader_source_class },
222
+ ]
223
+ RUBY
224
+ after_code = "class Application < Rails::Application\n"
225
+ end
226
+ insert_into_file(config_file, code, after: after_code)
227
+ end
228
+
180
229
  if gemfile_modified?
181
230
  say "Gemfile has been modified, make sure you `bundle install`"
182
231
  end
@@ -6,7 +6,7 @@ module Graphql
6
6
  # TODO: What other options should be supported?
7
7
  #
8
8
  # @example Generate a `GraphQL::Schema::RelayClassicMutation` by name
9
- # rails g graphql:mutation CreatePostMutation
9
+ # rails g graphql:mutation DeletePostMutation
10
10
  class MutationDeleteGenerator < OrmMutationsBase
11
11
 
12
12
  desc "Scaffold a Relay Classic ORM delete mutation for the given model class"
@@ -6,7 +6,7 @@ module Graphql
6
6
  # TODO: What other options should be supported?
7
7
  #
8
8
  # @example Generate a `GraphQL::Schema::RelayClassicMutation` by name
9
- # rails g graphql:mutation CreatePostMutation
9
+ # rails g graphql:mutation UpdatePostMutation
10
10
  class MutationUpdateGenerator < OrmMutationsBase
11
11
 
12
12
  desc "Scaffold a Relay Classic ORM update mutation for the given model class"
@@ -18,7 +18,7 @@ module Graphql
18
18
  class_option :orm, banner: "NAME", type: :string, required: true,
19
19
  desc: "ORM to generate the controller for"
20
20
 
21
- class_option 'namespaced_types',
21
+ class_option :namespaced_types,
22
22
  type: :boolean,
23
23
  required: false,
24
24
  default: false,
@@ -6,7 +6,24 @@ module Graphql
6
6
  # Add Node, `node(id:)`, and `nodes(ids:)`
7
7
  template("node_type.erb", "#{options[:directory]}/types/node_type.rb")
8
8
  in_root do
9
- fields = " # Add `node(id: ID!) and `nodes(ids: [ID!]!)`\n include GraphQL::Types::Relay::HasNodeField\n include GraphQL::Types::Relay::HasNodesField\n\n"
9
+ fields = <<-RUBY
10
+ field :node, Types::NodeType, null: true, description: "Fetches an object given its ID." do
11
+ argument :id, ID, required: true, description: "ID of the object."
12
+ end
13
+
14
+ def node(id:)
15
+ context.schema.object_from_id(id, context)
16
+ end
17
+
18
+ field :nodes, [Types::NodeType, null: true], null: true, description: "Fetches a list of objects given a list of IDs." do
19
+ argument :ids, [ID], required: true, description: "IDs of the objects."
20
+ end
21
+
22
+ def nodes(ids:)
23
+ ids.map { |id| context.schema.object_from_id(id, context) }
24
+ end
25
+
26
+ RUBY
10
27
  inject_into_file "#{options[:directory]}/types/query_type.rb", fields, after: /class .*QueryType\s*<\s*[^\s]+?\n/m, force: false
11
28
  end
12
29
 
@@ -33,27 +50,13 @@ module Graphql
33
50
  # Return a string UUID for `object`
34
51
  def self.id_from_object(object, type_definition, query_ctx)
35
52
  # For example, use Rails' GlobalID library (https://github.com/rails/globalid):
36
- object_id = object.to_global_id.to_s
37
- # Remove this redundant prefix to make IDs shorter:
38
- object_id = object_id.sub("gid://\#{GlobalID.app}/", "")
39
- encoded_id = Base64.urlsafe_encode64(object_id)
40
- # Remove the "=" padding
41
- encoded_id = encoded_id.sub(/=+/, "")
42
- # Add a type hint
43
- type_hint = type_definition.graphql_name.first
44
- "\#{type_hint}_\#{encoded_id}"
53
+ object.to_gid_param
45
54
  end
46
55
 
47
56
  # Given a string UUID, find the object
48
- def self.object_from_id(encoded_id_with_hint, query_ctx)
57
+ def self.object_from_id(global_id, query_ctx)
49
58
  # For example, use Rails' GlobalID library (https://github.com/rails/globalid):
50
- # Split off the type hint
51
- _type_hint, encoded_id = encoded_id_with_hint.split("_", 2)
52
- # Decode the ID
53
- id = Base64.urlsafe_decode64(encoded_id)
54
- # Rebuild it for Rails then find the object:
55
- full_global_id = "gid://\#{GlobalID.app}/\#{id}"
56
- GlobalID::Locator.locate(full_global_id)
59
+ GlobalID.find(global_id)
57
60
  end
58
61
  RUBY
59
62
  inject_into_file schema_file_path, schema_code, before: /^end\n/m, force: false
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  module Types
3
5
  class BaseArgument < GraphQL::Schema::Argument
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  module Types
3
5
  class BaseConnection < Types::BaseObject
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  module Types
3
5
  class BaseEdge < Types::BaseObject
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  module Types
3
5
  class BaseEnum < GraphQL::Schema::Enum
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  module Types
3
5
  class BaseField < GraphQL::Schema::Field
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  module Types
3
5
  class BaseInputObject < GraphQL::Schema::InputObject
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  module Types
3
5
  module BaseInterface
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  module Types
3
5
  class BaseObject < GraphQL::Schema::Object
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ <% module_namespacing_when_supported do -%>
4
+ module Resolvers
5
+ class BaseResolver < GraphQL::Schema::Resolver
6
+ end
7
+ end
8
+ <% end -%>
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  module Types
3
5
  class BaseScalar < GraphQL::Schema::Scalar
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  module Types
3
5
  class BaseUnion < GraphQL::Schema::Union
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  class GraphqlController < ApplicationController
3
5
  # If accessing from outside this domain, nullify the session
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  module Loaders
3
5
  class <%= class_name %> < GraphQL::Batch::Loader
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  module Mutations
3
5
  class <%= class_name %> < BaseMutation
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  module Types
3
5
  module NodeType
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  module Types
3
5
  class QueryType < Types::BaseObject
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing_when_supported do -%>
2
4
  class <%= schema_name %> < GraphQL::Schema
3
5
  query(Types::QueryType)
@@ -23,5 +25,11 @@ class <%= schema_name %> < GraphQL::Schema
23
25
  # to return the correct GraphQL object type for `obj`
24
26
  raise(GraphQL::RequiredImplementationMissingError)
25
27
  end
28
+
29
+ # Limit the size of incoming queries:
30
+ max_query_string_tokens(5000)
31
+
32
+ # Stop validating when it encounters this many errors:
33
+ validate_max_errors(100)
26
34
  end
27
35
  <% end -%>
@@ -11,7 +11,7 @@ module Graphql
11
11
  class TypeGeneratorBase < Rails::Generators::NamedBase
12
12
  include Core
13
13
 
14
- class_option 'namespaced_types',
14
+ class_option :namespaced_types,
15
15
  type: :boolean,
16
16
  required: false,
17
17
  default: false,
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ module Analysis
4
+ # Query analyzer for query ASTs. Query analyzers respond to visitor style methods
5
+ # but are prefixed by `enter` and `leave`.
6
+ #
7
+ # When an analyzer is initialized with a Multiplex, you can always get the current query from
8
+ # `visitor.query` in the visit methods.
9
+ #
10
+ # @param [GraphQL::Query, GraphQL::Execution::Multiplex] The query or multiplex to analyze
11
+ class Analyzer
12
+ def initialize(subject)
13
+ @subject = subject
14
+
15
+ if subject.is_a?(GraphQL::Query)
16
+ @query = subject
17
+ @multiplex = nil
18
+ else
19
+ @multiplex = subject
20
+ @query = nil
21
+ end
22
+ end
23
+
24
+ # Analyzer hook to decide at analysis time whether a query should
25
+ # be analyzed or not.
26
+ # @return [Boolean] If the query should be analyzed or not
27
+ def analyze?
28
+ true
29
+ end
30
+
31
+ # Analyzer hook to decide at analysis time whether analysis
32
+ # requires a visitor pass; can be disabled for precomputed results.
33
+ # @return [Boolean] If analysis requires visitation or not
34
+ def visit?
35
+ true
36
+ end
37
+
38
+ # The result for this analyzer. Returning {GraphQL::AnalysisError} results
39
+ # in a query error.
40
+ # @return [Any] The analyzer result
41
+ def result
42
+ raise GraphQL::RequiredImplementationMissingError
43
+ end
44
+
45
+ # rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
46
+ class << self
47
+ private
48
+
49
+ def build_visitor_hooks(member_name)
50
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
51
+ def on_enter_#{member_name}(node, parent, visitor)
52
+ end
53
+
54
+ def on_leave_#{member_name}(node, parent, visitor)
55
+ end
56
+ EOS
57
+ end
58
+ end
59
+
60
+ build_visitor_hooks :argument
61
+ build_visitor_hooks :directive
62
+ build_visitor_hooks :document
63
+ build_visitor_hooks :enum
64
+ build_visitor_hooks :field
65
+ build_visitor_hooks :fragment_spread
66
+ build_visitor_hooks :inline_fragment
67
+ build_visitor_hooks :input_object
68
+ build_visitor_hooks :list_type
69
+ build_visitor_hooks :non_null_type
70
+ build_visitor_hooks :null_value
71
+ build_visitor_hooks :operation_definition
72
+ build_visitor_hooks :type_name
73
+ build_visitor_hooks :variable_definition
74
+ build_visitor_hooks :variable_identifier
75
+ build_visitor_hooks :abstract_node
76
+ # rubocop:enable Development/NoEvalCop
77
+ protected
78
+
79
+ # @return [GraphQL::Query, GraphQL::Execution::Multiplex] Whatever this analyzer is analyzing
80
+ attr_reader :subject
81
+
82
+ # @return [GraphQL::Query, nil] `nil` if this analyzer is visiting a multiplex
83
+ # (When this is `nil`, use `visitor.query` inside visit methods to get the current query)
84
+ attr_reader :query
85
+
86
+ # @return [GraphQL::Execution::Multiplex, nil] `nil` if this analyzer is visiting a query
87
+ attr_reader :multiplex
88
+ end
89
+ end
90
+ end
@@ -1,44 +1,81 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
3
  module Analysis
4
- # A query reducer for tracking both field usage and deprecated field usage.
5
- #
6
- # @example Logging field usage and deprecated field usage
7
- # Schema.query_analyzers << GraphQL::Analysis::FieldUsage.new { |query, used_fields, used_deprecated_fields|
8
- # puts "Used GraphQL fields: #{used_fields.join(', ')}"
9
- # puts "Used deprecated GraphQL fields: #{used_deprecated_fields.join(', ')}"
10
- # }
11
- # Schema.execute(query_str)
12
- # # Used GraphQL fields: Cheese.id, Cheese.fatContent, Query.cheese
13
- # # Used deprecated GraphQL fields: Cheese.fatContent
14
- #
15
- class FieldUsage
16
- def initialize(&block)
17
- @field_usage_handler = block
4
+ class FieldUsage < Analyzer
5
+ def initialize(query)
6
+ super
7
+ @used_fields = Set.new
8
+ @used_deprecated_fields = Set.new
9
+ @used_deprecated_arguments = Set.new
10
+ @used_deprecated_enum_values = Set.new
18
11
  end
19
12
 
20
- def initial_value(query)
13
+ def on_leave_field(node, parent, visitor)
14
+ field_defn = visitor.field_definition
15
+ field = "#{visitor.parent_type_definition.graphql_name}.#{field_defn.graphql_name}"
16
+ @used_fields << field
17
+ @used_deprecated_fields << field if field_defn.deprecation_reason
18
+ arguments = visitor.query.arguments_for(node, field_defn)
19
+ # If there was an error when preparing this argument object,
20
+ # then this might be an error or something:
21
+ if arguments.respond_to?(:argument_values)
22
+ extract_deprecated_arguments(arguments.argument_values)
23
+ end
24
+ end
25
+
26
+ def result
21
27
  {
22
- query: query,
23
- used_fields: Set.new,
24
- used_deprecated_fields: Set.new
28
+ used_fields: @used_fields.to_a,
29
+ used_deprecated_fields: @used_deprecated_fields.to_a,
30
+ used_deprecated_arguments: @used_deprecated_arguments.to_a,
31
+ used_deprecated_enum_values: @used_deprecated_enum_values.to_a,
25
32
  }
26
33
  end
27
34
 
28
- def call(memo, visit_type, irep_node)
29
- if irep_node.ast_node.is_a?(GraphQL::Language::Nodes::Field) && visit_type == :leave
30
- field = "#{irep_node.owner_type.name}.#{irep_node.definition.name}"
31
- memo[:used_fields] << field
32
- if irep_node.definition.deprecation_reason
33
- memo[:used_deprecated_fields] << field
35
+ private
36
+
37
+ def extract_deprecated_arguments(argument_values)
38
+ argument_values.each_pair do |_argument_name, argument|
39
+ if argument.definition.deprecation_reason
40
+ @used_deprecated_arguments << argument.definition.path
34
41
  end
35
- end
36
42
 
37
- memo
43
+ arg_val = argument.value
44
+
45
+ next if arg_val.nil?
46
+
47
+ argument_type = argument.definition.type
48
+ if argument_type.non_null?
49
+ argument_type = argument_type.of_type
50
+ end
51
+
52
+ if argument_type.kind.input_object?
53
+ extract_deprecated_arguments(argument.original_value.arguments.argument_values) # rubocop:disable Development/ContextIsPassedCop -- runtime args instance
54
+ elsif argument_type.kind.enum?
55
+ extract_deprecated_enum_value(argument_type, arg_val)
56
+ elsif argument_type.list?
57
+ inner_type = argument_type.unwrap
58
+ case inner_type.kind
59
+ when TypeKinds::INPUT_OBJECT
60
+ argument.original_value.each do |value|
61
+ extract_deprecated_arguments(value.arguments.argument_values) # rubocop:disable Development/ContextIsPassedCop -- runtime args instance
62
+ end
63
+ when TypeKinds::ENUM
64
+ arg_val.each do |value|
65
+ extract_deprecated_enum_value(inner_type, value)
66
+ end
67
+ else
68
+ # Not a kind of input that we track
69
+ end
70
+ end
71
+ end
38
72
  end
39
73
 
40
- def final_value(memo)
41
- @field_usage_handler.call(memo[:query], memo[:used_fields].to_a, memo[:used_deprecated_fields].to_a)
74
+ def extract_deprecated_enum_value(enum_type, value)
75
+ enum_value = @query.types.enum_values(enum_type).find { |ev| ev.value == value }
76
+ if enum_value&.deprecation_reason
77
+ @used_deprecated_enum_values << enum_value.path
78
+ end
42
79
  end
43
80
  end
44
81
  end
@@ -1,25 +1,19 @@
1
1
  # frozen_string_literal: true
2
- require_relative "./query_complexity"
3
2
  module GraphQL
4
3
  module Analysis
5
4
  # Used under the hood to implement complexity validation,
6
5
  # see {Schema#max_complexity} and {Query#max_complexity}
7
- #
8
- # @example Assert max complexity of 10
9
- # # DON'T actually do this, graphql-ruby
10
- # # Does this for you based on your `max_complexity` setting
11
- # MySchema.query_analyzers << GraphQL::Analysis::MaxQueryComplexity.new(10)
12
- #
13
- class MaxQueryComplexity < GraphQL::Analysis::QueryComplexity
14
- def initialize(max_complexity)
15
- disallow_excessive_complexity = ->(query, complexity) {
16
- if complexity > max_complexity
17
- GraphQL::AnalysisError.new("Query has complexity of #{complexity}, which exceeds max complexity of #{max_complexity}")
18
- else
19
- nil
20
- end
21
- }
22
- super(&disallow_excessive_complexity)
6
+ class MaxQueryComplexity < QueryComplexity
7
+ def result
8
+ return if subject.max_complexity.nil?
9
+
10
+ total_complexity = max_possible_complexity
11
+
12
+ if total_complexity > subject.max_complexity
13
+ GraphQL::AnalysisError.new("Query has complexity of #{total_complexity}, which exceeds max complexity of #{subject.max_complexity}")
14
+ else
15
+ nil
16
+ end
23
17
  end
24
18
  end
25
19
  end
@@ -1,25 +1,19 @@
1
1
  # frozen_string_literal: true
2
- require_relative "./query_depth"
3
2
  module GraphQL
4
3
  module Analysis
5
- # Used under the hood to implement depth validation,
6
- # see {Schema#max_depth} and {Query#max_depth}
7
- #
8
- # @example Assert max depth of 10
9
- # # DON'T actually do this, graphql-ruby
10
- # # Does this for you based on your `max_depth` setting
11
- # MySchema.query_analyzers << GraphQL::Analysis::MaxQueryDepth.new(10)
12
- #
13
- class MaxQueryDepth < GraphQL::Analysis::QueryDepth
14
- def initialize(max_depth)
15
- disallow_excessive_depth = ->(query, depth) {
16
- if depth > max_depth
17
- GraphQL::AnalysisError.new("Query has depth of #{depth}, which exceeds max depth of #{max_depth}")
18
- else
19
- nil
20
- end
21
- }
22
- super(&disallow_excessive_depth)
4
+ class MaxQueryDepth < QueryDepth
5
+ def result
6
+ configured_max_depth = if query
7
+ query.max_depth
8
+ else
9
+ multiplex.schema.max_depth
10
+ end
11
+
12
+ if configured_max_depth && @max_depth > configured_max_depth
13
+ GraphQL::AnalysisError.new("Query has depth of #{@max_depth}, which exceeds max depth of #{configured_max_depth}")
14
+ else
15
+ nil
16
+ end
23
17
  end
24
18
  end
25
19
  end