graphql 1.10.2 → 2.0.21

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