graphql 2.0.31 → 2.6.1

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 (316) 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 +102 -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/field_resolve_step.rb +631 -0
  83. data/lib/graphql/execution/finalize.rb +217 -0
  84. data/lib/graphql/execution/input_values.rb +261 -0
  85. data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
  86. data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
  87. data/lib/graphql/execution/interpreter/handles_raw_value.rb +6 -0
  88. data/lib/graphql/execution/interpreter/resolve.rb +23 -25
  89. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +228 -0
  90. data/lib/graphql/execution/interpreter/runtime.rb +365 -435
  91. data/lib/graphql/execution/interpreter.rb +87 -163
  92. data/lib/graphql/execution/lazy.rb +1 -1
  93. data/lib/graphql/execution/load_argument_step.rb +64 -0
  94. data/lib/graphql/execution/lookahead.rb +105 -31
  95. data/lib/graphql/execution/multiplex.rb +7 -6
  96. data/lib/graphql/execution/next.rb +90 -0
  97. data/lib/graphql/execution/prepare_object_step.rb +128 -0
  98. data/lib/graphql/execution/runner.rb +410 -0
  99. data/lib/graphql/execution/selections_step.rb +91 -0
  100. data/lib/graphql/execution.rb +8 -4
  101. data/lib/graphql/execution_error.rb +17 -10
  102. data/lib/graphql/introspection/directive_location_enum.rb +1 -1
  103. data/lib/graphql/introspection/directive_type.rb +7 -3
  104. data/lib/graphql/introspection/dynamic_fields.rb +5 -1
  105. data/lib/graphql/introspection/entry_points.rb +20 -6
  106. data/lib/graphql/introspection/enum_value_type.rb +5 -5
  107. data/lib/graphql/introspection/field_type.rb +13 -5
  108. data/lib/graphql/introspection/input_value_type.rb +21 -13
  109. data/lib/graphql/introspection/schema_type.rb +8 -11
  110. data/lib/graphql/introspection/type_type.rb +64 -28
  111. data/lib/graphql/invalid_name_error.rb +1 -1
  112. data/lib/graphql/invalid_null_error.rb +26 -17
  113. data/lib/graphql/language/block_string.rb +34 -18
  114. data/lib/graphql/language/cache.rb +13 -0
  115. data/lib/graphql/language/comment.rb +18 -0
  116. data/lib/graphql/language/definition_slice.rb +1 -1
  117. data/lib/graphql/language/document_from_schema_definition.rb +90 -61
  118. data/lib/graphql/language/lexer.rb +323 -193
  119. data/lib/graphql/language/nodes.rb +139 -77
  120. data/lib/graphql/language/parser.rb +807 -1985
  121. data/lib/graphql/language/printer.rb +324 -151
  122. data/lib/graphql/language/sanitized_printer.rb +21 -23
  123. data/lib/graphql/language/static_visitor.rb +171 -0
  124. data/lib/graphql/language/visitor.rb +62 -119
  125. data/lib/graphql/language.rb +71 -1
  126. data/lib/graphql/load_application_object_failed_error.rb +5 -1
  127. data/lib/graphql/pagination/array_connection.rb +6 -6
  128. data/lib/graphql/pagination/connection.rb +30 -1
  129. data/lib/graphql/pagination/connections.rb +32 -0
  130. data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
  131. data/lib/graphql/query/context/scoped_context.rb +101 -0
  132. data/lib/graphql/query/context.rb +88 -144
  133. data/lib/graphql/query/null_context.rb +15 -18
  134. data/lib/graphql/query/partial.rb +194 -0
  135. data/lib/graphql/query/validation_pipeline.rb +4 -4
  136. data/lib/graphql/query/variable_validation_error.rb +1 -1
  137. data/lib/graphql/query/variables.rb +3 -3
  138. data/lib/graphql/query.rb +135 -81
  139. data/lib/graphql/railtie.rb +16 -6
  140. data/lib/graphql/rake_task.rb +3 -12
  141. data/lib/graphql/rubocop/graphql/base_cop.rb +1 -1
  142. data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
  143. data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
  144. data/lib/graphql/rubocop.rb +2 -0
  145. data/lib/graphql/runtime_error.rb +6 -0
  146. data/lib/graphql/schema/addition.rb +26 -13
  147. data/lib/graphql/schema/always_visible.rb +7 -2
  148. data/lib/graphql/schema/argument.rb +78 -14
  149. data/lib/graphql/schema/base_64_encoder.rb +3 -5
  150. data/lib/graphql/schema/build_from_definition.rb +140 -66
  151. data/lib/graphql/schema/directive/flagged.rb +4 -2
  152. data/lib/graphql/schema/directive/one_of.rb +12 -0
  153. data/lib/graphql/schema/directive/specified_by.rb +14 -0
  154. data/lib/graphql/schema/directive.rb +78 -12
  155. data/lib/graphql/schema/enum.rb +110 -27
  156. data/lib/graphql/schema/enum_value.rb +11 -3
  157. data/lib/graphql/schema/field/connection_extension.rb +4 -51
  158. data/lib/graphql/schema/field/scope_extension.rb +19 -7
  159. data/lib/graphql/schema/field.rb +245 -119
  160. data/lib/graphql/schema/field_extension.rb +12 -9
  161. data/lib/graphql/schema/has_single_input_argument.rb +160 -0
  162. data/lib/graphql/schema/input_object.rb +123 -65
  163. data/lib/graphql/schema/interface.rb +60 -16
  164. data/lib/graphql/schema/introspection_system.rb +8 -17
  165. data/lib/graphql/schema/late_bound_type.rb +4 -0
  166. data/lib/graphql/schema/list.rb +8 -4
  167. data/lib/graphql/schema/loader.rb +3 -4
  168. data/lib/graphql/schema/member/base_dsl_methods.rb +18 -12
  169. data/lib/graphql/schema/member/has_arguments.rb +132 -100
  170. data/lib/graphql/schema/member/has_authorization.rb +35 -0
  171. data/lib/graphql/schema/member/has_dataloader.rb +99 -0
  172. data/lib/graphql/schema/member/has_deprecation_reason.rb +15 -0
  173. data/lib/graphql/schema/member/has_directives.rb +5 -5
  174. data/lib/graphql/schema/member/has_fields.rb +121 -17
  175. data/lib/graphql/schema/member/has_interfaces.rb +27 -13
  176. data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
  177. data/lib/graphql/schema/member/has_validators.rb +1 -1
  178. data/lib/graphql/schema/member/relay_shortcuts.rb +1 -1
  179. data/lib/graphql/schema/member/scoped.rb +19 -0
  180. data/lib/graphql/schema/member/type_system_helpers.rb +18 -5
  181. data/lib/graphql/schema/member/validates_input.rb +3 -3
  182. data/lib/graphql/schema/member.rb +6 -0
  183. data/lib/graphql/schema/mutation.rb +7 -0
  184. data/lib/graphql/schema/non_null.rb +1 -1
  185. data/lib/graphql/schema/object.rb +34 -8
  186. data/lib/graphql/schema/printer.rb +9 -7
  187. data/lib/graphql/schema/ractor_shareable.rb +79 -0
  188. data/lib/graphql/schema/relay_classic_mutation.rb +6 -129
  189. data/lib/graphql/schema/resolver.rb +128 -32
  190. data/lib/graphql/schema/scalar.rb +4 -9
  191. data/lib/graphql/schema/subscription.rb +63 -12
  192. data/lib/graphql/schema/timeout.rb +19 -2
  193. data/lib/graphql/schema/type_expression.rb +2 -2
  194. data/lib/graphql/schema/union.rb +2 -2
  195. data/lib/graphql/schema/unique_within_type.rb +1 -1
  196. data/lib/graphql/schema/validator/all_validator.rb +62 -0
  197. data/lib/graphql/schema/validator/required_validator.rb +92 -11
  198. data/lib/graphql/schema/validator.rb +3 -1
  199. data/lib/graphql/schema/visibility/migration.rb +188 -0
  200. data/lib/graphql/schema/visibility/profile.rb +464 -0
  201. data/lib/graphql/schema/visibility/visit.rb +190 -0
  202. data/lib/graphql/schema/visibility.rb +311 -0
  203. data/lib/graphql/schema/warden.rb +275 -103
  204. data/lib/graphql/schema/wrapper.rb +7 -1
  205. data/lib/graphql/schema.rb +954 -212
  206. data/lib/graphql/static_validation/all_rules.rb +3 -3
  207. data/lib/graphql/static_validation/base_visitor.rb +96 -71
  208. data/lib/graphql/static_validation/literal_validator.rb +6 -7
  209. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +2 -2
  210. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +18 -6
  211. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +6 -2
  212. data/lib/graphql/static_validation/rules/directives_are_defined.rb +6 -3
  213. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -0
  214. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +14 -3
  215. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +59 -15
  216. data/lib/graphql/static_validation/rules/fields_will_merge.rb +391 -262
  217. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +10 -2
  218. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +6 -6
  219. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +15 -2
  220. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  221. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
  222. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
  223. data/lib/graphql/static_validation/rules/not_single_subscription_error.rb +25 -0
  224. data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
  225. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +28 -8
  226. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +5 -5
  227. data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +26 -0
  228. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +7 -3
  229. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
  230. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
  231. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
  232. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +14 -2
  233. data/lib/graphql/static_validation/validation_context.rb +22 -6
  234. data/lib/graphql/static_validation/validator.rb +9 -1
  235. data/lib/graphql/static_validation.rb +0 -1
  236. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +8 -5
  237. data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
  238. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +45 -19
  239. data/lib/graphql/subscriptions/event.rb +22 -4
  240. data/lib/graphql/subscriptions/serialize.rb +3 -1
  241. data/lib/graphql/subscriptions.rb +56 -17
  242. data/lib/graphql/testing/helpers.rb +161 -0
  243. data/lib/graphql/testing/mock_action_cable.rb +111 -0
  244. data/lib/graphql/testing.rb +3 -0
  245. data/lib/graphql/tracing/active_support_notifications_trace.rb +14 -3
  246. data/lib/graphql/tracing/active_support_notifications_tracing.rb +1 -1
  247. data/lib/graphql/tracing/appoptics_trace.rb +11 -3
  248. data/lib/graphql/tracing/appoptics_tracing.rb +9 -2
  249. data/lib/graphql/tracing/appsignal_trace.rb +32 -55
  250. data/lib/graphql/tracing/appsignal_tracing.rb +2 -0
  251. data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
  252. data/lib/graphql/tracing/data_dog_trace.rb +46 -158
  253. data/lib/graphql/tracing/data_dog_tracing.rb +2 -0
  254. data/lib/graphql/tracing/detailed_trace/active_record_backend.rb +74 -0
  255. data/lib/graphql/tracing/detailed_trace/memory_backend.rb +60 -0
  256. data/lib/graphql/tracing/detailed_trace/redis_backend.rb +72 -0
  257. data/lib/graphql/tracing/detailed_trace.rb +156 -0
  258. data/lib/graphql/tracing/legacy_hooks_trace.rb +75 -0
  259. data/lib/graphql/tracing/legacy_trace.rb +4 -61
  260. data/lib/graphql/tracing/monitor_trace.rb +283 -0
  261. data/lib/graphql/tracing/new_relic_trace.rb +47 -54
  262. data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
  263. data/lib/graphql/tracing/notifications_trace.rb +184 -34
  264. data/lib/graphql/tracing/notifications_tracing.rb +2 -0
  265. data/lib/graphql/tracing/null_trace.rb +9 -0
  266. data/lib/graphql/tracing/perfetto_trace/trace.proto +141 -0
  267. data/lib/graphql/tracing/perfetto_trace/trace_pb.rb +33 -0
  268. data/lib/graphql/tracing/perfetto_trace.rb +864 -0
  269. data/lib/graphql/tracing/platform_trace.rb +5 -0
  270. data/lib/graphql/tracing/platform_tracing.rb +3 -1
  271. data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +5 -1
  272. data/lib/graphql/tracing/prometheus_trace.rb +72 -68
  273. data/lib/graphql/tracing/prometheus_tracing.rb +2 -0
  274. data/lib/graphql/tracing/scout_trace.rb +32 -55
  275. data/lib/graphql/tracing/scout_tracing.rb +2 -0
  276. data/lib/graphql/tracing/sentry_trace.rb +82 -0
  277. data/lib/graphql/tracing/statsd_trace.rb +33 -41
  278. data/lib/graphql/tracing/statsd_tracing.rb +2 -0
  279. data/lib/graphql/tracing/trace.rb +118 -1
  280. data/lib/graphql/tracing.rb +31 -28
  281. data/lib/graphql/type_kinds.rb +2 -1
  282. data/lib/graphql/types/iso_8601_duration.rb +77 -0
  283. data/lib/graphql/types/relay/connection_behaviors.rb +45 -3
  284. data/lib/graphql/types/relay/edge_behaviors.rb +19 -1
  285. data/lib/graphql/types/relay/has_node_field.rb +13 -8
  286. data/lib/graphql/types/relay/has_nodes_field.rb +13 -8
  287. data/lib/graphql/types/relay/node_behaviors.rb +13 -2
  288. data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
  289. data/lib/graphql/types.rb +18 -10
  290. data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
  291. data/lib/graphql/unauthorized_error.rb +9 -1
  292. data/lib/graphql/version.rb +1 -1
  293. data/lib/graphql.rb +69 -54
  294. data/readme.md +12 -2
  295. metadata +236 -40
  296. data/lib/graphql/analysis/ast/analyzer.rb +0 -84
  297. data/lib/graphql/analysis/ast/field_usage.rb +0 -57
  298. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -22
  299. data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
  300. data/lib/graphql/analysis/ast/query_complexity.rb +0 -230
  301. data/lib/graphql/analysis/ast/query_depth.rb +0 -55
  302. data/lib/graphql/analysis/ast/visitor.rb +0 -276
  303. data/lib/graphql/analysis/ast.rb +0 -81
  304. data/lib/graphql/backtrace/inspect_result.rb +0 -50
  305. data/lib/graphql/backtrace/trace.rb +0 -96
  306. data/lib/graphql/backtrace/tracer.rb +0 -80
  307. data/lib/graphql/deprecation.rb +0 -9
  308. data/lib/graphql/filter.rb +0 -59
  309. data/lib/graphql/language/parser.y +0 -560
  310. data/lib/graphql/language/token.rb +0 -34
  311. data/lib/graphql/schema/base_64_bp.rb +0 -26
  312. data/lib/graphql/schema/invalid_type_error.rb +0 -7
  313. data/lib/graphql/schema/null_mask.rb +0 -11
  314. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +0 -17
  315. data/lib/graphql/static_validation/type_stack.rb +0 -216
  316. data/lib/graphql/subscriptions/instrumentation.rb +0 -28
