graphql 1.12.12 → 2.4.8

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 (428) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/core.rb +3 -8
  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 +60 -4
  10. data/lib/generators/graphql/interface_generator.rb +7 -7
  11. data/lib/generators/graphql/mutation_create_generator.rb +22 -0
  12. data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
  13. data/lib/generators/graphql/mutation_generator.rb +5 -30
  14. data/lib/generators/graphql/mutation_update_generator.rb +22 -0
  15. data/lib/generators/graphql/object_generator.rb +10 -38
  16. data/lib/generators/graphql/orm_mutations_base.rb +40 -0
  17. data/lib/generators/graphql/relay.rb +23 -12
  18. data/lib/generators/graphql/scalar_generator.rb +4 -2
  19. data/lib/generators/graphql/templates/base_argument.erb +2 -0
  20. data/lib/generators/graphql/templates/base_connection.erb +2 -0
  21. data/lib/generators/graphql/templates/base_edge.erb +2 -0
  22. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  23. data/lib/generators/graphql/templates/base_field.erb +2 -0
  24. data/lib/generators/graphql/templates/base_input_object.erb +2 -0
  25. data/lib/generators/graphql/templates/base_interface.erb +2 -0
  26. data/lib/generators/graphql/templates/base_object.erb +2 -0
  27. data/lib/generators/graphql/templates/base_resolver.erb +8 -0
  28. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  29. data/lib/generators/graphql/templates/base_union.erb +2 -0
  30. data/lib/generators/graphql/templates/enum.erb +5 -1
  31. data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
  32. data/lib/generators/graphql/templates/input.erb +9 -0
  33. data/lib/generators/graphql/templates/interface.erb +4 -2
  34. data/lib/generators/graphql/templates/loader.erb +2 -0
  35. data/lib/generators/graphql/templates/mutation.erb +3 -1
  36. data/lib/generators/graphql/templates/mutation_create.erb +20 -0
  37. data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
  38. data/lib/generators/graphql/templates/mutation_update.erb +21 -0
  39. data/lib/generators/graphql/templates/node_type.erb +2 -0
  40. data/lib/generators/graphql/templates/object.erb +4 -2
  41. data/lib/generators/graphql/templates/query_type.erb +2 -0
  42. data/lib/generators/graphql/templates/scalar.erb +3 -1
  43. data/lib/generators/graphql/templates/schema.erb +22 -2
  44. data/lib/generators/graphql/templates/union.erb +4 -2
  45. data/lib/generators/graphql/type_generator.rb +46 -10
  46. data/lib/generators/graphql/union_generator.rb +5 -5
  47. data/lib/graphql/analysis/analyzer.rb +89 -0
  48. data/lib/graphql/analysis/field_usage.rb +65 -28
  49. data/lib/graphql/analysis/max_query_complexity.rb +11 -17
  50. data/lib/graphql/analysis/max_query_depth.rb +13 -19
  51. data/lib/graphql/analysis/query_complexity.rb +156 -61
  52. data/lib/graphql/analysis/query_depth.rb +38 -23
  53. data/lib/graphql/analysis/visitor.rb +283 -0
  54. data/lib/graphql/analysis.rb +90 -6
  55. data/lib/graphql/autoload.rb +38 -0
  56. data/lib/graphql/backtrace/inspect_result.rb +0 -12
  57. data/lib/graphql/backtrace/table.rb +4 -22
  58. data/lib/graphql/backtrace/trace.rb +93 -0
  59. data/lib/graphql/backtrace/tracer.rb +8 -6
  60. data/lib/graphql/backtrace.rb +3 -8
  61. data/lib/graphql/coercion_error.rb +1 -9
  62. data/lib/graphql/current.rb +52 -0
  63. data/lib/graphql/dataloader/async_dataloader.rb +89 -0
  64. data/lib/graphql/dataloader/null_dataloader.rb +4 -2
  65. data/lib/graphql/dataloader/request.rb +5 -0
  66. data/lib/graphql/dataloader/source.rb +125 -33
  67. data/lib/graphql/dataloader.rb +193 -143
  68. data/lib/graphql/date_encoding_error.rb +16 -0
  69. data/lib/graphql/dig.rb +1 -1
  70. data/lib/graphql/duration_encoding_error.rb +16 -0
  71. data/lib/graphql/execution/errors.rb +12 -81
  72. data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
  73. data/lib/graphql/execution/interpreter/arguments.rb +2 -2
  74. data/lib/graphql/execution/interpreter/arguments_cache.rb +33 -36
  75. data/lib/graphql/execution/interpreter/resolve.rb +38 -4
  76. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +175 -0
  77. data/lib/graphql/execution/interpreter/runtime.rb +447 -403
  78. data/lib/graphql/execution/interpreter.rb +126 -80
  79. data/lib/graphql/execution/lazy.rb +11 -21
  80. data/lib/graphql/execution/lookahead.rb +133 -55
  81. data/lib/graphql/execution/multiplex.rb +4 -172
  82. data/lib/graphql/execution.rb +11 -4
  83. data/lib/graphql/integer_encoding_error.rb +18 -2
  84. data/lib/graphql/introspection/directive_location_enum.rb +2 -2
  85. data/lib/graphql/introspection/directive_type.rb +6 -4
  86. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  87. data/lib/graphql/introspection/entry_points.rb +11 -18
  88. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  89. data/lib/graphql/introspection/field_type.rb +4 -4
  90. data/lib/graphql/introspection/input_value_type.rb +10 -4
  91. data/lib/graphql/introspection/schema_type.rb +17 -15
  92. data/lib/graphql/introspection/type_type.rb +29 -16
  93. data/lib/graphql/introspection.rb +6 -2
  94. data/lib/graphql/invalid_null_error.rb +1 -1
  95. data/lib/graphql/language/block_string.rb +37 -25
  96. data/lib/graphql/language/cache.rb +13 -0
  97. data/lib/graphql/language/comment.rb +18 -0
  98. data/lib/graphql/language/definition_slice.rb +1 -1
  99. data/lib/graphql/language/document_from_schema_definition.rb +122 -81
  100. data/lib/graphql/language/lexer.rb +364 -1467
  101. data/lib/graphql/language/nodes.rb +197 -106
  102. data/lib/graphql/language/parser.rb +799 -1920
  103. data/lib/graphql/language/printer.rb +372 -160
  104. data/lib/graphql/language/sanitized_printer.rb +25 -27
  105. data/lib/graphql/language/static_visitor.rb +167 -0
  106. data/lib/graphql/language/visitor.rb +188 -141
  107. data/lib/graphql/language.rb +62 -1
  108. data/lib/graphql/load_application_object_failed_error.rb +5 -1
  109. data/lib/graphql/name_validator.rb +0 -4
  110. data/lib/graphql/pagination/active_record_relation_connection.rb +37 -8
  111. data/lib/graphql/pagination/array_connection.rb +8 -6
  112. data/lib/graphql/pagination/connection.rb +61 -7
  113. data/lib/graphql/pagination/connections.rb +22 -23
  114. data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
  115. data/lib/graphql/pagination/relation_connection.rb +60 -28
  116. data/lib/graphql/query/context/scoped_context.rb +101 -0
  117. data/lib/graphql/query/context.rb +146 -222
  118. data/lib/graphql/query/input_validation_result.rb +10 -1
  119. data/lib/graphql/query/null_context.rb +15 -32
  120. data/lib/graphql/query/validation_pipeline.rb +15 -39
  121. data/lib/graphql/query/variable_validation_error.rb +3 -3
  122. data/lib/graphql/query/variables.rb +35 -17
  123. data/lib/graphql/query.rb +149 -82
  124. data/lib/graphql/railtie.rb +15 -109
  125. data/lib/graphql/rake_task/validate.rb +1 -1
  126. data/lib/graphql/rake_task.rb +30 -11
  127. data/lib/graphql/relay/range_add.rb +9 -16
  128. data/lib/graphql/relay.rb +0 -15
  129. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  130. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  131. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  132. data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
  133. data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
  134. data/lib/graphql/rubocop.rb +6 -0
  135. data/lib/graphql/schema/addition.rb +98 -54
  136. data/lib/graphql/schema/always_visible.rb +14 -0
  137. data/lib/graphql/schema/argument.rb +179 -82
  138. data/lib/graphql/schema/base_64_encoder.rb +3 -5
  139. data/lib/graphql/schema/build_from_definition.rb +77 -39
  140. data/lib/graphql/schema/directive/feature.rb +1 -1
  141. data/lib/graphql/schema/directive/flagged.rb +4 -4
  142. data/lib/graphql/schema/directive/include.rb +1 -1
  143. data/lib/graphql/schema/directive/one_of.rb +24 -0
  144. data/lib/graphql/schema/directive/skip.rb +1 -1
  145. data/lib/graphql/schema/directive/specified_by.rb +14 -0
  146. data/lib/graphql/schema/directive/transform.rb +2 -2
  147. data/lib/graphql/schema/directive.rb +36 -22
  148. data/lib/graphql/schema/enum.rb +158 -63
  149. data/lib/graphql/schema/enum_value.rb +12 -21
  150. data/lib/graphql/schema/field/connection_extension.rb +7 -17
  151. data/lib/graphql/schema/field/scope_extension.rb +8 -1
  152. data/lib/graphql/schema/field.rb +521 -359
  153. data/lib/graphql/schema/field_extension.rb +86 -2
  154. data/lib/graphql/schema/find_inherited_value.rb +3 -7
  155. data/lib/graphql/schema/finder.rb +5 -5
  156. data/lib/graphql/schema/has_single_input_argument.rb +160 -0
  157. data/lib/graphql/schema/input_object.rb +148 -99
  158. data/lib/graphql/schema/interface.rb +41 -64
  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 +18 -7
  162. data/lib/graphql/schema/loader.rb +6 -5
  163. data/lib/graphql/schema/member/base_dsl_methods.rb +32 -18
  164. data/lib/graphql/schema/member/build_type.rb +16 -13
  165. data/lib/graphql/schema/member/has_arguments.rb +270 -86
  166. data/lib/graphql/schema/member/has_ast_node.rb +12 -0
  167. data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
  168. data/lib/graphql/schema/member/has_directives.rb +81 -61
  169. data/lib/graphql/schema/member/has_fields.rb +169 -31
  170. data/lib/graphql/schema/member/has_interfaces.rb +143 -0
  171. data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
  172. data/lib/graphql/schema/member/has_validators.rb +32 -6
  173. data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
  174. data/lib/graphql/schema/member/scoped.rb +19 -0
  175. data/lib/graphql/schema/member/type_system_helpers.rb +16 -0
  176. data/lib/graphql/schema/member/validates_input.rb +6 -6
  177. data/lib/graphql/schema/member.rb +1 -6
  178. data/lib/graphql/schema/mutation.rb +7 -9
  179. data/lib/graphql/schema/non_null.rb +7 -7
  180. data/lib/graphql/schema/object.rb +38 -119
  181. data/lib/graphql/schema/printer.rb +24 -25
  182. data/lib/graphql/schema/relay_classic_mutation.rb +13 -91
  183. data/lib/graphql/schema/resolver/has_payload_type.rb +46 -11
  184. data/lib/graphql/schema/resolver.rb +118 -115
  185. data/lib/graphql/schema/scalar.rb +20 -21
  186. data/lib/graphql/schema/subscription.rb +95 -21
  187. data/lib/graphql/schema/timeout.rb +25 -29
  188. data/lib/graphql/schema/type_expression.rb +2 -2
  189. data/lib/graphql/schema/type_membership.rb +21 -4
  190. data/lib/graphql/schema/union.rb +16 -16
  191. data/lib/graphql/schema/unique_within_type.rb +1 -1
  192. data/lib/graphql/schema/validator/all_validator.rb +62 -0
  193. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  194. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  195. data/lib/graphql/schema/validator/exclusion_validator.rb +3 -1
  196. data/lib/graphql/schema/validator/format_validator.rb +4 -5
  197. data/lib/graphql/schema/validator/inclusion_validator.rb +3 -1
  198. data/lib/graphql/schema/validator/length_validator.rb +5 -3
  199. data/lib/graphql/schema/validator/numericality_validator.rb +13 -2
  200. data/lib/graphql/schema/validator/required_validator.rb +56 -18
  201. data/lib/graphql/schema/validator.rb +38 -28
  202. data/lib/graphql/schema/visibility/migration.rb +188 -0
  203. data/lib/graphql/schema/visibility/profile.rb +359 -0
  204. data/lib/graphql/schema/visibility/visit.rb +190 -0
  205. data/lib/graphql/schema/visibility.rb +294 -0
  206. data/lib/graphql/schema/warden.rb +423 -134
  207. data/lib/graphql/schema/wrapper.rb +0 -5
  208. data/lib/graphql/schema.rb +1015 -1057
  209. data/lib/graphql/static_validation/all_rules.rb +3 -1
  210. data/lib/graphql/static_validation/base_visitor.rb +15 -28
  211. data/lib/graphql/static_validation/definition_dependencies.rb +7 -2
  212. data/lib/graphql/static_validation/error.rb +3 -1
  213. data/lib/graphql/static_validation/literal_validator.rb +24 -7
  214. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  215. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +1 -1
  216. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +4 -3
  217. data/lib/graphql/static_validation/rules/directives_are_defined.rb +13 -7
  218. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +15 -13
  219. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +12 -2
  220. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +13 -5
  221. data/lib/graphql/static_validation/rules/fields_will_merge.rb +62 -35
  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/fragment_types_exist.rb +12 -2
  225. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
  226. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  227. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
  228. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
  229. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  230. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  231. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  232. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  233. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +7 -5
  234. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +5 -5
  235. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
  236. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +14 -8
  237. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
  238. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
  239. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +14 -8
  240. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +11 -2
  241. data/lib/graphql/static_validation/validation_context.rb +32 -6
  242. data/lib/graphql/static_validation/validator.rb +11 -27
  243. data/lib/graphql/static_validation.rb +0 -3
  244. data/lib/graphql/string_encoding_error.rb +13 -3
  245. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +49 -11
  246. data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
  247. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +40 -1
  248. data/lib/graphql/subscriptions/event.rb +87 -38
  249. data/lib/graphql/subscriptions/serialize.rb +27 -3
  250. data/lib/graphql/subscriptions.rb +63 -49
  251. data/lib/graphql/testing/helpers.rb +155 -0
  252. data/lib/graphql/testing.rb +2 -0
  253. data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
  254. data/lib/graphql/tracing/active_support_notifications_tracing.rb +6 -20
  255. data/lib/graphql/tracing/appoptics_trace.rb +253 -0
  256. data/lib/graphql/tracing/appoptics_tracing.rb +4 -2
  257. data/lib/graphql/tracing/appsignal_trace.rb +79 -0
  258. data/lib/graphql/tracing/appsignal_tracing.rb +17 -0
  259. data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
  260. data/lib/graphql/tracing/data_dog_trace.rb +185 -0
  261. data/lib/graphql/tracing/data_dog_tracing.rb +27 -15
  262. data/lib/graphql/{execution/instrumentation.rb → tracing/legacy_hooks_trace.rb} +11 -28
  263. data/lib/graphql/tracing/legacy_trace.rb +12 -0
  264. data/lib/graphql/tracing/new_relic_trace.rb +77 -0
  265. data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
  266. data/lib/graphql/tracing/notifications_trace.rb +45 -0
  267. data/lib/graphql/tracing/notifications_tracing.rb +61 -0
  268. data/lib/graphql/tracing/null_trace.rb +9 -0
  269. data/lib/graphql/tracing/platform_trace.rb +118 -0
  270. data/lib/graphql/tracing/platform_tracing.rb +46 -49
  271. data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +6 -2
  272. data/lib/graphql/tracing/prometheus_trace.rb +94 -0
  273. data/lib/graphql/tracing/prometheus_tracing.rb +5 -3
  274. data/lib/graphql/tracing/scout_trace.rb +74 -0
  275. data/lib/graphql/tracing/scout_tracing.rb +2 -0
  276. data/lib/graphql/tracing/sentry_trace.rb +114 -0
  277. data/lib/graphql/tracing/statsd_trace.rb +58 -0
  278. data/lib/graphql/tracing/statsd_tracing.rb +2 -0
  279. data/lib/graphql/tracing/trace.rb +79 -0
  280. data/lib/graphql/tracing.rb +29 -52
  281. data/lib/graphql/type_kinds.rb +7 -4
  282. data/lib/graphql/types/big_int.rb +5 -1
  283. data/lib/graphql/types/int.rb +1 -1
  284. data/lib/graphql/types/iso_8601_date.rb +17 -6
  285. data/lib/graphql/types/iso_8601_date_time.rb +12 -1
  286. data/lib/graphql/types/iso_8601_duration.rb +77 -0
  287. data/lib/graphql/types/relay/base_connection.rb +16 -6
  288. data/lib/graphql/types/relay/connection_behaviors.rb +92 -32
  289. data/lib/graphql/types/relay/edge_behaviors.rb +46 -7
  290. data/lib/graphql/types/relay/has_node_field.rb +2 -2
  291. data/lib/graphql/types/relay/has_nodes_field.rb +2 -2
  292. data/lib/graphql/types/relay/node_behaviors.rb +12 -2
  293. data/lib/graphql/types/relay/page_info_behaviors.rb +11 -2
  294. data/lib/graphql/types/relay.rb +0 -3
  295. data/lib/graphql/types/string.rb +2 -2
  296. data/lib/graphql/types.rb +18 -10
  297. data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
  298. data/lib/graphql/unauthorized_error.rb +1 -1
  299. data/lib/graphql/version.rb +1 -1
  300. data/lib/graphql.rb +82 -137
  301. data/readme.md +13 -6
  302. metadata +127 -186
  303. data/lib/graphql/analysis/analyze_query.rb +0 -98
  304. data/lib/graphql/analysis/ast/analyzer.rb +0 -84
  305. data/lib/graphql/analysis/ast/field_usage.rb +0 -28
  306. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -23
  307. data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
  308. data/lib/graphql/analysis/ast/query_complexity.rb +0 -234
  309. data/lib/graphql/analysis/ast/query_depth.rb +0 -56
  310. data/lib/graphql/analysis/ast/visitor.rb +0 -268
  311. data/lib/graphql/analysis/ast.rb +0 -91
  312. data/lib/graphql/analysis/reducer_state.rb +0 -48
  313. data/lib/graphql/argument.rb +0 -131
  314. data/lib/graphql/authorization.rb +0 -82
  315. data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
  316. data/lib/graphql/backwards_compatibility.rb +0 -61
  317. data/lib/graphql/base_type.rb +0 -230
  318. data/lib/graphql/boolean_type.rb +0 -2
  319. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  320. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  321. data/lib/graphql/compatibility/execution_specification.rb +0 -436
  322. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  323. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
  324. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  325. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  326. data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
  327. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
  328. data/lib/graphql/compatibility.rb +0 -5
  329. data/lib/graphql/define/assign_argument.rb +0 -12
  330. data/lib/graphql/define/assign_connection.rb +0 -13
  331. data/lib/graphql/define/assign_enum_value.rb +0 -18
  332. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  333. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  334. data/lib/graphql/define/assign_object_field.rb +0 -42
  335. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  336. data/lib/graphql/define/instance_definable.rb +0 -240
  337. data/lib/graphql/define/no_definition_error.rb +0 -7
  338. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  339. data/lib/graphql/define/type_definer.rb +0 -31
  340. data/lib/graphql/define.rb +0 -31
  341. data/lib/graphql/deprecated_dsl.rb +0 -47
  342. data/lib/graphql/deprecation.rb +0 -13
  343. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  344. data/lib/graphql/directive/include_directive.rb +0 -2
  345. data/lib/graphql/directive/skip_directive.rb +0 -2
  346. data/lib/graphql/directive.rb +0 -111
  347. data/lib/graphql/enum_type.rb +0 -129
  348. data/lib/graphql/execution/execute.rb +0 -333
  349. data/lib/graphql/execution/flatten.rb +0 -40
  350. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  351. data/lib/graphql/execution/typecast.rb +0 -50
  352. data/lib/graphql/field/resolve.rb +0 -59
  353. data/lib/graphql/field.rb +0 -226
  354. data/lib/graphql/filter.rb +0 -53
  355. data/lib/graphql/float_type.rb +0 -2
  356. data/lib/graphql/function.rb +0 -128
  357. data/lib/graphql/id_type.rb +0 -2
  358. data/lib/graphql/input_object_type.rb +0 -138
  359. data/lib/graphql/int_type.rb +0 -2
  360. data/lib/graphql/interface_type.rb +0 -72
  361. data/lib/graphql/internal_representation/document.rb +0 -27
  362. data/lib/graphql/internal_representation/node.rb +0 -206
  363. data/lib/graphql/internal_representation/print.rb +0 -51
  364. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  365. data/lib/graphql/internal_representation/scope.rb +0 -88
  366. data/lib/graphql/internal_representation/visit.rb +0 -36
  367. data/lib/graphql/internal_representation.rb +0 -7
  368. data/lib/graphql/language/lexer.rl +0 -262
  369. data/lib/graphql/language/parser.y +0 -543
  370. data/lib/graphql/language/token.rb +0 -38
  371. data/lib/graphql/list_type.rb +0 -80
  372. data/lib/graphql/non_null_type.rb +0 -71
  373. data/lib/graphql/object_type.rb +0 -130
  374. data/lib/graphql/query/arguments.rb +0 -189
  375. data/lib/graphql/query/arguments_cache.rb +0 -24
  376. data/lib/graphql/query/executor.rb +0 -52
  377. data/lib/graphql/query/literal_input.rb +0 -136
  378. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  379. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  380. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  381. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  382. data/lib/graphql/query/serial_execution.rb +0 -40
  383. data/lib/graphql/relay/array_connection.rb +0 -83
  384. data/lib/graphql/relay/base_connection.rb +0 -189
  385. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  386. data/lib/graphql/relay/connection_resolve.rb +0 -43
  387. data/lib/graphql/relay/connection_type.rb +0 -41
  388. data/lib/graphql/relay/edge.rb +0 -27
  389. data/lib/graphql/relay/edge_type.rb +0 -19
  390. data/lib/graphql/relay/edges_instrumentation.rb +0 -40
  391. data/lib/graphql/relay/global_id_resolve.rb +0 -18
  392. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  393. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  394. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  395. data/lib/graphql/relay/mutation/result.rb +0 -38
  396. data/lib/graphql/relay/mutation.rb +0 -106
  397. data/lib/graphql/relay/node.rb +0 -39
  398. data/lib/graphql/relay/page_info.rb +0 -7
  399. data/lib/graphql/relay/relation_connection.rb +0 -188
  400. data/lib/graphql/relay/type_extensions.rb +0 -32
  401. data/lib/graphql/scalar_type.rb +0 -91
  402. data/lib/graphql/schema/base_64_bp.rb +0 -26
  403. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  404. data/lib/graphql/schema/default_parse_error.rb +0 -10
  405. data/lib/graphql/schema/default_type_error.rb +0 -17
  406. data/lib/graphql/schema/invalid_type_error.rb +0 -7
  407. data/lib/graphql/schema/member/accepts_definition.rb +0 -152
  408. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -31
  409. data/lib/graphql/schema/member/instrumentation.rb +0 -131
  410. data/lib/graphql/schema/middleware_chain.rb +0 -82
  411. data/lib/graphql/schema/possible_types.rb +0 -44
  412. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  413. data/lib/graphql/schema/timeout_middleware.rb +0 -88
  414. data/lib/graphql/schema/traversal.rb +0 -228
  415. data/lib/graphql/schema/validation.rb +0 -313
  416. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  417. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  418. data/lib/graphql/static_validation/type_stack.rb +0 -216
  419. data/lib/graphql/string_type.rb +0 -2
  420. data/lib/graphql/subscriptions/instrumentation.rb +0 -79
  421. data/lib/graphql/subscriptions/subscription_root.rb +0 -76
  422. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  423. data/lib/graphql/types/relay/default_relay.rb +0 -27
  424. data/lib/graphql/types/relay/node_field.rb +0 -25
  425. data/lib/graphql/types/relay/nodes_field.rb +0 -27
  426. data/lib/graphql/union_type.rb +0 -115
  427. data/lib/graphql/upgrader/member.rb +0 -937
  428. data/lib/graphql/upgrader/schema.rb +0 -38
