graphql 2.0.32 → 2.5.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (308) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/detailed_trace_generator.rb +77 -0
  3. data/lib/generators/graphql/install/mutation_root_generator.rb +2 -2
  4. data/lib/generators/graphql/install/templates/base_mutation.erb +2 -0
  5. data/lib/generators/graphql/install/templates/mutation_type.erb +2 -0
  6. data/lib/generators/graphql/install_generator.rb +49 -0
  7. data/lib/generators/graphql/orm_mutations_base.rb +1 -1
  8. data/lib/generators/graphql/templates/base_argument.erb +2 -0
  9. data/lib/generators/graphql/templates/base_connection.erb +2 -0
  10. data/lib/generators/graphql/templates/base_edge.erb +2 -0
  11. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  12. data/lib/generators/graphql/templates/base_field.erb +2 -0
  13. data/lib/generators/graphql/templates/base_input_object.erb +2 -0
  14. data/lib/generators/graphql/templates/base_interface.erb +2 -0
  15. data/lib/generators/graphql/templates/base_object.erb +2 -0
  16. data/lib/generators/graphql/templates/base_resolver.erb +8 -0
  17. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  18. data/lib/generators/graphql/templates/base_union.erb +2 -0
  19. data/lib/generators/graphql/templates/create_graphql_detailed_traces.erb +10 -0
  20. data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
  21. data/lib/generators/graphql/templates/loader.erb +2 -0
  22. data/lib/generators/graphql/templates/mutation.erb +2 -0
  23. data/lib/generators/graphql/templates/node_type.erb +2 -0
  24. data/lib/generators/graphql/templates/query_type.erb +2 -0
  25. data/lib/generators/graphql/templates/schema.erb +5 -0
  26. data/lib/generators/graphql/type_generator.rb +1 -1
  27. data/lib/graphql/analysis/analyzer.rb +90 -0
  28. data/lib/graphql/analysis/field_usage.rb +82 -0
  29. data/lib/graphql/analysis/max_query_complexity.rb +20 -0
  30. data/lib/graphql/analysis/max_query_depth.rb +20 -0
  31. data/lib/graphql/analysis/query_complexity.rb +263 -0
  32. data/lib/graphql/analysis/query_depth.rb +58 -0
  33. data/lib/graphql/analysis/visitor.rb +280 -0
  34. data/lib/graphql/analysis.rb +95 -1
  35. data/lib/graphql/autoload.rb +38 -0
  36. data/lib/graphql/backtrace/table.rb +118 -55
  37. data/lib/graphql/backtrace.rb +1 -19
  38. data/lib/graphql/coercion_error.rb +1 -9
  39. data/lib/graphql/current.rb +57 -0
  40. data/lib/graphql/dashboard/application_controller.rb +41 -0
  41. data/lib/graphql/dashboard/detailed_traces.rb +47 -0
  42. data/lib/graphql/dashboard/installable.rb +22 -0
  43. data/lib/graphql/dashboard/landings_controller.rb +9 -0
  44. data/lib/graphql/dashboard/limiters.rb +93 -0
  45. data/lib/graphql/dashboard/operation_store.rb +199 -0
  46. data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.css +6 -0
  47. data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.js +7 -0
  48. data/lib/graphql/dashboard/statics/charts.min.css +1 -0
  49. data/lib/graphql/dashboard/statics/dashboard.css +30 -0
  50. data/lib/graphql/dashboard/statics/dashboard.js +143 -0
  51. data/lib/graphql/dashboard/statics/header-icon.png +0 -0
  52. data/lib/graphql/dashboard/statics/icon.png +0 -0
  53. data/lib/graphql/dashboard/statics_controller.rb +31 -0
  54. data/lib/graphql/dashboard/subscriptions.rb +97 -0
  55. data/lib/graphql/dashboard/views/graphql/dashboard/detailed_traces/traces/index.html.erb +45 -0
  56. data/lib/graphql/dashboard/views/graphql/dashboard/landings/show.html.erb +18 -0
  57. data/lib/graphql/dashboard/views/graphql/dashboard/limiters/limiters/show.html.erb +62 -0
  58. data/lib/graphql/dashboard/views/graphql/dashboard/not_installed.html.erb +18 -0
  59. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/_form.html.erb +24 -0
  60. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/edit.html.erb +21 -0
  61. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/index.html.erb +69 -0
  62. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/new.html.erb +7 -0
  63. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/index.html.erb +39 -0
  64. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/show.html.erb +32 -0
  65. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/index.html.erb +81 -0
  66. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/show.html.erb +71 -0
  67. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/subscriptions/show.html.erb +41 -0
  68. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/index.html.erb +55 -0
  69. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/show.html.erb +40 -0
  70. data/lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb +108 -0
  71. data/lib/graphql/dashboard.rb +96 -0
  72. data/lib/graphql/dataloader/active_record_association_source.rb +84 -0
  73. data/lib/graphql/dataloader/active_record_source.rb +47 -0
  74. data/lib/graphql/dataloader/async_dataloader.rb +112 -0
  75. data/lib/graphql/dataloader/null_dataloader.rb +55 -10
  76. data/lib/graphql/dataloader/request.rb +5 -0
  77. data/lib/graphql/dataloader/source.rb +35 -12
  78. data/lib/graphql/dataloader.rb +224 -149
  79. data/lib/graphql/date_encoding_error.rb +1 -1
  80. data/lib/graphql/dig.rb +2 -1
  81. data/lib/graphql/duration_encoding_error.rb +16 -0
  82. data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
  83. data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
  84. data/lib/graphql/execution/interpreter/resolve.rb +23 -25
  85. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +228 -0
  86. data/lib/graphql/execution/interpreter/runtime.rb +363 -434
  87. data/lib/graphql/execution/interpreter.rb +91 -164
  88. data/lib/graphql/execution/lookahead.rb +105 -31
  89. data/lib/graphql/execution/multiplex.rb +7 -6
  90. data/lib/graphql/execution/next/field_resolve_step.rb +711 -0
  91. data/lib/graphql/execution/next/load_argument_step.rb +60 -0
  92. data/lib/graphql/execution/next/prepare_object_step.rb +129 -0
  93. data/lib/graphql/execution/next/runner.rb +389 -0
  94. data/lib/graphql/execution/next/selections_step.rb +37 -0
  95. data/lib/graphql/execution/next.rb +70 -0
  96. data/lib/graphql/execution.rb +1 -0
  97. data/lib/graphql/execution_error.rb +13 -10
  98. data/lib/graphql/introspection/directive_location_enum.rb +1 -1
  99. data/lib/graphql/introspection/directive_type.rb +7 -3
  100. data/lib/graphql/introspection/dynamic_fields.rb +5 -1
  101. data/lib/graphql/introspection/entry_points.rb +20 -6
  102. data/lib/graphql/introspection/enum_value_type.rb +5 -5
  103. data/lib/graphql/introspection/field_type.rb +13 -5
  104. data/lib/graphql/introspection/input_value_type.rb +21 -13
  105. data/lib/graphql/introspection/schema_type.rb +8 -11
  106. data/lib/graphql/introspection/type_type.rb +64 -28
  107. data/lib/graphql/invalid_name_error.rb +1 -1
  108. data/lib/graphql/invalid_null_error.rb +26 -17
  109. data/lib/graphql/language/block_string.rb +34 -18
  110. data/lib/graphql/language/cache.rb +13 -0
  111. data/lib/graphql/language/comment.rb +18 -0
  112. data/lib/graphql/language/definition_slice.rb +1 -1
  113. data/lib/graphql/language/document_from_schema_definition.rb +90 -61
  114. data/lib/graphql/language/lexer.rb +319 -193
  115. data/lib/graphql/language/nodes.rb +136 -77
  116. data/lib/graphql/language/parser.rb +807 -1985
  117. data/lib/graphql/language/printer.rb +324 -151
  118. data/lib/graphql/language/sanitized_printer.rb +21 -23
  119. data/lib/graphql/language/static_visitor.rb +171 -0
  120. data/lib/graphql/language/visitor.rb +23 -83
  121. data/lib/graphql/language.rb +71 -1
  122. data/lib/graphql/load_application_object_failed_error.rb +5 -1
  123. data/lib/graphql/pagination/array_connection.rb +6 -6
  124. data/lib/graphql/pagination/connection.rb +30 -1
  125. data/lib/graphql/pagination/connections.rb +32 -0
  126. data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
  127. data/lib/graphql/query/context/scoped_context.rb +101 -0
  128. data/lib/graphql/query/context.rb +82 -144
  129. data/lib/graphql/query/null_context.rb +15 -18
  130. data/lib/graphql/query/partial.rb +179 -0
  131. data/lib/graphql/query/validation_pipeline.rb +4 -4
  132. data/lib/graphql/query/variable_validation_error.rb +1 -1
  133. data/lib/graphql/query/variables.rb +3 -3
  134. data/lib/graphql/query.rb +126 -81
  135. data/lib/graphql/railtie.rb +16 -6
  136. data/lib/graphql/rake_task.rb +3 -12
  137. data/lib/graphql/rubocop/graphql/base_cop.rb +1 -1
  138. data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
  139. data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
  140. data/lib/graphql/rubocop.rb +2 -0
  141. data/lib/graphql/schema/addition.rb +26 -13
  142. data/lib/graphql/schema/always_visible.rb +7 -2
  143. data/lib/graphql/schema/argument.rb +75 -9
  144. data/lib/graphql/schema/base_64_encoder.rb +3 -5
  145. data/lib/graphql/schema/build_from_definition.rb +123 -60
  146. data/lib/graphql/schema/directive/flagged.rb +4 -2
  147. data/lib/graphql/schema/directive/one_of.rb +12 -0
  148. data/lib/graphql/schema/directive/specified_by.rb +14 -0
  149. data/lib/graphql/schema/directive.rb +54 -2
  150. data/lib/graphql/schema/enum.rb +110 -27
  151. data/lib/graphql/schema/enum_value.rb +10 -2
  152. data/lib/graphql/schema/field/connection_extension.rb +15 -49
  153. data/lib/graphql/schema/field/scope_extension.rb +23 -7
  154. data/lib/graphql/schema/field.rb +245 -118
  155. data/lib/graphql/schema/field_extension.rb +34 -1
  156. data/lib/graphql/schema/has_single_input_argument.rb +160 -0
  157. data/lib/graphql/schema/input_object.rb +116 -60
  158. data/lib/graphql/schema/interface.rb +34 -16
  159. data/lib/graphql/schema/introspection_system.rb +8 -17
  160. data/lib/graphql/schema/late_bound_type.rb +4 -0
  161. data/lib/graphql/schema/list.rb +3 -3
  162. data/lib/graphql/schema/loader.rb +3 -4
  163. data/lib/graphql/schema/member/base_dsl_methods.rb +18 -2
  164. data/lib/graphql/schema/member/has_arguments.rb +132 -100
  165. data/lib/graphql/schema/member/has_authorization.rb +35 -0
  166. data/lib/graphql/schema/member/has_dataloader.rb +99 -0
  167. data/lib/graphql/schema/member/has_deprecation_reason.rb +15 -0
  168. data/lib/graphql/schema/member/has_directives.rb +4 -4
  169. data/lib/graphql/schema/member/has_fields.rb +115 -15
  170. data/lib/graphql/schema/member/has_interfaces.rb +26 -12
  171. data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
  172. data/lib/graphql/schema/member/has_validators.rb +1 -1
  173. data/lib/graphql/schema/member/relay_shortcuts.rb +1 -1
  174. data/lib/graphql/schema/member/scoped.rb +19 -0
  175. data/lib/graphql/schema/member/type_system_helpers.rb +17 -4
  176. data/lib/graphql/schema/member/validates_input.rb +3 -3
  177. data/lib/graphql/schema/member.rb +6 -0
  178. data/lib/graphql/schema/mutation.rb +7 -0
  179. data/lib/graphql/schema/object.rb +34 -8
  180. data/lib/graphql/schema/printer.rb +9 -7
  181. data/lib/graphql/schema/ractor_shareable.rb +79 -0
  182. data/lib/graphql/schema/relay_classic_mutation.rb +6 -129
  183. data/lib/graphql/schema/resolver.rb +90 -32
  184. data/lib/graphql/schema/scalar.rb +4 -9
  185. data/lib/graphql/schema/subscription.rb +63 -10
  186. data/lib/graphql/schema/timeout.rb +19 -2
  187. data/lib/graphql/schema/type_expression.rb +2 -2
  188. data/lib/graphql/schema/union.rb +2 -2
  189. data/lib/graphql/schema/unique_within_type.rb +1 -1
  190. data/lib/graphql/schema/validator/all_validator.rb +62 -0
  191. data/lib/graphql/schema/validator/required_validator.rb +92 -11
  192. data/lib/graphql/schema/validator.rb +3 -1
  193. data/lib/graphql/schema/visibility/migration.rb +188 -0
  194. data/lib/graphql/schema/visibility/profile.rb +445 -0
  195. data/lib/graphql/schema/visibility/visit.rb +190 -0
  196. data/lib/graphql/schema/visibility.rb +311 -0
  197. data/lib/graphql/schema/warden.rb +275 -103
  198. data/lib/graphql/schema.rb +950 -210
  199. data/lib/graphql/static_validation/all_rules.rb +3 -3
  200. data/lib/graphql/static_validation/base_visitor.rb +7 -6
  201. data/lib/graphql/static_validation/literal_validator.rb +6 -7
  202. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  203. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +1 -1
  204. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -2
  205. data/lib/graphql/static_validation/rules/directives_are_defined.rb +3 -3
  206. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -0
  207. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +12 -2
  208. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +47 -13
  209. data/lib/graphql/static_validation/rules/fields_will_merge.rb +88 -25
  210. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +10 -2
  211. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  212. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +12 -2
  213. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  214. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
  215. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
  216. data/lib/graphql/static_validation/rules/not_single_subscription_error.rb +25 -0
  217. data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
  218. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +5 -5
  219. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +5 -5
  220. data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +26 -0
  221. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +7 -3
  222. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
  223. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
  224. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
  225. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +11 -2
  226. data/lib/graphql/static_validation/validation_context.rb +21 -5
  227. data/lib/graphql/static_validation/validator.rb +9 -1
  228. data/lib/graphql/static_validation.rb +0 -1
  229. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +8 -5
  230. data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
  231. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +12 -10
  232. data/lib/graphql/subscriptions/event.rb +21 -4
  233. data/lib/graphql/subscriptions/serialize.rb +3 -1
  234. data/lib/graphql/subscriptions.rb +21 -17
  235. data/lib/graphql/testing/helpers.rb +161 -0
  236. data/lib/graphql/testing/mock_action_cable.rb +111 -0
  237. data/lib/graphql/testing.rb +3 -0
  238. data/lib/graphql/tracing/active_support_notifications_trace.rb +14 -3
  239. data/lib/graphql/tracing/active_support_notifications_tracing.rb +1 -1
  240. data/lib/graphql/tracing/appoptics_trace.rb +7 -3
  241. data/lib/graphql/tracing/appoptics_tracing.rb +9 -2
  242. data/lib/graphql/tracing/appsignal_trace.rb +32 -59
  243. data/lib/graphql/tracing/appsignal_tracing.rb +2 -0
  244. data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
  245. data/lib/graphql/tracing/data_dog_trace.rb +46 -162
  246. data/lib/graphql/tracing/data_dog_tracing.rb +2 -0
  247. data/lib/graphql/tracing/detailed_trace/active_record_backend.rb +74 -0
  248. data/lib/graphql/tracing/detailed_trace/memory_backend.rb +60 -0
  249. data/lib/graphql/tracing/detailed_trace/redis_backend.rb +72 -0
  250. data/lib/graphql/tracing/detailed_trace.rb +156 -0
  251. data/lib/graphql/tracing/legacy_hooks_trace.rb +75 -0
  252. data/lib/graphql/tracing/legacy_trace.rb +4 -61
  253. data/lib/graphql/tracing/monitor_trace.rb +283 -0
  254. data/lib/graphql/tracing/new_relic_trace.rb +47 -54
  255. data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
  256. data/lib/graphql/tracing/notifications_trace.rb +183 -37
  257. data/lib/graphql/tracing/notifications_tracing.rb +2 -0
  258. data/lib/graphql/tracing/null_trace.rb +9 -0
  259. data/lib/graphql/tracing/perfetto_trace/trace.proto +141 -0
  260. data/lib/graphql/tracing/perfetto_trace/trace_pb.rb +33 -0
  261. data/lib/graphql/tracing/perfetto_trace.rb +864 -0
  262. data/lib/graphql/tracing/platform_tracing.rb +3 -1
  263. data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +5 -1
  264. data/lib/graphql/tracing/prometheus_trace.rb +73 -73
  265. data/lib/graphql/tracing/prometheus_tracing.rb +2 -0
  266. data/lib/graphql/tracing/scout_trace.rb +32 -58
  267. data/lib/graphql/tracing/scout_tracing.rb +2 -0
  268. data/lib/graphql/tracing/sentry_trace.rb +82 -0
  269. data/lib/graphql/tracing/statsd_trace.rb +33 -45
  270. data/lib/graphql/tracing/statsd_tracing.rb +2 -0
  271. data/lib/graphql/tracing/trace.rb +112 -1
  272. data/lib/graphql/tracing.rb +31 -28
  273. data/lib/graphql/type_kinds.rb +2 -1
  274. data/lib/graphql/types/iso_8601_duration.rb +77 -0
  275. data/lib/graphql/types/relay/connection_behaviors.rb +44 -2
  276. data/lib/graphql/types/relay/edge_behaviors.rb +18 -0
  277. data/lib/graphql/types/relay/has_node_field.rb +13 -8
  278. data/lib/graphql/types/relay/has_nodes_field.rb +13 -8
  279. data/lib/graphql/types/relay/node_behaviors.rb +13 -2
  280. data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
  281. data/lib/graphql/types.rb +18 -10
  282. data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
  283. data/lib/graphql/unauthorized_error.rb +5 -1
  284. data/lib/graphql/version.rb +1 -1
  285. data/lib/graphql.rb +71 -54
  286. data/readme.md +12 -2
  287. metadata +233 -37
  288. data/lib/graphql/analysis/ast/analyzer.rb +0 -84
  289. data/lib/graphql/analysis/ast/field_usage.rb +0 -57
  290. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -22
  291. data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
  292. data/lib/graphql/analysis/ast/query_complexity.rb +0 -230
  293. data/lib/graphql/analysis/ast/query_depth.rb +0 -55
  294. data/lib/graphql/analysis/ast/visitor.rb +0 -276
  295. data/lib/graphql/analysis/ast.rb +0 -81
  296. data/lib/graphql/backtrace/inspect_result.rb +0 -50
  297. data/lib/graphql/backtrace/trace.rb +0 -96
  298. data/lib/graphql/backtrace/tracer.rb +0 -80
  299. data/lib/graphql/deprecation.rb +0 -9
  300. data/lib/graphql/filter.rb +0 -59
  301. data/lib/graphql/language/parser.y +0 -560
  302. data/lib/graphql/language/token.rb +0 -34
  303. data/lib/graphql/schema/base_64_bp.rb +0 -26
  304. data/lib/graphql/schema/invalid_type_error.rb +0 -7
  305. data/lib/graphql/schema/null_mask.rb +0 -11
  306. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +0 -17
  307. data/lib/graphql/static_validation/type_stack.rb +0 -216
  308. data/lib/graphql/subscriptions/instrumentation.rb +0 -28