@@ -0,0 +1,194 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ class Query
4
+ # This class is _like_ a {GraphQL::Query}, except it can run on an arbitrary path within a query string.
5
+ #
6
+ # It depends on a "parent" {Query}.
7
+ #
8
+ # During execution, it calls query-related tracing hooks but passes itself as `query:`.
9
+ #
10
+ # The {Partial} will use your {Schema.resolve_type} hook to find the right GraphQL type to use for
11
+ # `object` in some cases.
12
+ #
13
+ # @see Query#run_partials Run via {Query#run_partials}
14
+ class Partial
15
+ include Query::Runnable
16
+
17
+ # @param path [Array<String, Integer>] A path in `query.query_string` to start executing from
18
+ # @param object [Object] A starting object for execution
19
+ # @param query [GraphQL::Query] A full query instance that this partial is based on. Caches are shared.
20
+ # @param context [Hash] Extra context values to merge into `query.context`, if provided
21
+ # @param fragment_node [GraphQL::Language::Nodes::InlineFragment, GraphQL::Language::Nodes::FragmentDefinition]
22
+ def initialize(path: nil, object:, query:, context: nil, fragment_node: nil, type: nil)
23
+ @path = path
24
+ @object = object
25
+ @query = query
26
+ @schema = query.schema
27
+ context_vals = @query.context.to_h
28
+ if context
29
+ context_vals = context_vals.merge(context)
30
+ end
31
+ @context = GraphQL::Query::Context.new(query: self, schema: @query.schema, values: context_vals)
32
+ @multiplex = nil
33
+ @result_values = nil
34
+ @result = nil
35
+ @finalizers = @top_level_finalizers = nil
36
+
37
+ if fragment_node
38
+ @ast_nodes = [fragment_node]
39
+ @root_type = type || raise(ArgumentError, "Pass `type:` when using `node:`")
40
+ # This is only used when `@leaf`
41
+ @field_definition = nil
42
+ elsif path.nil?
43
+ raise ArgumentError, "`path:` is required if `node:` is not given; add `path:`"
44
+ else
45
+ set_type_info_from_path
46
+ end
47
+
48
+ @leaf = @root_type.unwrap.kind.leaf?
49
+ end
50
+
51
+ def leaf?
52
+ @leaf
53
+ end
54
+
55
+ def root_value
56
+ object
57
+ end
58
+
59
+ attr_reader :context, :query, :ast_nodes, :root_type, :object, :field_definition, :path, :schema
60
+
61
+ attr_accessor :multiplex, :result_values
62
+
63
+ class Result < GraphQL::Query::Result
64
+ def path
65
+ @query.path
66
+ end
67
+
68
+ # @return [GraphQL::Query::Partial]
69
+ def partial
70
+ @query
71
+ end
72
+ end
73
+
74
+ def result
75
+ @result ||= Result.new(query: self, values: result_values)
76
+ end
77
+
78
+ def current_trace
79
+ @query.current_trace
80
+ end
81
+
82
+ def types
83
+ @query.types
84
+ end
85
+
86
+ def resolve_type(...)
87
+ @query.resolve_type(...)
88
+ end
89
+
90
+ def variables
91
+ @query.variables
92
+ end
93
+
94
+ def fragments
95
+ @query.fragments
96
+ end
97
+
98
+ def validate
99
+ @query.validate
100
+ end
101
+
102
+ def valid?
103
+ @query.valid?
104
+ end
105
+
106
+ def query?
107
+ true
108
+ end
109
+
110
+ def run_partials(...)
111
+ @query.run_partials(...)
112
+ end
113
+
114
+ def analyzers
115
+ EmptyObjects::EMPTY_ARRAY
116
+ end
117
+
118
+ def analysis_errors=(_ignored)
119
+ # pass
120
+ end
121
+
122
+ def subscription?
123
+ @query.subscription?
124
+ end
125
+
126
+ def selected_operation
127
+ Language::Nodes::OperationDefinition.new(selections: ast_nodes.flat_map(&:selections))
128
+ end
129
+
130
+ def static_errors
131
+ @query.static_errors
132
+ end
133
+
134
+ def selected_operation_name
135
+ @query.selected_operation_name
136
+ end
137
+
138
+ private
139
+
140
+ def set_type_info_from_path
141
+ selections = [@query.selected_operation]
142
+ type = @query.root_type
143
+ field_defn = nil
144
+
145
+ @path.each do |name_in_doc|
146
+ if name_in_doc.is_a?(Integer)
147
+ if type.list?
148
+ type = type.unwrap
149
+ next
150
+ else
151
+ raise ArgumentError, "Received path with index `#{name_in_doc}`, but type wasn't a list. Type: #{type.to_type_signature}, path: #{@path}"
152
+ end
153
+ end
154
+
155
+ next_selections = []
156
+ selections.each do |selection|
157
+ selections_to_check = []
158
+ selections_to_check.concat(selection.selections)
159
+ while (sel = selections_to_check.shift)
160
+ case sel
161
+ when GraphQL::Language::Nodes::InlineFragment
162
+ selections_to_check.concat(sel.selections)
163
+ when GraphQL::Language::Nodes::FragmentSpread
164
+ fragment = @query.fragments[sel.name]
165
+ selections_to_check.concat(fragment.selections)
166
+ when GraphQL::Language::Nodes::Field
167
+ if sel.alias == name_in_doc || sel.name == name_in_doc
168
+ next_selections << sel
169
+ end
170
+ else
171
+ raise "Unexpected selection in partial path: #{sel.class}, #{sel.inspect}"
172
+ end
173
+ end
174
+ end
175
+
176
+ if next_selections.empty?
177
+ raise ArgumentError, "Path `#{@path.inspect}` is not present in this query. `#{name_in_doc.inspect}` was not found. Try a different path or rewrite the query to include it."
178
+ end
179
+ field_name = next_selections.first.name
180
+ field_defn = @schema.get_field(type, field_name, @query.context) || raise("Invariant: no field called #{field_name} on #{type.graphql_name}")
181
+ type = field_defn.type
182
+ if type.non_null?
183
+ type = type.of_type
184
+ end
185
+ selections = next_selections
186
+ end
187
+
188
+ @ast_nodes = selections
189
+ @root_type = type
190
+ @field_definition = field_defn
191
+ end
192
+ end
193
+ end
194
+ end
@@ -14,7 +14,7 @@ module GraphQL
14
14
  #