@@ -0,0 +1,253 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "graphql/tracing/platform_trace"
4
+
5
+ module GraphQL
6
+ module Tracing
7
+
8
+ # This class uses the AppopticsAPM SDK from the appoptics_apm gem to create
9
+ # traces for GraphQL.
10
+ #
11
+ # There are 4 configurations available. They can be set in the
12
+ # appoptics_apm config file or in code. Please see:
13
+ # {https://docs.appoptics.com/kb/apm_tracing/ruby/configure}
14
+ #
15
+ # AppOpticsAPM::Config[:graphql][:enabled] = true|false
16
+ # AppOpticsAPM::Config[:graphql][:transaction_name] = true|false
17
+ # AppOpticsAPM::Config[:graphql][:sanitize_query] = true|false
18
+ # AppOpticsAPM::Config[:graphql][:remove_comments] = true|false
19
+ module AppOpticsTrace
20
+ # These GraphQL events will show up as 'graphql.prep' spans
21
+ PREP_KEYS = ['lex', 'parse', 'validate', 'analyze_query', 'analyze_multiplex'].freeze
22
+ # These GraphQL events will show up as 'graphql.execute' spans
23
+ EXEC_KEYS = ['execute_multiplex', 'execute_query', 'execute_query_lazy'].freeze
24
+
25
+ # During auto-instrumentation this version of AppOpticsTracing is compared
26
+ # with the version provided in the appoptics_apm gem, so that the newer
27
+ # version of the class can be used
28
+
29
+ def self.version
30
+ Gem::Version.new('1.0.0')
31
+ end
32
+
33
+ [
34
+ 'lex',
35
+ 'parse',
36
+ 'validate',
37
+ 'analyze_query',
38
+ 'analyze_multiplex',
39
+ 'execute_multiplex',
40
+ 'execute_query',
41
+ 'execute_query_lazy',
42
+ ].each do |trace_method|
43
+ module_eval <<-RUBY, __FILE__, __LINE__
44
+ def #{trace_method}(**data)
45
+ return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
46
+ layer = span_name("#{trace_method}")
47
+ kvs = metadata(data, layer)
48
+ kvs[:Key] = "#{trace_method}" if (PREP_KEYS + EXEC_KEYS).include?("#{trace_method}")
49
+
50
+ transaction_name(kvs[:InboundQuery]) if kvs[:InboundQuery] && layer == 'graphql.execute'
51
+
52
+ ::AppOpticsAPM::SDK.trace(layer, kvs) do
53
+ kvs.clear # we don't have to send them twice
54
+ super
55
+ end
56
+ end
57
+ RUBY
58
+ end
59
+
60
+ def execute_field(query:, field:, ast_node:, arguments:, object:)
61
+ return_type = field.type.unwrap
62
+ trace_field = if return_type.kind.scalar? || return_type.kind.enum?
63
+ (field.trace.nil? && @trace_scalars) || field.trace
64
+ else
65
+ true
66
+ end
67
+ platform_key = if trace_field
68
+ @platform_key_cache[AppOpticsTrace].platform_field_key_cache[field]
69
+ else
70
+ nil
71
+ end
72
+ if platform_key && trace_field
73
+ return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
74
+ layer = platform_key
75
+ kvs = metadata({query: query, field: field, ast_node: ast_node, arguments: arguments, object: object}, layer)
76
+
77
+ ::AppOpticsAPM::SDK.trace(layer, kvs) do
78
+ kvs.clear # we don't have to send them twice
79
+ super
80
+ end
81
+ else
82
+ super
83
+ end
84
+ end
85
+
86
+ def execute_field_lazy(query:, field:, ast_node:, arguments:, object:)
87
+ execute_field(query: query, field: field, ast_node: ast_node, arguments: arguments, object: object)
88
+ end
89
+
90
+ def authorized(**data)
91
+ return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
92
+ layer = @platform_key_cache[AppOpticsTrace].platform_authorized_key_cache[data[:type]]
93
+ kvs = metadata(data, layer)
94
+
95
+ ::AppOpticsAPM::SDK.trace(layer, kvs) do
96
+ kvs.clear # we don't have to send them twice
97
+ super
98
+ end
99
+ end
100
+
101
+ def authorized_lazy(**data)
102
+ return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
103
+ layer = @platform_key_cache[AppOpticsTrace].platform_authorized_key_cache[data[:type]]
104
+ kvs = metadata(data, layer)
105
+
106
+ ::AppOpticsAPM::SDK.trace(layer, kvs) do
107
+ kvs.clear # we don't have to send them twice
108
+ super
109
+ end
110
+ end
111
+
112
+ def resolve_type(**data)
113
+ return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
114
+ layer = @platform_key_cache[AppOpticsTrace].platform_resolve_type_key_cache[data[:type]]
115
+
116
+ kvs = metadata(data, layer)
117
+
118
+ ::AppOpticsAPM::SDK.trace(layer, kvs) do
119
+ kvs.clear # we don't have to send them twice
120
+ super
121
+ end
122
+ end
123
+
124
+ def resolve_type_lazy(**data)
125
+ return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
126
+ layer = @platform_key_cache[AppOpticsTrace].platform_resolve_type_key_cache[data[:type]]
127
+ kvs = metadata(data, layer)
128
+
129
+ ::AppOpticsAPM::SDK.trace(layer, kvs) do
130
+ kvs.clear # we don't have to send them twice
131
+ super
132
+ end
133
+ end
134
+
135
+ include PlatformTrace
136
+
137
+ def platform_field_key(field)
138
+ "graphql.#{field.owner.graphql_name}.#{field.graphql_name}"
139
+ end
140
+
141
+ def platform_authorized_key(type)
142
+ "graphql.authorized.#{type.graphql_name}"
143
+ end
144
+
145
+ def platform_resolve_type_key(type)
146
+ "graphql.resolve_type.#{type.graphql_name}"
147
+ end
148
+
149
+ private
150
+
151
+ def gql_config
152
+ ::AppOpticsAPM::Config[:graphql] ||= {}
153
+ end
154
+
155
+ def transaction_name(query)
156
+ return if gql_config[:transaction_name] == false ||
157
+ ::AppOpticsAPM::SDK.get_transaction_name
158
+
159
+ split_query = query.strip.split(/\W+/, 3)
160
+ split_query[0] = 'query' if split_query[0].empty?
161
+ name = "graphql.#{split_query[0..1].join('.')}"
162
+
163
+ ::AppOpticsAPM::SDK.set_transaction_name(name)
164
+ end
165
+
166
+ def multiplex_transaction_name(names)
167
+ return if gql_config[:transaction_name] == false ||
168
+ ::AppOpticsAPM::SDK.get_transaction_name
169
+
170
+ name = "graphql.multiplex.#{names.join('.')}"
171
+ name = "#{name[0..251]}..." if name.length > 254
172
+
173
+ ::AppOpticsAPM::SDK.set_transaction_name(name)
174
+ end
175
+
176
+ def span_name(key)
177
+ return 'graphql.prep' if PREP_KEYS.include?(key)
178
+ return 'graphql.execute' if EXEC_KEYS.include?(key)
179
+
180
+ key[/^graphql\./] ? key : "graphql.#{key}"
181
+ end
182
+
183
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
184
+ def metadata(data, layer)
185
+ data.keys.map do |key|
186
+ case key
187
+ when :context
188
+ graphql_context(data[key], layer)
189
+ when :query
190
+ graphql_query(data[key])
191
+ when :query_string
192
+ graphql_query_string(data[key])
193
+ when :multiplex
194
+ graphql_multiplex(data[key])
195
+ when :path
196
+ [key, data[key].join(".")]
197
+ else
198
+ [key, data[key]]
199
+ end
200
+ end.tap { _1.flatten!(2) }.each_slice(2).to_h.merge(Spec: 'graphql')
201
+ end
202
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
203
+
204
+ def graphql_context(context, layer)
205
+ context.errors && context.errors.each do |err|
206
+ AppOpticsAPM::API.log_exception(layer, err)
207
+ end
208
+
209
+ [[:Path, context.path.join('.')]]
210
+ end
211
+
212
+ def graphql_query(query)
213
+ return [] unless query
214
+
215
+ query_string = query.query_string
216
+ query_string = remove_comments(query_string) if gql_config[:remove_comments] != false
217
+ query_string = sanitize(query_string) if gql_config[:sanitize_query] != false
218
+
219
+ [[:InboundQuery, query_string],
220
+ [:Operation, query.selected_operation_name]]
221
+ end
222
+
223
+ def graphql_query_string(query_string)
224
+ query_string = remove_comments(query_string) if gql_config[:remove_comments] != false
225
+ query_string = sanitize(query_string) if gql_config[:sanitize_query] != false
226
+
227
+ [:InboundQuery, query_string]
228
+ end
229
+
230
+ def graphql_multiplex(data)
231
+ names = data.queries.map(&:operations).map!(&:keys).tap(&:flatten!).tap(&:compact!)
232
+ multiplex_transaction_name(names) if names.size > 1
233
+
234
+ [:Operations, names.join(', ')]
235
+ end
236
+
237
+ def sanitize(query)
238
+ return unless query
239
+
240
+ # remove arguments
241
+ query.gsub(/"[^"]*"/, '"?"') # strings
242
+ .gsub(/-?[0-9]*\.?[0-9]+e?[0-9]*/, '?') # ints + floats
243
+ .gsub(/\[[^\]]*\]/, '[?]') # arrays
244
+ end
245
+
246
+ def remove_comments(query)
247
+ return unless query
248
+
249
+ query.gsub(/#[^\n\r]*/, '')
250
+ end
251
+ end
252
+ end
253
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_tracing"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
 
@@ -117,7 +119,7 @@ module GraphQL
117
119
  else
118
120
  [key, data[key]]
119
121
  end
120
- end.flatten(2).each_slice(2).to_h.merge(Spec: 'graphql')
122
+ end.tap { _1.flatten!(2) }.each_slice(2).to_h.merge(Spec: 'graphql')
121
123
  end
122
124
  # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
123
125
 
@@ -148,7 +150,7 @@ module GraphQL
148
150
  end
149
151
 
150
152
  def graphql_multiplex(data)
151
- names = data.queries.map(&:operations).map(&:keys).flatten.compact
153
+ names = data.queries.map(&:operations).map!(&:keys).tap(&:flatten!).tap(&:compact!)
152
154
  multiplex_transaction_name(names) if names.size > 1
153
155
 
154
156
  [:Operations, names.join(', ')]
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "graphql/tracing/platform_trace"
4
+
5
+ module GraphQL
6
+ module Tracing
7
+ module AppsignalTrace
8
+ include PlatformTrace
9
+
10
+ # @param set_action_name [Boolean] If true, the GraphQL operation name will be used as the transaction name.
11
+ # This is not advised if you run more than one query per HTTP request, for example, with `graphql-client` or multiplexing.
12
+ # It can also be specified per-query with `context[:set_appsignal_action_name]`.
13
+ def initialize(set_action_name: false, **rest)
14
+ @set_action_name = set_action_name
15
+ super
16
+ end
17
+
18
+ {
19
+ "lex" => "lex.graphql",
20
+ "parse" => "parse.graphql",
21
+ "validate" => "validate.graphql",
22
+ "analyze_query" => "analyze.graphql",
23
+ "analyze_multiplex" => "analyze.graphql",
24
+ "execute_multiplex" => "execute.graphql",
25
+ "execute_query" => "execute.graphql",
26
+ "execute_query_lazy" => "execute.graphql",
27
+ }.each do |trace_method, platform_key|
28
+ module_eval <<-RUBY, __FILE__, __LINE__
29
+ def #{trace_method}(**data)
30
+ #{
31
+ if trace_method == "execute_query"
32
+ <<-RUBY
33
+ set_this_txn_name = data[:query].context[:set_appsignal_action_name]
34
+ if set_this_txn_name == true || (set_this_txn_name.nil? && @set_action_name)
35
+ Appsignal::Transaction.current.set_action(transaction_name(data[:query]))
36
+ end
37
+ RUBY
38
+ end
39
+ }
40
+
41
+ Appsignal.instrument("#{platform_key}") do
42
+ super
43
+ end
44
+ end
45
+ RUBY
46
+ end
47
+
48
+ def platform_execute_field(platform_key)
49
+ Appsignal.instrument(platform_key) do
50
+ yield
51
+ end
52
+ end
53
+
54
+ def platform_authorized(platform_key)
55
+ Appsignal.instrument(platform_key) do
56
+ yield
57
+ end
58
+ end
59
+
60
+ def platform_resolve_type(platform_key)
61
+ Appsignal.instrument(platform_key) do
62
+ yield
63
+ end
64
+ end
65
+
66
+ def platform_field_key(field)
67
+ "#{field.owner.graphql_name}.#{field.graphql_name}.graphql"
68
+ end
69
+
70
+ def platform_authorized_key(type)
71
+ "#{type.graphql_name}.authorized.graphql"
72
+ end
73
+
74
+ def platform_resolve_type_key(type)
75
+ "#{type.graphql_name}.resolve_type.graphql"
76
+ end
77
+ end
78
+ end
79
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_tracing"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
  class AppsignalTracing < PlatformTracing