@@ -12,7 +12,7 @@ module GraphQL
12
12
  @possible_types = {}
13
13
  @types = {}
14
14
  @union_memberships = {}
15
- @references = Hash.new { |h, k| h[k] = [] }
15
+ @references = Hash.new { |h, k| h[k] = Set.new }
16
16
  @arguments_with_default_values = []
17
17
  add_type_and_traverse(new_types)
18
18
  end
@@ -20,7 +20,7 @@ module GraphQL
20
20
  private
21
21
 
22
22
  def references_to(thing, from:)
23
- @references[thing] << from
23
+ @references[thing].add(from)
24
24
  end
25
25
 
26
26
  def get_type(name)
@@ -40,7 +40,7 @@ module GraphQL
40
40
  end
41
41
 
42
42
  def add_directives_from(owner)
43
- if (dir_instances = owner.directives).any?
43
+ if !(dir_instances = owner.directives).empty?
44
44
  dirs = dir_instances.map(&:class)
45
45
  @directives.merge(dirs)
46
46
  add_type_and_traverse(dirs)
@@ -95,7 +95,7 @@ module GraphQL
95
95
  # It's a union with possible_types
96
96
  # Replace the item by class name
97
97
  owner.assign_type_membership_object_type(type)
98
- @possible_types[owner.graphql_name] = owner.possible_types
98
+ @possible_types[owner] = owner.possible_types
99
99
  elsif type.kind.interface? && (owner.kind.object? || owner.kind.interface?)