15
15
  # @api private
16
16
  class ValidationPipeline
17
- attr_reader :max_depth, :max_complexity
17
+ attr_reader :max_depth, :max_complexity, :validate_timeout_remaining
18
18
 
19
19
  def initialize(query:, parse_error:, operation_name_error:, max_depth:, max_complexity:)
20
20
  @validation_errors = []
@@ -71,7 +71,7 @@ module GraphQL
71
71
  validator = @query.static_validator || @schema.static_validator
72
72
  validation_result = validator.validate(@query, validate: @query.validate, timeout: @schema.validate_timeout, max_errors: @schema.validate_max_errors)
73
73
  @validation_errors.concat(validation_result[:errors])
74
-
74
+ @validate_timeout_remaining = validation_result[:remaining_timeout]
75
75
  if @validation_errors.empty?
76
76
  @validation_errors.concat(@query.variables.errors)
77
77
  end
@@ -100,10 +100,10 @@ module GraphQL
100
100
  # Depending on the analysis engine, we must use different analyzers
101
101
  # remove this once everything has switched over to AST analyzers
102
102
  if max_depth
103
- qa << GraphQL::Analysis::AST::MaxQueryDepth
103
+ qa << GraphQL::Analysis::MaxQueryDepth
104
104
  end
105
105
  if max_complexity