@@ -14,7 +16,22 @@ module GraphQL
14
16
  "execute_query_lazy" => "execute.graphql",
15
17
  }
16
18
 
19
+ # @param set_action_name [Boolean] If true, the GraphQL operation name will be used as the transaction name.
20
+ # This is not advised if you run more than one query per HTTP request, for example, with `graphql-client` or multiplexing.
21
+ # It can also be specified per-query with `context[:set_appsignal_action_name]`.
22
+ def initialize(options = {})
23
+ @set_action_name = options.fetch(:set_action_name, false)
24
+ super
25
+ end
26
+
17
27
  def platform_trace(platform_key, key, data)
28
+ if key == "execute_query"
29
+ set_this_txn_name = data[:query].context[:set_appsignal_action_name]
30
+ if set_this_txn_name == true || (set_this_txn_name.nil? && @set_action_name)
31
+ Appsignal::Transaction.current.set_action(transaction_name(data[:query]))
32
+ end
33
+ end
34
+
18
35
  Appsignal.instrument(platform_key) do
19
36
  yield
20
37
  end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ module Tracing
5
+ # This trace class calls legacy-style tracer with payload hashes.
6
+ # New-style `trace_with` modules significantly reduce the overhead of tracing,
7
+ # but that advantage is lost when legacy-style tracers are also used (since the payload hashes are still constructed).
8
+ module CallLegacyTracers
9
+ def lex(query_string:)
10
+ (@multiplex || @query).trace("lex", { query_string: query_string }) { super }
11
+ end
12
+
13
+ def parse(query_string:)
14
+ (@multiplex || @query).trace("parse", { query_string: query_string }) { super }
15
+ end
16
+
17
+ def validate(query:, validate:)
18
+ query.trace("validate", { validate: validate, query: query }) { super }
19
+ end
20
+
21
+ def analyze_multiplex(multiplex:)
22
+ multiplex.trace("analyze_multiplex", { multiplex: multiplex }) { super }
23
+ end
24
+
25
+ def analyze_query(query:)
26
+ query.trace("analyze_query", { query: query }) { super }
27
+ end
28
+
29
+ def execute_multiplex(multiplex:)
30
+ multiplex.trace("execute_multiplex", { multiplex: multiplex }) { super }
31
+ end
32
+
33
+ def execute_query(query:)
34
+ query.trace("execute_query", { query: query }) { super }
35
+ end
36
+
37
+ def execute_query_lazy(query:, multiplex:)
38
+ multiplex.trace("execute_query_lazy", { multiplex: multiplex, query: query }) { super }
39
+ end
40
+
41
+ def execute_field(field:, query:, ast_node:, arguments:, object:)
42
+ query.trace("execute_field", { field: field, query: query, ast_node: ast_node, arguments: arguments, object: object, owner: field.owner, path: query.context[:current_path] }) { super }
43
+ end
44
+
45
+ def execute_field_lazy(field:, query:, ast_node:, arguments:, object:)
46
+ query.trace("execute_field_lazy", { field: field, query: query, ast_node: ast_node, arguments: arguments, object: object, owner: field.owner, path: query.context[:current_path] }) { super }
47
+ end
48
+
49
+ def authorized(query:, type:, object:)
50
+ query.trace("authorized", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
51
+ end
52
+
53
+ def authorized_lazy(query:, type:, object:)
54
+ query.trace("authorized_lazy", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
55
+ end
56
+
57
+ def resolve_type(query:, type:, object:)
58
+ query.trace("resolve_type", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
59
+ end
60
+
61
+ def resolve_type_lazy(query:, type:, object:)
62
+ query.trace("resolve_type_lazy", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,185 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "graphql/tracing/platform_trace"
4
+
5
+ module GraphQL
6
+ module Tracing
7
+ module DataDogTrace
8
+ # @param tracer [#trace] Deprecated
9
+ # @param analytics_enabled [Boolean] Deprecated
10
+ # @param analytics_sample_rate [Float] Deprecated
11
+ def initialize(tracer: nil, analytics_enabled: false, analytics_sample_rate: 1.0, service: nil, **rest)
12
+ if tracer.nil?
13
+ tracer = defined?(Datadog::Tracing) ? Datadog::Tracing : Datadog.tracer
14
+ end
15
+ @tracer = tracer
16
+
17
+ @analytics_enabled = analytics_enabled
18
+ @analytics_sample_rate = analytics_sample_rate
19
+
20
+ @service_name = service
21
+ @has_prepare_span = respond_to?(:prepare_span)
22
+ super
23
+ end
24
+
25
+ {
26
+ 'lex' => 'lex.graphql',
27
+ 'parse' => 'parse.graphql',
28
+ 'validate' => 'validate.graphql',
29
+ 'analyze_query' => 'analyze.graphql',
30
+ 'analyze_multiplex' => 'analyze.graphql',
31
+ 'execute_multiplex' => 'execute.graphql',
32
+ 'execute_query' => 'execute.graphql',
33
+ 'execute_query_lazy' => 'execute.graphql',
34
+ }.each do |trace_method, trace_key|
35
+ module_eval <<-RUBY, __FILE__, __LINE__
36
+ def #{trace_method}(**data)
37
+ @tracer.trace("#{trace_key}", service: @service_name, type: 'custom') do |span|
38
+ span.set_tag('component', 'graphql')
39
+ span.set_tag('operation', '#{trace_method}')
40
+
41
+ #{
42
+ if trace_method == 'execute_multiplex'
43
+ <<-RUBY
44
+ operations = data[:multiplex].queries.map(&:selected_operation_name).join(', ')
45
+
46
+ resource = if operations.empty?
47
+ first_query = data[:multiplex].queries.first
48
+ fallback_transaction_name(first_query && first_query.context)
49
+ else
50
+ operations
51
+ end
52
+ span.resource = resource if resource
53
+
54
+ # [Deprecated] will be removed in the future
55
+ span.set_metric('_dd1.sr.eausr', @analytics_sample_rate) if @analytics_enabled
56
+ RUBY
57
+ elsif trace_method == 'execute_query'
58
+ <<-RUBY
59
+ span.set_tag(:selected_operation_name, data[:query].selected_operation_name)
60
+ span.set_tag(:selected_operation_type, data[:query].selected_operation.operation_type)
61
+ span.set_tag(:query_string, data[:query].query_string)
62
+ RUBY
63
+ end
64
+ }
65
+ if @has_prepare_span
66
+ prepare_span("#{trace_method.sub("platform_", "")}", data, span)
67
+ end
68
+ super
69
+ end
70
+ end
71
+ RUBY
72
+ end
73
+
74
+ def execute_field_span(span_key, query, field, ast_node, arguments, object)
75
+ return_type = field.type.unwrap
76
+ trace_field = if return_type.kind.scalar? || return_type.kind.enum?
77
+ (field.trace.nil? && @trace_scalars) || field.trace
78
+ else
79
+ true
80
+ end
81
+ platform_key = if trace_field
82
+ @platform_key_cache[DataDogTrace].platform_field_key_cache[field]
83
+ else
84
+ nil
85
+ end
86
+ if platform_key && trace_field
87
+ @tracer.trace(platform_key, service: @service_name, type: 'custom') do |span|
88
+ span.set_tag('component', 'graphql')
89
+ span.set_tag('operation', span_key)
90
+
91
+ if @has_prepare_span
92
+ prepare_span_data = { query: query, field: field, ast_node: ast_node, arguments: arguments, object: object }
93
+ prepare_span(span_key, prepare_span_data, span)
94
+ end
95
+ yield
96
+ end
97
+ else
98
+ yield
99
+ end
100
+ end
101
+ def execute_field(query:, field:, ast_node:, arguments:, object:)
102
+ execute_field_span("execute_field", query, field, ast_node, arguments, object) do
103
+ super(query: query, field: field, ast_node: ast_node, arguments: arguments, object: object)
104
+ end
105
+ end
106
+
107
+ def execute_field_lazy(query:, field:, ast_node:, arguments:, object:)
108
+ execute_field_span("execute_field_lazy", query, field, ast_node, arguments, object) do
109
+ super(query: query, field: field, ast_node: ast_node, arguments: arguments, object: object)
110
+ end
111
+ end
112
+
113
+ def authorized(query:, type:, object:)
114
+ authorized_span("authorized", object, type, query) do
115
+ super(query: query, type: type, object: object)
116
+ end
117
+ end
118
+
119
+ def authorized_span(span_key, object, type, query)
120
+ platform_key = @platform_key_cache[DataDogTrace].platform_authorized_key_cache[type]
121
+ @tracer.trace(platform_key, service: @service_name, type: 'custom') do |span|
122
+ span.set_tag('component', 'graphql')
123
+ span.set_tag('operation', span_key)
124
+
125
+ if @has_prepare_span
126
+ prepare_span(span_key, {object: object, type: type, query: query}, span)
127
+ end
128
+ yield
129
+ end
130
+ end
131
+
132
+ def authorized_lazy(object:, type:, query:)
133
+ authorized_span("authorized_lazy", object, type, query) do
134
+ super(query: query, type: type, object: object)
135
+ end
136
+ end
137
+
138
+ def resolve_type(object:, type:, query:)
139
+ resolve_type_span("resolve_type", object, type, query) do
140
+ super(object: object, query: query, type: type)
141
+ end
142
+ end
143
+
144
+ def resolve_type_lazy(object:, type:, query:)
145
+ resolve_type_span("resolve_type_lazy", object, type, query) do
146
+ super(object: object, query: query, type: type)
147
+ end
148
+ end
149
+
150
+ def resolve_type_span(span_key, object, type, query)
151
+ platform_key = @platform_key_cache[DataDogTrace].platform_resolve_type_key_cache[type]
152
+ @tracer.trace(platform_key, service: @service_name, type: 'custom') do |span|
153
+ span.set_tag('component', 'graphql')
154
+ span.set_tag('operation', span_key)
155
+
156
+ if @has_prepare_span
157
+ prepare_span(span_key, {object: object, type: type, query: query}, span)
158
+ end
159
+ yield
160
+ end
161
+ end
162
+
163
+ include PlatformTrace
164
+
165
+ # Implement this method in a subclass to apply custom tags to datadog spans
166
+ # @param key [String] The event being traced
167
+ # @param data [Hash] The runtime data for this event (@see GraphQL::Tracing for keys for each event)
168
+ # @param span [Datadog::Tracing::SpanOperation] The datadog span for this event
169
+ # def prepare_span(key, data, span)
170
+ # end
171
+
172
+ def platform_field_key(field)
173
+ field.path
174
+ end
175
+
176
+ def platform_authorized_key(type)
177
+ "#{type.graphql_name}.authorized"
178
+ end
179
+
180
+ def platform_resolve_type_key(type)
181
+ "#{type.graphql_name}.resolve_type"
182
+ end
183
+ end
184
+ end
185
+ end