100
100
  new_interfaces = []
101
101
  owner.interfaces.each do |int_t|
@@ -110,7 +110,7 @@ module GraphQL
110
110
  end
111
111
  owner.implements(*new_interfaces)
112
112
  new_interfaces.each do |int|
113
- pt = @possible_types[int.graphql_name] ||= []
113
+ pt = @possible_types[int] ||= []
114
114
  if !pt.include?(owner) && owner.is_a?(Class)
115
115
  pt << owner
116
116
  end
@@ -126,6 +126,7 @@ module GraphQL
126
126
  @types[type.graphql_name] = type
127
127
  when GraphQL::Schema::Field, GraphQL::Schema::Argument
128
128
  orig_type = owner.type
129
+ unwrapped_t = type
129
130
  # Apply list/non-null wrapper as needed
130
131
  if orig_type.respond_to?(:of_type)
131
132
  transforms = []
@@ -142,6 +143,7 @@ module GraphQL
142
143
  transforms.reverse_each { |t| type = type.public_send(t) }
143
144
  end
144
145
  owner.type = type
146
+ references_to(unwrapped_t, from: owner)
145
147
  else
146
148
  raise "Unexpected update: #{owner.inspect} #{type.inspect}"
147
149
  end
@@ -164,7 +166,9 @@ module GraphQL
164
166
  @directives << type