106
- qa << GraphQL::Analysis::AST::MaxQueryComplexity
106
+ qa << GraphQL::Analysis::MaxQueryComplexity
107
107
  end
108
108
  qa
109
109
  else
@@ -10,7 +10,7 @@ module GraphQL
10
10
 
11
11
  msg ||= "Variable $#{variable_ast.name} of type #{type.to_type_signature} was provided invalid value"
12
12
 
13
- if problem_fields.any?
13
+ if !problem_fields.empty?
14
14
  msg += " for #{problem_fields.join(", ")}"
15
15
  end
16
16
 
@@ -26,7 +26,7 @@ module GraphQL
26
26
  # - Then, fall back to the default value from the query string
27
27
  # If it's still nil, raise an error if it's required.
28
28
  variable_type = schema.type_from_ast(ast_variable.type, context: ctx)
29
- if variable_type.nil?
29
+ if variable_type.nil? || !variable_type.unwrap.kind.input?
30
30
  # Pass -- it will get handled by a validator
31
31
  else
32
32
  variable_name = ast_variable.name
@@ -80,12 +80,12 @@ module GraphQL
80
80
  else
81
81
  val
82
82
  end
83
- end
83
+ end
84
84
 
85
85
  def add_max_errors_reached_message
86
86
  message = "Too many errors processing variables, max validation error limit reached. Execution aborted"