165
167
  type.all_argument_definitions.each do |arg|
166
168
  arg_type = arg.type.unwrap
167
- references_to(arg_type, from: arg)
169
+ if !arg_type.is_a?(GraphQL::Schema::LateBoundType)
170
+ references_to(arg_type, from: arg)
171
+ end
168
172
  path.push(arg.graphql_name)
169
173
  add_type(arg_type, owner: arg, late_types: late_types, path: path)
170
174
  path.pop
@@ -185,16 +189,21 @@ module GraphQL
185
189
  add_directives_from(type)
186
190
  if type.kind.fields?
187
191
  type.all_field_definitions.each do |field|
192
+ field.ensure_loaded
188
193
  name = field.graphql_name
189
194
  field_type = field.type.unwrap
190
- references_to(field_type, from: field)
195
+ if !field_type.is_a?(GraphQL::Schema::LateBoundType)
196
+ references_to(field_type, from: field)
197
+ end
191
198
  path.push(name)
192
199
  add_type(field_type, owner: field, late_types: late_types, path: path)
193
200
  add_directives_from(field)
194
201
  field.all_argument_definitions.each do |arg|
195
202
  add_directives_from(arg)
196
203
  arg_type = arg.type.unwrap
197
- references_to(arg_type, from: arg)
204
+ if !arg_type.is_a?(GraphQL::Schema::LateBoundType)
205
+ references_to(arg_type, from: arg)
206
+ end
198
207
  path.push(arg.graphql_name)
199
208
  add_type(arg_type, owner: arg, late_types: late_types, path: path)
200
209
  path.pop
@@ -209,7 +218,9 @@ module GraphQL
209
218
  type.all_argument_definitions.each do |arg|
210
219
  add_directives_from(arg)
211
220
  arg_type = arg.type.unwrap
212
- references_to(arg_type, from: arg)
221
+ if !arg_type.is_a?(GraphQL::Schema::LateBoundType)
222
+ references_to(arg_type, from: arg)
223
+ end
213
224
  path.push(arg.graphql_name)
214
225
  add_type(arg_type, owner: arg, late_types: late_types, path: path)
215
226
  path.pop
@@ -219,7 +230,7 @@ module GraphQL
219
230
  end
220
231
  end
221
232
  if type.kind.union?
222
- @possible_types[type.graphql_name] = type.all_possible_types
233
+ @possible_types[type] = type.all_possible_types
223
234
  path.push("possible_types")
224
235
  type.all_possible_types.each do |t|
225
236
  add_type(t, owner: type, late_types: late_types, path: path)
@@ -234,7 +245,7 @@ module GraphQL
234
245
  path.pop
235
246
  end
236
247
  if type.kind.object?
237
- possible_types_for_this_name = @possible_types[type.graphql_name] ||= []
248
+ possible_types_for_this_name = @possible_types[type] ||= []
238
249
  possible_types_for_this_name << type