87
87
  validation_result = GraphQL::Query::InputValidationResult.from_problem(message)
88
- errors << GraphQL::Query::VariableValidationError.new(nil, nil, nil, validation_result, msg: message)
88
+ errors << GraphQL::Query::VariableValidationError.new(nil, nil, nil, validation_result, msg: message)
89
89
  end
90
90
  end
91
91
  end
data/lib/graphql/query.rb CHANGED
@@ -1,19 +1,56 @@
1
1
  # frozen_string_literal: true
2
- require "graphql/query/context"
3
- require "graphql/query/fingerprint"
4
- require "graphql/query/null_context"
5
- require "graphql/query/result"
6
- require "graphql/query/variables"
7
- require "graphql/query/input_validation_result"
8
- require "graphql/query/variable_validation_error"
9
- require "graphql/query/validation_pipeline"
10
2
 
11
3
  module GraphQL
12
4
  # A combination of query string and {Schema} instance which can be reduced to a {#result}.
13
5
  class Query
6
+ extend Autoload
14
7
  include Tracing::Traceable
15
8
  extend Forwardable
16
9
 
10
+ autoload :Context, "graphql/query/context"
11
+ autoload :Fingerprint, "graphql/query/fingerprint"
12
+ autoload :NullContext, "graphql/query/null_context"
13
+ autoload :Partial, "graphql/query/partial"
14
+ autoload :Result, "graphql/query/result"
15
+ autoload :Variables, "graphql/query/variables"
16
+ autoload :InputValidationResult, "graphql/query/input_validation_result"
17
+ autoload :VariableValidationError, "graphql/query/variable_validation_error"
18
+ autoload :ValidationPipeline, "graphql/query/validation_pipeline"
19
+
20
+ # Code shared with {Partial}
21
+ module Runnable
22
+ def after_lazy(value, &block)
23
+ if !defined?(@runtime_instance)
24
+ @runtime_instance = context.namespace(:interpreter_runtime)[:runtime]
25
+ end
26
+
27
+ if @runtime_instance
28
+ @runtime_instance.minimal_after_lazy(value, &block)
29
+ else
30
+ @schema.after_lazy(value, &block)
31
+ end
32
+ end
33
+
34
+ # Node-level cache for calculating arguments. Used during execution and query analysis.
35
+ # @param ast_node [GraphQL::Language::Nodes::AbstractNode]
36
+ # @param definition [GraphQL::Schema::Field]
37
+ # @param parent_object [GraphQL::Schema::Object]
38
+ # @return [Hash{Symbol => Object}]
39
+ def arguments_for(ast_node, definition, parent_object: nil)
40
+ arguments_cache.fetch(ast_node, definition, parent_object)
41
+ end
42
+
43
+ def arguments_cache
44
+ @arguments_cache ||= Execution::Interpreter::ArgumentsCache.new(self)
45
+ end
46
+
47
+ # @api private
48
+ def handle_or_reraise(err)
49
+ @schema.handle_or_reraise(context, err)
50
+ end
51
+ end
52
+
53
+ include Runnable
17
54
  class OperationNameMissingError < GraphQL::ExecutionError
18
55
  def initialize(name)
19
56
  msg = if name.nil?
@@ -48,7 +85,7 @@ module GraphQL
48
85
  # @return [GraphQL::StaticValidation::Validator] if present, the query will validate with these rules.
49
86
  attr_reader :static_validator
50
87
 
51
- # @param new_validate [GraphQL::StaticValidation::Validator] if present, the query will validate with these rules. This can't be reasssigned after validation.
88
+ # @param new_validator [GraphQL::StaticValidation::Validator] if present, the query will validate with these rules. This can't be reasssigned after validation.
52
89
  def static_validator=(new_validator)
53
90
  if defined?(@validation_pipeline) && @validation_pipeline && @validation_pipeline.has_validated?
54
91
  raise ArgumentError, "Can't reassign Query#static_validator= after validation has run, remove this assignment."