239
250
  end
240
251
 
@@ -246,8 +257,10 @@ module GraphQL
246
257
  interface_type = interface_type_membership.abstract_type
247
258
  # We can get these now; we'll have to get late-bound types later
248
259
  if interface_type.is_a?(Module) && type.is_a?(Class)
249
- implementers = @possible_types[interface_type.graphql_name] ||= []
250
- implementers << type
260
+ implementers = @possible_types[interface_type] ||= []
261
+ if !implementers.include?(type)
262
+ implementers << type
263
+ end
251
264
  end
252
265
  when String, Schema::LateBoundType
253
266
  interface_type = interface_type_membership
@@ -1,9 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
3
  class Schema
4
- class AlwaysVisible
4
+ module AlwaysVisible
5
5
  def self.use(schema, **opts)
6
- schema.warden_class = GraphQL::Schema::Warden::NullWarden
6
+ schema.use(GraphQL::Schema::Visibility, profiles: { nil => {} })
7
+ schema.extend(self)
8
+ end
9
+
10
+ def visible?(_member, _context)
11
+ true
7
12
  end
8
13
  end
9
14
  end
@@ -4,6 +4,7 @@ module GraphQL
4
4
  class Argument
5
5
  include GraphQL::Schema::Member::HasPath
6
6
  include GraphQL::Schema::Member::HasAstNode
7
+ include GraphQL::Schema::Member::HasAuthorization
7
8
  include GraphQL::Schema::Member::HasDirectives
8
9
  include GraphQL::Schema::Member::HasDeprecationReason
9
10
  include GraphQL::Schema::Member::HasValidators
@@ -39,9 +40,14 @@ module GraphQL
39
40
  # @param arg_name [Symbol]
40
41
  # @param type_expr
41
42
  # @param desc [String]
43
+ # @param type [Class, Array<Class>] Input type; positional argument also accepted
44
+ # @param name [Symbol] positional argument also accepted # @param loads [Class, Array<Class>] A GraphQL type to load for the given ID when one is present
45
+ # @param definition_block [Proc] Called with the newly-created {Argument}
46
+ # @param owner [Class] Private, used by GraphQL-Ruby during schema definition
42
47
  # @param required [Boolean, :nullable] if true, this argument is non-null; if false, this argument is nullable. If `:nullable`, then the argument must be provided, though it may be `null`.
43
48
  # @param description [String]
44
49
  # @param default_value [Object]
50
+ # @param loads [Class, Array<Class>] A GraphQL type to load for the given ID when one is present
45
51
  # @param as [Symbol] Override the keyword name when passed to a method
46
52
  # @param prepare [Symbol] A method to call to transform this argument's valuebefore sending it to field resolution
47
53
  # @param camelize [Boolean] if true, the name will be camelized when building the schema
@@ -50,12 +56,15 @@ module GraphQL
50
56
  # @param deprecation_reason [String]
51
57
  # @param validates [Hash, nil] Options for building validators, if any should be applied
52
58
  # @param replace_null_with_default [Boolean] if `true`, incoming values of `null` will be replaced with the configured `default_value`
53
- def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value: NOT_CONFIGURED, as: nil, from_resolver: false, camelize: true, prepare: nil, owner:, validates: nil, directives: nil, deprecation_reason: nil, replace_null_with_default: false, &definition_block)
59
+ # @param comment [String] Private, used by GraphQL-Ruby when parsing GraphQL schema files
60
+ # @param ast_node [GraphQL::Language::Nodes::InputValueDefinition] Private, used by GraphQL-Ruby when parsing schema files
61
+ def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, comment: nil, ast_node: nil, default_value: NOT_CONFIGURED, as: nil, from_resolver: false, camelize: true, prepare: nil, owner:, validates: nil, directives: nil, deprecation_reason: nil, replace_null_with_default: false, &definition_block)
54
62
  arg_name ||= name
55
63
  @name = -(camelize ? Member::BuildType.camelize(arg_name.to_s) : arg_name.to_s)
56
64
  NameValidator.validate!(@name)
57
65
  @type_expr = type_expr || type
58
66
  @description = desc || description
67
+ @comment = comment
59
68
  @null = required != true
60
69
  @default_value = default_value
61
70
  if replace_null_with_default
@@ -127,6 +136,17 @@ module GraphQL
127
136
  end
128
137
  end
129
138
 
139
+ attr_writer :comment
140
+
141
+ # @return [String] Comment for this argument
142
+ def comment(text = nil)
143
+ if text
144
+ @comment = text
145
+ else
146
+ @comment
147
+ end
148
+ end
149
+
130
150
  # @return [String] Deprecation reason for this argument
131
151
  def deprecation_reason(text = nil)
132
152
  if text
@@ -145,6 +165,10 @@ module GraphQL
145
165
  true
146
166
  end
147
167
 
168
+ def authorizes?(_context)
169
+ self.method(:authorized?).owner != GraphQL::Schema::Argument
170
+ end
171
+
148
172
  def authorized?(obj, value, ctx)
149
173
  authorized_as_type?(obj, value, ctx, as_type: type)
150
174
  end
@@ -200,12 +224,17 @@ module GraphQL
200
224
  @statically_coercible = !requires_parent_object
201
225
  end
202
226
 
227
+ def freeze
228
+ statically_coercible?
229
+ super
230
+ end
231
+
203
232
  # Apply the {prepare} configuration to `value`, using methods from `obj`.
204
233
  # Used by the runtime.
205
234
  # @api private
206
235
  def prepare_value(obj, value, context: nil)
207
- if value.is_a?(GraphQL::Schema::InputObject)
208
- value = value.prepare
236
+ if type.unwrap.kind.input_object?
237
+ value = recursively_prepare_input_object(value, type, context)
209
238
  end
210
239
 
211
240
  Schema::Validator.validate!(validators, obj, context, value)
@@ -219,8 +248,13 @@ module GraphQL
219
248
  #
220
249
  # This will have to be called later, when the runtime object _is_ available.
221
250
  value
222
- else
251
+ elsif obj.respond_to?(@prepare)
223
252
  obj.public_send(@prepare, value)
253
+ elsif owner.respond_to?(@prepare)
254
+ owner.public_send(@prepare, value, context || obj.context)
255
+ else
256
+ raise "Invalid prepare for #{@owner.name}.name: #{@prepare.inspect}. "\
257
+ "Could not find prepare method #{@prepare} on #{obj.class} or #{owner}."
224
258
  end