@@ -95,41 +132,43 @@ module GraphQL
95
132
  # @param root_value [Object] the object used to resolve fields on the root type
96
133
  # @param max_depth [Numeric] the maximum number of nested selections allowed for this query (falls back to schema-level value)
97
134
  # @param max_complexity [Numeric] the maximum field complexity for this query (falls back to schema-level value)
98
- # @param except [<#call(schema_member, context)>] If provided, objects will be hidden from the schema when `.call(schema_member, context)` returns truthy
99
- # @param only [<#call(schema_member, context)>] If provided, objects will be hidden from the schema when `.call(schema_member, context)` returns false
100
- def initialize(schema, query_string = nil, query: nil, document: nil, context: nil, variables: nil, validate: true, static_validator: nil, subscription_topic: nil, operation_name: nil, root_value: nil, max_depth: schema.max_depth, max_complexity: schema.max_complexity, except: nil, only: nil, warden: nil)
135
+ # @param visibility_profile [Symbol] Another way to assign `context[:visibility_profile]`
136
+ def initialize(schema, query_string = nil, query: nil, document: nil, context: nil, variables: nil, multiplex: nil, validate: true, static_validator: nil, visibility_profile: nil, subscription_topic: nil, operation_name: nil, root_value: nil, max_depth: schema.max_depth, max_complexity: schema.max_complexity, warden: nil, use_visibility_profile: nil)
101
137
  # Even if `variables: nil` is passed, use an empty hash for simpler logic
102
138
  variables ||= {}
139
+ @multiplex = multiplex
103
140
  @schema = schema
104
- if only || except
105
- merge_filters(except: except, only: only)
141
+ @context = schema.context_class.new(query: self, values: context)
142
+ if visibility_profile
143
+ @context[:visibility_profile] ||= visibility_profile
144
+ end
145
+
146
+ if use_visibility_profile.nil?
147
+ use_visibility_profile = warden ? false : schema.use_visibility_profile?
106
148
  end
107
- @context = schema.context_class.new(query: self, object: root_value, values: context)
108
- @warden = warden
149
+
150
+ if use_visibility_profile
151
+ @visibility_profile = @schema.visibility.profile_for(@context)
152
+ @warden = Schema::Warden::NullWarden.new(context: @context, schema: @schema)
153
+ else
154
+ @visibility_profile = nil
155
+ @warden = warden
156
+ end
157
+
109
158
  @subscription_topic = subscription_topic
110
159
  @root_value = root_value
111
160
  @fragments = nil
112
161
  @operations = nil
162
+ @finalizers = @top_level_finalizers = nil
113
163
  @validate = validate
114
164
  self.static_validator = static_validator if static_validator
115
165
  context_tracers = (context ? context.fetch(:tracers, []) : [])
116
166
  @tracers = schema.tracers + context_tracers
117
167
 
118
- # Support `ctx[:backtrace] = true` for wrapping backtraces
119
- if context && context[:backtrace] && !@tracers.include?(GraphQL::Backtrace::Tracer)
120
- if schema.trace_class <= GraphQL::Tracing::CallLegacyTracers
121
- context_tracers += [GraphQL::Backtrace::Tracer]
122
- @tracers << GraphQL::Backtrace::Tracer
123
- elsif !(current_trace.class <= GraphQL::Backtrace::Trace)
124
- raise "Invariant: `backtrace: true` should have provided a trace class with Backtrace mixed in, but it didnt. (Found: #{current_trace.class.ancestors}). This is a bug in GraphQL-Ruby, please report it on GitHub."
125
- end
126
- end
127
-
128
- if context_tracers.any? && !(schema.trace_class <= GraphQL::Tracing::CallLegacyTracers)
168
+ if !context_tracers.empty? && !(schema.trace_class <= GraphQL::Tracing::CallLegacyTracers)
129
169
  raise ArgumentError, "context[:tracers] are not supported without `trace_with(GraphQL::Tracing::CallLegacyTracers)` in the schema configuration, please add it."
130
170
  end
131
171
 
132
-
133
172
  @analysis_errors = []
134
173
  if variables.is_a?(String)
135
174
  raise ArgumentError, "Query variables should be a Hash, not a String. Try JSON.parse to prepare variables."
@@ -168,6 +207,8 @@ module GraphQL
168
207
 
169
208
  @result_values = nil
170
209
  @executed = false
210
+
211
+ @logger = schema.logger_for(context)
171
212
  end
172
213
 
173
214
  # If a document was provided to `GraphQL::Schema#execute` instead of the raw query string, we will need to get it from the document
@@ -175,9 +216,8 @@ module GraphQL
175
216
  @query_string ||= (document ? document.to_query_string : nil)
176
217
  end
177
218
 
178
- def interpreter?
179
- true
180
- end
219
+ # @return [Symbol, nil]
220
+ attr_reader :visibility_profile
181
221
 
182
222
  attr_accessor :multiplex
183
223
 
@@ -194,9 +234,11 @@ module GraphQL
194
234
  # @return [GraphQL::Execution::Lookahead]
195
235
  def lookahead
196
236
  @lookahead ||= begin
197
- ast_node = selected_operation
198
- root_type = warden.root_type_for_operation(ast_node.operation_type || "query")
199
- GraphQL::Execution::Lookahead.new(query: self, root_type: root_type, ast_nodes: [ast_node])
237
+ if selected_operation.nil?
238
+ GraphQL::Execution::Lookahead::NULL_LOOKAHEAD
239
+ else
240
+ GraphQL::Execution::Lookahead.new(query: self, root_type: root_type, ast_nodes: [selected_operation])
241
+ end
200
242
  end
201
243
  end
202
244
 
@@ -221,8 +263,28 @@ module GraphQL
221
263
  with_prepared_ast { @operations }
222
264
  end
223
265
 
266
+ def path
267
+ EmptyObjects::EMPTY_ARRAY
268
+ end
269
+
270
+ # Run subtree partials of this query and return their results.
271
+ # Each partial is identified with a `path:` and `object:`
272
+ # where the path references a field in the AST and the object will be treated
273
+ # as the return value from that field. Subfields of the field named by `path`
274
+ # will be executed with `object` as the starting point
275
+ # @param partials_hashes [Array<Hash{Symbol => Object}>] Hashes with `path:` and `object:` keys
276
+ # @return [Array<GraphQL::Query::Result>]
277
+ def run_partials(partials_hashes)
278
+ partials = partials_hashes.map { |partial_options| Partial.new(query: self, **partial_options) }
279
+ if context[:__graphql_execute_next]
280
+ Execution::Next.run_all(@schema, partials, context: @context)
281
+ else
282
+ Execution::Interpreter.run_all(@schema, partials, context: @context)
283
+ end
284
+ end
285
+
224
286
  # Get the result for this query, executing it once
225
- # @return [Hash] A GraphQL response, with `"data"` and/or `"errors"` keys
287
+ # @return [GraphQL::Query::Result] A Hash-like GraphQL response, with `"data"` and/or `"errors"` keys
226
288
  def result
227
289
  if !@executed
228
290
  Execution::Interpreter.run_all(@schema, [self], context: @context)
@@ -263,19 +325,6 @@ module GraphQL
263
325
  end
264
326
  end
265
327
 
266
- # Node-level cache for calculating arguments. Used during execution and query analysis.
267
- # @param ast_node [GraphQL::Language::Nodes::AbstractNode]
268
- # @param definition [GraphQL::Schema::Field]
269
- # @param parent_object [GraphQL::Schema::Object]
270
- # @return Hash{Symbol => Object}
271
- def arguments_for(ast_node, definition, parent_object: nil)
272
- arguments_cache.fetch(ast_node, definition, parent_object)
273
- end
274
-
275
- def arguments_cache
276
- @arguments_cache ||= Execution::Interpreter::ArgumentsCache.new(self)
277
- end
278
-
279
328
  # A version of the given query string, with:
280
329
  # - Variables inlined to the query
281
330
  # - Strings replaced with `<REDACTED>`
@@ -304,7 +353,7 @@ module GraphQL
304
353
 
305
354
  # @return [String] An opaque hash for identifying this query's given query string and selected operation
306
355
  def operation_fingerprint
307
- @operation_fingerprint ||= "#{selected_operation_name || "anonymous"}/#{Fingerprint.generate(query_string)}"
356
+ @operation_fingerprint ||= "#{selected_operation_name || "anonymous"}/#{Fingerprint.generate(query_string || "")}"
308
357
  end
309
358
 
310
359
  # @return [String] An opaque hash for identifying this query's given a variable values (not including defaults)
@@ -317,7 +366,7 @@ module GraphQL
317
366
  end
318
367
 
319
368
  def_delegators :validation_pipeline, :validation_errors,
320
- :analyzers, :ast_analyzers, :max_depth, :max_complexity
369
+ :analyzers, :ast_analyzers, :max_depth, :max_complexity, :validate_timeout_remaining
321
370
 
322
371
  attr_accessor :analysis_errors
323
372
  def valid?
@@ -328,7 +377,38 @@ module GraphQL
328
377
  with_prepared_ast { @warden }
329
378
  end
330
379
 
331
- def_delegators :warden, :get_type, :get_field, :possible_types, :root_type_for_operation
380
+ def get_type(type_name)
381
+ types.type(type_name) # rubocop:disable Development/ContextIsPassedCop
382
+ end
383
+
384
+ def get_field(owner, field_name)
385
+ types.field(owner, field_name) # rubocop:disable Development/ContextIsPassedCop
386
+ end
387
+
388
+ def possible_types(type)
389
+ types.possible_types(type) # rubocop:disable Development/ContextIsPassedCop
390
+ end
391
+
392
+ def root_type_for_operation(op_type)
393
+ case op_type
394
+ when "query", nil
395
+ types.query_root # rubocop:disable Development/ContextIsPassedCop
396
+ when "mutation"
397
+ types.mutation_root # rubocop:disable Development/ContextIsPassedCop
398
+ when "subscription"
399
+ types.subscription_root # rubocop:disable Development/ContextIsPassedCop
400
+ else
401
+ raise ArgumentError, "unexpected root type name: #{op_type.inspect}; expected nil, 'query', 'mutation', or 'subscription'"
402
+ end
403
+ end
404
+
405
+ def root_type
406
+ root_type_for_operation(selected_operation.operation_type)
407
+ end
408
+
409
+ def types
410
+ @visibility_profile || warden.visibility_profile
411
+ end
332
412
 
333
413
  # @param abstract_type [GraphQL::UnionType, GraphQL::InterfaceType]
334
414
  # @param value [Object] Any runtime value
@@ -354,37 +434,11 @@ module GraphQL
354
434
  with_prepared_ast { @query }
355
435
  end
356
436
 
357
- # @return [void]
358
- def merge_filters(only: nil, except: nil)
359
- if @prepared_ast
360
- raise "Can't add filters after preparing the query"
361
- else
362
- @filter ||= @schema.default_filter
363
- @filter = @filter.merge(only: only, except: except)
364
- end
365
- nil
366
- end
367
-
368
437
  def subscription?