225
259
  elsif @prepare.respond_to?(:call)
226
260
  @prepare.call(value, context || obj.context)
@@ -283,6 +317,7 @@ module GraphQL
283
317
  # TODO code smell to access such a deeply-nested constant in a distant module
284
318
  argument_values[arg_key] = GraphQL::Execution::Interpreter::ArgumentValue.new(
285
319
  value: resolved_loaded_value,
320
+ original_value: resolved_coerced_value,
286
321
  definition: self,
287
322
  default_used: default_used,
288
323
  )
@@ -304,10 +339,15 @@ module GraphQL
304
339
  context.query.after_lazy(custom_loaded_value) do |custom_value|
305
340
  if loads
306
341
  if type.list?
307
- loaded_values = custom_value.each_with_index.map { |custom_val, idx|
308
- id = coerced_value[idx]
309
- load_method_owner.authorize_application_object(self, id, context, custom_val)
310
- }
342
+ loaded_values = []
343
+ context.dataloader.run_isolated do
344
+ custom_value.each_with_index.map { |custom_val, idx|
345
+ id = coerced_value[idx]
346
+ context.dataloader.append_job do
347
+ loaded_values[idx] = load_method_owner.authorize_application_object(self, id, context, custom_val)
348
+ end
349
+ }
350
+ end
311
351
  context.schema.after_any_lazies(loaded_values, &:itself)
312
352
  else
313
353
  load_method_owner.authorize_application_object(self, coerced_value, context, custom_loaded_value)
@@ -318,7 +358,16 @@ module GraphQL
318
358
  end
319
359
  elsif loads
320
360
  if type.list?
321
- loaded_values = coerced_value.map { |val| load_method_owner.load_and_authorize_application_object(self, val, context) }
361
+ loaded_values = []
362
+ # We want to run these list items all together,
363
+ # but we also need to wait for the result so we can return it :S
364
+ context.dataloader.run_isolated do
365
+ coerced_value.each_with_index { |val, idx|
366
+ context.dataloader.append_job do
367
+ loaded_values[idx] = load_method_owner.load_and_authorize_application_object(self, val, context)
368
+ end
369
+ }
370
+ end
322
371
  context.schema.after_any_lazies(loaded_values, &:itself)
323
372
  else
324
373
  load_method_owner.load_and_authorize_application_object(self, coerced_value, context)
@@ -330,6 +379,7 @@ module GraphQL
330
379
 
331
380
  # @api private
332
381
  def validate_default_value
382
+ return unless default_value?
333
383
  coerced_default_value = begin
334
384
  # This is weird, but we should accept single-item default values for list-type arguments.
335
385
  # If we used `coerce_isolated_input` below, it would do this for us, but it's not really
@@ -365,6 +415,22 @@ module GraphQL
365
415
 
366
416
  private
367
417
 
418
+ def recursively_prepare_input_object(value, type, context)
419
+ if type.non_null?
420
+ type = type.of_type
421
+ end
422
+
423
+ if type.list? && !value.nil?
424
+ inner_type = type.of_type
425
+ value.map { |v| recursively_prepare_input_object(v, inner_type, context) }
426
+ elsif value.is_a?(GraphQL::Schema::InputObject)
427
+ value.validate_for(context)
428
+ value.prepare
429
+ else
430
+ value
431
+ end
432
+ end
433
+
368
434
  def validate_input_type(input_type)
369
435
  if input_type.is_a?(String) || input_type.is_a?(GraphQL::Schema::LateBoundType)
370
436
  # Do nothing; assume this will be validated later
@@ -1,18 +1,16 @@
1
1
  # frozen_string_literal: true
2
-
3
- require 'graphql/schema/base_64_bp'
4
-
2
+ require "base64"
5
3
  module GraphQL
6
4
  class Schema
7
5
  # @api private
8
6
  module Base64Encoder
9
7
  def self.encode(unencoded_text, nonce: false)
10
- Base64Bp.urlsafe_encode64(unencoded_text, padding: false)
8
+ Base64.urlsafe_encode64(unencoded_text, padding: false)
11
9
  end
12
10
 
13
11
  def self.decode(encoded_text, nonce: false)
14
12
  # urlsafe_decode64 is for forward compatibility
15
- Base64Bp.urlsafe_decode64(encoded_text)
13
+ Base64.urlsafe_decode64(encoded_text)
16
14
  rescue ArgumentError
17
15
  raise GraphQL::ExecutionError, "Invalid input: #{encoded_text.inspect}"
18
16
  end