369
438
  with_prepared_ast { @subscription }
370
439
  end
371
440
 
372
- # @api private
373
- def handle_or_reraise(err)
374
- schema.handle_or_reraise(context, err)
375
- end
376
-
377
- def after_lazy(value, &block)
378
- if !defined?(@runtime_instance)
379
- @runtime_instance = context.namespace(:interpreter_runtime)[:runtime]
380
- end
381
-
382
- if @runtime_instance
383
- @runtime_instance.minimal_after_lazy(value, &block)
384
- else
385
- @schema.after_lazy(value, &block)
386
- end
387
- end
441
+ attr_reader :logger
388
442
 
389
443
  private
390
444
 
@@ -400,11 +454,11 @@ module GraphQL
400
454
 
401
455
  def prepare_ast
402
456
  @prepared_ast = true
403
- @warden ||= @schema.warden_class.new(@filter, schema: @schema, context: @context)
457
+ @warden ||= @schema.warden_class.new(schema: @schema, context: @context)
404
458
  parse_error = nil
405
459
  @document ||= begin
406
460
  if query_string
407
- GraphQL.parse(query_string, trace: self.current_trace)
461
+ GraphQL.parse(query_string, trace: self.current_trace, max_tokens: @schema.max_query_string_tokens)
408
462
  end
409
463
  rescue GraphQL::ParseError => err
410
464
  parse_error = err
@@ -436,7 +490,7 @@ module GraphQL
436
490
  @mutation = false
437
491
  @subscription = false
438
492
  operation_name_error = nil
439
- if @operations.any?
493
+ if !@operations.empty?
440
494
  @selected_operation = find_operation(@operations, @operation_name)
441
495
  if @selected_operation.nil?
442
496
  operation_name_error = GraphQL::Query::OperationNameMissingError.new(@operation_name)
@@ -1,12 +1,22 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module GraphQL
4
+ # Support {GraphQL::Parser::Cache} and {GraphQL.eager_load!}
5
+ #
6
+ # @example Enable the parser cache with default directory
7
+ #
8
+ # config.graphql.parser_cache = true
9
+ #
3
10
  class Railtie < Rails::Railtie
4
- config.before_configuration do
5
- # Bootsnap compile cache has similar expiration properties,
6
- # so we assume that if the user has bootsnap setup it's ok
7
- # to piggy back on it.
8
- if ::Object.const_defined?("Bootsnap::CompileCache::ISeq") && Bootsnap::CompileCache::ISeq.cache_dir
9
- Language::Parser.cache ||= Language::Cache.new(Pathname.new(Bootsnap::CompileCache::ISeq.cache_dir).join('graphql'))
11
+ config.graphql = ActiveSupport::OrderedOptions.new
12
+ config.graphql.parser_cache = false
13
+ config.eager_load_namespaces << GraphQL
14
+
15
+ initializer("graphql.cache") do |app|
16
+ if config.graphql.parser_cache
17
+ Language::Parser.cache ||= Language::Cache.new(
18
+ app.root.join("tmp/cache/graphql")
19
+ )
10
20
  end
11
21
  end
12
22
  end
@@ -9,8 +9,7 @@ module GraphQL
9
9
  # By default, schemas are looked up by name as constants using `schema_name:`.
10
10
  # You can provide a `load_schema` function to return your schema another way.
11
11
  #
12
- # `load_context:`, `only:` and `except:` are supported so that
13
- # you can keep an eye on how filters affect your schema.
12
+ # Use `load_context:` and `visible?` to dump schemas under certain visibility constraints.
14
13
  #
15
14
  # @example Dump a Schema to .graphql + .json files
16
15
  # require "graphql/rake_task"
@@ -36,8 +35,6 @@ module GraphQL
36
35
  schema_name: nil,
37
36
  load_schema: ->(task) { Object.const_get(task.schema_name) },
38
37
  load_context: ->(task) { {} },
39
- only: nil,
40
- except: nil,
41
38
  directory: ".",
42
39
  idl_outfile: "schema.graphql",
43
40
  json_outfile: "schema.json",
@@ -68,12 +65,6 @@ module GraphQL
68
65
  # @return [<#call(task)>] A callable for loading the query context
69
66
  attr_accessor :load_context
70
67
 
71
- # @return [<#call(member, ctx)>, nil] A filter for this task
72
- attr_accessor :only
73
-
74
- # @return [<#call(member, ctx)>, nil] A filter for this task
75
- attr_accessor :except
76
-
77
68
  # @return [String] target for IDL task
78
69
  attr_accessor :idl_outfile
79
70
 
@@ -117,10 +108,10 @@ module GraphQL
117
108
  include_is_repeatable: include_is_repeatable,
118
109
  include_specified_by_url: include_specified_by_url,
119
110
  include_schema_description: include_schema_description,
120
- only: @only, except: @except, context: context
111
+ context: context
121
112
  )
122
113
  when :to_definition
123
- schema.to_definition(only: @only, except: @except, context: context)
114
+ schema.to_definition(context: context)
124
115
  else
125
116
  raise ArgumentError, "Unexpected schema dump method: #{method_name.inspect}"
126
117
  end
@@ -9,7 +9,7 @@ module GraphQL
9
9
 
10
10
  # Return the source of `send_node`, but without the keyword argument represented by `pair_node`
11
11
  def source_without_keyword_argument(send_node, pair_node)
12
- # work back to the preceeding comma
12
+ # work back to the preceding comma
13
13
  first_pos = pair_node.location.expression.begin_pos
14
14
  end_pos = pair_node.location.expression.end_pos
15
15
  node_source = send_node.source_range.source