graphql 1.9.0 → 2.1.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.

Potentially problematic release.


This version of graphql might be problematic. Click here for more details.

Files changed (723) hide show
  1. checksums.yaml +5 -5
  2. data/lib/generators/graphql/core.rb +21 -9
  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/install/templates/base_mutation.erb +12 -0
  8. data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +4 -0
  9. data/lib/generators/graphql/install_generator.rb +49 -9
  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 +66 -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 +8 -0
  22. data/lib/generators/graphql/templates/base_connection.erb +10 -0
  23. data/lib/generators/graphql/templates/base_edge.erb +10 -0
  24. data/lib/generators/graphql/templates/base_enum.erb +4 -0
  25. data/lib/generators/graphql/templates/base_field.erb +9 -0
  26. data/lib/generators/graphql/templates/base_input_object.erb +5 -0
  27. data/lib/generators/graphql/templates/base_interface.erb +6 -0
  28. data/lib/generators/graphql/templates/base_object.erb +5 -0
  29. data/lib/generators/graphql/templates/base_scalar.erb +4 -0
  30. data/lib/generators/graphql/templates/base_union.erb +4 -0
  31. data/lib/generators/graphql/templates/enum.erb +7 -1
  32. data/lib/generators/graphql/templates/graphql_controller.erb +23 -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 +4 -0
  36. data/lib/generators/graphql/templates/mutation.erb +5 -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 +11 -0
  41. data/lib/generators/graphql/templates/object.erb +7 -3
  42. data/lib/generators/graphql/templates/query_type.erb +5 -3
  43. data/lib/generators/graphql/templates/scalar.erb +5 -1
  44. data/lib/generators/graphql/templates/schema.erb +27 -27
  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/analyzer.rb +41 -12
  49. data/lib/graphql/analysis/ast/field_usage.rb +32 -3
  50. data/lib/graphql/analysis/ast/max_query_complexity.rb +4 -5
  51. data/lib/graphql/analysis/ast/max_query_depth.rb +7 -3
  52. data/lib/graphql/analysis/ast/query_complexity.rb +182 -66
  53. data/lib/graphql/analysis/ast/query_depth.rb +15 -26
  54. data/lib/graphql/analysis/ast/visitor.rb +83 -62
  55. data/lib/graphql/analysis/ast.rb +23 -20
  56. data/lib/graphql/analysis.rb +0 -7
  57. data/lib/graphql/backtrace/inspect_result.rb +0 -1
  58. data/lib/graphql/backtrace/table.rb +37 -16
  59. data/lib/graphql/backtrace/trace.rb +96 -0
  60. data/lib/graphql/backtrace/traced_error.rb +0 -1
  61. data/lib/graphql/backtrace/tracer.rb +39 -9
  62. data/lib/graphql/backtrace.rb +22 -18
  63. data/lib/graphql/coercion_error.rb +8 -0
  64. data/lib/graphql/dataloader/null_dataloader.rb +24 -0
  65. data/lib/graphql/dataloader/request.rb +19 -0
  66. data/lib/graphql/dataloader/request_all.rb +19 -0
  67. data/lib/graphql/dataloader/source.rb +195 -0
  68. data/lib/graphql/dataloader.rb +320 -0
  69. data/lib/graphql/date_encoding_error.rb +16 -0
  70. data/lib/graphql/deprecation.rb +9 -0
  71. data/lib/graphql/dig.rb +1 -1
  72. data/lib/graphql/execution/directive_checks.rb +2 -2
  73. data/lib/graphql/execution/errors.rb +93 -0
  74. data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
  75. data/lib/graphql/execution/interpreter/arguments.rb +88 -0
  76. data/lib/graphql/execution/interpreter/arguments_cache.rb +105 -0
  77. data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
  78. data/lib/graphql/execution/interpreter/resolve.rb +62 -24
  79. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +170 -0
  80. data/lib/graphql/execution/interpreter/runtime.rb +695 -392
  81. data/lib/graphql/execution/interpreter.rb +199 -74
  82. data/lib/graphql/execution/lazy/lazy_method_map.rb +4 -0
  83. data/lib/graphql/execution/lazy.rb +11 -21
  84. data/lib/graphql/execution/lookahead.rb +110 -150
  85. data/lib/graphql/execution/multiplex.rb +6 -148
  86. data/lib/graphql/execution.rb +12 -4
  87. data/lib/graphql/execution_error.rb +3 -2
  88. data/lib/graphql/integer_decoding_error.rb +17 -0
  89. data/lib/graphql/integer_encoding_error.rb +26 -2
  90. data/lib/graphql/introspection/base_object.rb +2 -5
  91. data/lib/graphql/introspection/directive_location_enum.rb +2 -2
  92. data/lib/graphql/introspection/directive_type.rb +12 -6
  93. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  94. data/lib/graphql/introspection/entry_points.rb +6 -18
  95. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  96. data/lib/graphql/introspection/field_type.rb +9 -5
  97. data/lib/graphql/introspection/input_value_type.rb +41 -7
  98. data/lib/graphql/introspection/introspection_query.rb +6 -92
  99. data/lib/graphql/introspection/schema_type.rb +13 -12
  100. data/lib/graphql/introspection/type_type.rb +34 -17
  101. data/lib/graphql/introspection.rb +100 -0
  102. data/lib/graphql/invalid_null_error.rb +18 -0
  103. data/lib/graphql/language/block_string.rb +50 -23
  104. data/lib/graphql/language/cache.rb +37 -0
  105. data/lib/graphql/language/definition_slice.rb +21 -10
  106. data/lib/graphql/language/document_from_schema_definition.rb +153 -87
  107. data/lib/graphql/language/lexer.rb +249 -1450
  108. data/lib/graphql/language/nodes.rb +152 -142
  109. data/lib/graphql/language/parser.rb +1036 -953
  110. data/lib/graphql/language/parser.y +159 -120
  111. data/lib/graphql/language/printer.rb +342 -154
  112. data/lib/graphql/language/sanitized_printer.rb +220 -0
  113. data/lib/graphql/language/static_visitor.rb +167 -0
  114. data/lib/graphql/language/token.rb +2 -2
  115. data/lib/graphql/language/visitor.rb +196 -140
  116. data/lib/graphql/language.rb +4 -1
  117. data/lib/graphql/load_application_object_failed_error.rb +22 -0
  118. data/lib/graphql/name_validator.rb +2 -7
  119. data/lib/graphql/pagination/active_record_relation_connection.rb +77 -0
  120. data/lib/graphql/pagination/array_connection.rb +79 -0
  121. data/lib/graphql/pagination/connection.rb +275 -0
  122. data/lib/graphql/pagination/connections.rb +135 -0
  123. data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
  124. data/lib/graphql/pagination/relation_connection.rb +228 -0
  125. data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
  126. data/lib/graphql/pagination.rb +6 -0
  127. data/lib/graphql/parse_error.rb +0 -1
  128. data/lib/graphql/query/context/scoped_context.rb +101 -0
  129. data/lib/graphql/query/context.rb +157 -187
  130. data/lib/graphql/query/fingerprint.rb +26 -0
  131. data/lib/graphql/query/input_validation_result.rb +33 -7
  132. data/lib/graphql/query/null_context.rb +21 -14
  133. data/lib/graphql/query/validation_pipeline.rb +17 -38
  134. data/lib/graphql/query/variable_validation_error.rb +17 -3
  135. data/lib/graphql/query/variables.rb +49 -14
  136. data/lib/graphql/query.rb +142 -61
  137. data/lib/graphql/railtie.rb +6 -102
  138. data/lib/graphql/rake_task/validate.rb +5 -2
  139. data/lib/graphql/rake_task.rb +42 -20
  140. data/lib/graphql/relay/range_add.rb +17 -10
  141. data/lib/graphql/relay.rb +0 -15
  142. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  143. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  144. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  145. data/lib/graphql/rubocop.rb +4 -0
  146. data/lib/graphql/schema/addition.rb +271 -0
  147. data/lib/graphql/schema/always_visible.rb +10 -0
  148. data/lib/graphql/schema/argument.rb +301 -32
  149. data/lib/graphql/schema/base_64_bp.rb +3 -2
  150. data/lib/graphql/schema/base_64_encoder.rb +2 -0
  151. data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
  152. data/lib/graphql/schema/build_from_definition/resolve_map.rb +13 -5
  153. data/lib/graphql/schema/build_from_definition.rb +349 -203
  154. data/lib/graphql/schema/built_in_types.rb +5 -5
  155. data/lib/graphql/schema/directive/deprecated.rb +18 -0
  156. data/lib/graphql/schema/directive/feature.rb +2 -2
  157. data/lib/graphql/schema/directive/flagged.rb +57 -0
  158. data/lib/graphql/schema/directive/include.rb +2 -2
  159. data/lib/graphql/schema/directive/one_of.rb +12 -0
  160. data/lib/graphql/schema/directive/skip.rb +2 -2
  161. data/lib/graphql/schema/directive/specified_by.rb +14 -0
  162. data/lib/graphql/schema/directive/transform.rb +14 -2
  163. data/lib/graphql/schema/directive.rb +134 -15
  164. data/lib/graphql/schema/enum.rb +137 -39
  165. data/lib/graphql/schema/enum_value.rb +17 -23
  166. data/lib/graphql/schema/field/connection_extension.rb +36 -20
  167. data/lib/graphql/schema/field/scope_extension.rb +15 -5
  168. data/lib/graphql/schema/field.rb +570 -334
  169. data/lib/graphql/schema/field_extension.rb +88 -4
  170. data/lib/graphql/schema/find_inherited_value.rb +31 -0
  171. data/lib/graphql/schema/finder.rb +16 -14
  172. data/lib/graphql/schema/has_single_input_argument.rb +156 -0
  173. data/lib/graphql/schema/input_object.rb +190 -48
  174. data/lib/graphql/schema/interface.rb +24 -49
  175. data/lib/graphql/schema/introspection_system.rb +109 -36
  176. data/lib/graphql/schema/late_bound_type.rb +9 -2
  177. data/lib/graphql/schema/list.rb +61 -3
  178. data/lib/graphql/schema/loader.rb +146 -97
  179. data/lib/graphql/schema/member/base_dsl_methods.rb +45 -51
  180. data/lib/graphql/schema/member/build_type.rb +34 -17
  181. data/lib/graphql/schema/member/has_arguments.rb +385 -10
  182. data/lib/graphql/schema/member/has_ast_node.rb +32 -0
  183. data/lib/graphql/schema/member/has_deprecation_reason.rb +24 -0
  184. data/lib/graphql/schema/member/has_directives.rb +118 -0
  185. data/lib/graphql/schema/member/has_fields.rb +180 -35
  186. data/lib/graphql/schema/member/has_interfaces.rb +143 -0
  187. data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
  188. data/lib/graphql/schema/member/has_validators.rb +57 -0
  189. data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
  190. data/lib/graphql/schema/member/scoped.rb +19 -0
  191. data/lib/graphql/schema/member/type_system_helpers.rb +20 -3
  192. data/lib/graphql/schema/member/validates_input.rb +33 -0
  193. data/lib/graphql/schema/member.rb +11 -6
  194. data/lib/graphql/schema/mutation.rb +4 -9
  195. data/lib/graphql/schema/non_null.rb +34 -4
  196. data/lib/graphql/schema/object.rb +55 -64
  197. data/lib/graphql/schema/printer.rb +26 -40
  198. data/lib/graphql/schema/relay_classic_mutation.rb +13 -80
  199. data/lib/graphql/schema/resolver/has_payload_type.rb +53 -12
  200. data/lib/graphql/schema/resolver.rb +182 -162
  201. data/lib/graphql/schema/scalar.rb +40 -15
  202. data/lib/graphql/schema/subscription.rb +85 -27
  203. data/lib/graphql/schema/timeout.rb +119 -0
  204. data/lib/graphql/schema/type_expression.rb +21 -13
  205. data/lib/graphql/schema/type_membership.rb +51 -0
  206. data/lib/graphql/schema/union.rb +69 -15
  207. data/lib/graphql/schema/unique_within_type.rb +1 -2
  208. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  209. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  210. data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
  211. data/lib/graphql/schema/validator/format_validator.rb +48 -0
  212. data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
  213. data/lib/graphql/schema/validator/length_validator.rb +59 -0
  214. data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
  215. data/lib/graphql/schema/validator/required_validator.rb +82 -0
  216. data/lib/graphql/schema/validator.rb +171 -0
  217. data/lib/graphql/schema/warden.rb +330 -59
  218. data/lib/graphql/schema/wrapper.rb +0 -5
  219. data/lib/graphql/schema.rb +985 -858
  220. data/lib/graphql/static_validation/all_rules.rb +4 -1
  221. data/lib/graphql/static_validation/base_visitor.rb +33 -32
  222. data/lib/graphql/static_validation/definition_dependencies.rb +28 -14
  223. data/lib/graphql/static_validation/error.rb +3 -1
  224. data/lib/graphql/static_validation/literal_validator.rb +71 -28
  225. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +46 -79
  226. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +23 -6
  227. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +35 -26
  228. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
  229. data/lib/graphql/static_validation/rules/directives_are_defined.rb +12 -6
  230. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +14 -14
  231. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +4 -4
  232. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +15 -7
  233. data/lib/graphql/static_validation/rules/fields_will_merge.rb +107 -57
  234. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
  235. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  236. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
  237. data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
  238. data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
  239. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  240. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  241. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  242. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  243. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +6 -4
  244. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +22 -10
  245. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +13 -7
  246. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +12 -13
  247. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +19 -14
  248. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  249. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +5 -3
  250. data/lib/graphql/static_validation/validation_context.rb +17 -7
  251. data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
  252. data/lib/graphql/static_validation/validator.rb +32 -20
  253. data/lib/graphql/static_validation.rb +1 -3
  254. data/lib/graphql/string_encoding_error.rb +13 -3
  255. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +134 -24
  256. data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
  257. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +58 -0
  258. data/lib/graphql/subscriptions/event.rb +90 -27
  259. data/lib/graphql/subscriptions/instrumentation.rb +0 -47
  260. data/lib/graphql/subscriptions/serialize.rb +53 -6
  261. data/lib/graphql/subscriptions.rb +147 -62
  262. data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
  263. data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -17
  264. data/lib/graphql/tracing/appoptics_trace.rb +251 -0
  265. data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
  266. data/lib/graphql/tracing/appsignal_trace.rb +77 -0
  267. data/lib/graphql/tracing/appsignal_tracing.rb +23 -0
  268. data/lib/graphql/tracing/data_dog_trace.rb +196 -0
  269. data/lib/graphql/tracing/data_dog_tracing.rb +53 -2
  270. data/lib/graphql/tracing/legacy_trace.rb +69 -0
  271. data/lib/graphql/tracing/new_relic_trace.rb +75 -0
  272. data/lib/graphql/tracing/new_relic_tracing.rb +9 -12
  273. data/lib/graphql/tracing/notifications_trace.rb +45 -0
  274. data/lib/graphql/tracing/notifications_tracing.rb +59 -0
  275. data/lib/graphql/tracing/platform_trace.rb +118 -0
  276. data/lib/graphql/tracing/platform_tracing.rb +77 -31
  277. data/lib/graphql/tracing/prometheus_trace.rb +89 -0
  278. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +5 -2
  279. data/lib/graphql/tracing/prometheus_tracing.rb +11 -3
  280. data/lib/graphql/tracing/scout_trace.rb +72 -0
  281. data/lib/graphql/tracing/scout_tracing.rb +19 -0
  282. data/lib/graphql/tracing/statsd_trace.rb +56 -0
  283. data/lib/graphql/tracing/statsd_tracing.rb +42 -0
  284. data/lib/graphql/tracing/trace.rb +75 -0
  285. data/lib/graphql/tracing.rb +24 -67
  286. data/lib/graphql/type_kinds.rb +6 -3
  287. data/lib/graphql/types/big_int.rb +23 -0
  288. data/lib/graphql/types/int.rb +11 -3
  289. data/lib/graphql/types/iso_8601_date.rb +45 -0
  290. data/lib/graphql/types/iso_8601_date_time.rb +36 -8
  291. data/lib/graphql/types/json.rb +25 -0
  292. data/lib/graphql/types/relay/base_connection.rb +18 -90
  293. data/lib/graphql/types/relay/base_edge.rb +2 -36
  294. data/lib/graphql/types/relay/connection_behaviors.rb +193 -0
  295. data/lib/graphql/types/relay/edge_behaviors.rb +82 -0
  296. data/lib/graphql/types/relay/has_node_field.rb +41 -0
  297. data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
  298. data/lib/graphql/types/relay/node.rb +2 -4
  299. data/lib/graphql/types/relay/node_behaviors.rb +25 -0
  300. data/lib/graphql/types/relay/page_info.rb +2 -14
  301. data/lib/graphql/types/relay/page_info_behaviors.rb +30 -0
  302. data/lib/graphql/types/relay.rb +10 -5
  303. data/lib/graphql/types/string.rb +8 -2
  304. data/lib/graphql/types.rb +3 -0
  305. data/lib/graphql/unauthorized_error.rb +3 -3
  306. data/lib/graphql/unauthorized_field_error.rb +1 -1
  307. data/lib/graphql/unresolved_type_error.rb +2 -2
  308. data/lib/graphql/version.rb +1 -1
  309. data/lib/graphql.rb +68 -54
  310. data/readme.md +4 -7
  311. metadata +150 -822
  312. data/lib/graphql/analysis/analyze_query.rb +0 -91
  313. data/lib/graphql/analysis/field_usage.rb +0 -45
  314. data/lib/graphql/analysis/max_query_complexity.rb +0 -26
  315. data/lib/graphql/analysis/max_query_depth.rb +0 -26
  316. data/lib/graphql/analysis/query_complexity.rb +0 -88
  317. data/lib/graphql/analysis/query_depth.rb +0 -56
  318. data/lib/graphql/analysis/reducer_state.rb +0 -48
  319. data/lib/graphql/argument.rb +0 -153
  320. data/lib/graphql/authorization.rb +0 -82
  321. data/lib/graphql/backwards_compatibility.rb +0 -60
  322. data/lib/graphql/base_type.rb +0 -226
  323. data/lib/graphql/boolean_type.rb +0 -2
  324. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  325. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  326. data/lib/graphql/compatibility/execution_specification.rb +0 -435
  327. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  328. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -213
  329. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -91
  330. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  331. data/lib/graphql/compatibility/query_parser_specification.rb +0 -264
  332. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -680
  333. data/lib/graphql/compatibility.rb +0 -5
  334. data/lib/graphql/define/assign_argument.rb +0 -12
  335. data/lib/graphql/define/assign_connection.rb +0 -13
  336. data/lib/graphql/define/assign_enum_value.rb +0 -18
  337. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  338. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  339. data/lib/graphql/define/assign_object_field.rb +0 -42
  340. data/lib/graphql/define/defined_object_proxy.rb +0 -50
  341. data/lib/graphql/define/instance_definable.rb +0 -300
  342. data/lib/graphql/define/no_definition_error.rb +0 -7
  343. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  344. data/lib/graphql/define/type_definer.rb +0 -31
  345. data/lib/graphql/define.rb +0 -31
  346. data/lib/graphql/deprecated_dsl.rb +0 -42
  347. data/lib/graphql/directive/deprecated_directive.rb +0 -13
  348. data/lib/graphql/directive/include_directive.rb +0 -2
  349. data/lib/graphql/directive/skip_directive.rb +0 -2
  350. data/lib/graphql/directive.rb +0 -104
  351. data/lib/graphql/enum_type.rb +0 -193
  352. data/lib/graphql/execution/execute.rb +0 -319
  353. data/lib/graphql/execution/flatten.rb +0 -40
  354. data/lib/graphql/execution/instrumentation.rb +0 -92
  355. data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
  356. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  357. data/lib/graphql/execution/typecast.rb +0 -50
  358. data/lib/graphql/field/resolve.rb +0 -59
  359. data/lib/graphql/field.rb +0 -330
  360. data/lib/graphql/filter.rb +0 -53
  361. data/lib/graphql/float_type.rb +0 -2
  362. data/lib/graphql/function.rb +0 -153
  363. data/lib/graphql/id_type.rb +0 -2
  364. data/lib/graphql/input_object_type.rb +0 -153
  365. data/lib/graphql/int_type.rb +0 -2
  366. data/lib/graphql/interface_type.rb +0 -86
  367. data/lib/graphql/internal_representation/document.rb +0 -27
  368. data/lib/graphql/internal_representation/node.rb +0 -206
  369. data/lib/graphql/internal_representation/print.rb +0 -51
  370. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  371. data/lib/graphql/internal_representation/scope.rb +0 -88
  372. data/lib/graphql/internal_representation/visit.rb +0 -36
  373. data/lib/graphql/internal_representation.rb +0 -7
  374. data/lib/graphql/language/lexer.rl +0 -236
  375. data/lib/graphql/list_type.rb +0 -80
  376. data/lib/graphql/literal_validation_error.rb +0 -6
  377. data/lib/graphql/non_null_type.rb +0 -81
  378. data/lib/graphql/object_type.rb +0 -141
  379. data/lib/graphql/query/arguments.rb +0 -179
  380. data/lib/graphql/query/arguments_cache.rb +0 -25
  381. data/lib/graphql/query/executor.rb +0 -53
  382. data/lib/graphql/query/literal_input.rb +0 -115
  383. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  384. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  385. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  386. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  387. data/lib/graphql/query/serial_execution.rb +0 -39
  388. data/lib/graphql/relay/array_connection.rb +0 -85
  389. data/lib/graphql/relay/base_connection.rb +0 -172
  390. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  391. data/lib/graphql/relay/connection_resolve.rb +0 -43
  392. data/lib/graphql/relay/connection_type.rb +0 -40
  393. data/lib/graphql/relay/edge.rb +0 -27
  394. data/lib/graphql/relay/edge_type.rb +0 -18
  395. data/lib/graphql/relay/edges_instrumentation.rb +0 -40
  396. data/lib/graphql/relay/global_id_resolve.rb +0 -18
  397. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  398. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  399. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  400. data/lib/graphql/relay/mutation/result.rb +0 -38
  401. data/lib/graphql/relay/mutation.rb +0 -190
  402. data/lib/graphql/relay/node.rb +0 -36
  403. data/lib/graphql/relay/page_info.rb +0 -7
  404. data/lib/graphql/relay/relation_connection.rb +0 -186
  405. data/lib/graphql/relay/type_extensions.rb +0 -30
  406. data/lib/graphql/scalar_type.rb +0 -135
  407. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  408. data/lib/graphql/schema/default_parse_error.rb +0 -10
  409. data/lib/graphql/schema/default_type_error.rb +0 -15
  410. data/lib/graphql/schema/member/accepts_definition.rb +0 -152
  411. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -26
  412. data/lib/graphql/schema/member/instrumentation.rb +0 -121
  413. data/lib/graphql/schema/middleware_chain.rb +0 -82
  414. data/lib/graphql/schema/possible_types.rb +0 -39
  415. data/lib/graphql/schema/rescue_middleware.rb +0 -55
  416. data/lib/graphql/schema/timeout_middleware.rb +0 -85
  417. data/lib/graphql/schema/traversal.rb +0 -228
  418. data/lib/graphql/schema/validation.rb +0 -286
  419. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  420. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  421. data/lib/graphql/static_validation/type_stack.rb +0 -216
  422. data/lib/graphql/string_type.rb +0 -2
  423. data/lib/graphql/subscriptions/subscription_root.rb +0 -66
  424. data/lib/graphql/tracing/skylight_tracing.rb +0 -61
  425. data/lib/graphql/types/relay/base_field.rb +0 -22
  426. data/lib/graphql/types/relay/base_interface.rb +0 -29
  427. data/lib/graphql/types/relay/base_object.rb +0 -26
  428. data/lib/graphql/types/relay/node_field.rb +0 -43
  429. data/lib/graphql/types/relay/nodes_field.rb +0 -45
  430. data/lib/graphql/union_type.rb +0 -100
  431. data/lib/graphql/upgrader/member.rb +0 -899
  432. data/lib/graphql/upgrader/schema.rb +0 -37
  433. data/spec/dummy/Gemfile +0 -12
  434. data/spec/dummy/Gemfile.lock +0 -157
  435. data/spec/dummy/README.md +0 -24
  436. data/spec/dummy/Rakefile +0 -7
  437. data/spec/dummy/app/assets/config/manifest.js +0 -1
  438. data/spec/dummy/app/assets/javascripts/application.js +0 -66
  439. data/spec/dummy/app/channels/application_cable/channel.rb +0 -5
  440. data/spec/dummy/app/channels/application_cable/connection.rb +0 -5
  441. data/spec/dummy/app/channels/graphql_channel.rb +0 -116
  442. data/spec/dummy/app/controllers/application_controller.rb +0 -4
  443. data/spec/dummy/app/controllers/pages_controller.rb +0 -5
  444. data/spec/dummy/app/helpers/application_helper.rb +0 -3
  445. data/spec/dummy/app/jobs/application_job.rb +0 -3
  446. data/spec/dummy/app/views/layouts/application.html.erb +0 -12
  447. data/spec/dummy/app/views/pages/show.html +0 -16
  448. data/spec/dummy/bin/bundle +0 -4
  449. data/spec/dummy/bin/rails +0 -5
  450. data/spec/dummy/bin/rake +0 -5
  451. data/spec/dummy/bin/setup +0 -31
  452. data/spec/dummy/bin/update +0 -27
  453. data/spec/dummy/bin/yarn +0 -12
  454. data/spec/dummy/config/application.rb +0 -30
  455. data/spec/dummy/config/boot.rb +0 -4
  456. data/spec/dummy/config/cable.yml +0 -10
  457. data/spec/dummy/config/environment.rb +0 -6
  458. data/spec/dummy/config/environments/development.rb +0 -40
  459. data/spec/dummy/config/environments/production.rb +0 -76
  460. data/spec/dummy/config/environments/test.rb +0 -37
  461. data/spec/dummy/config/initializers/application_controller_renderer.rb +0 -9
  462. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -8
  463. data/spec/dummy/config/initializers/cookies_serializer.rb +0 -6
  464. data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -5
  465. data/spec/dummy/config/initializers/inflections.rb +0 -17
  466. data/spec/dummy/config/initializers/mime_types.rb +0 -5
  467. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -10
  468. data/spec/dummy/config/locales/en.yml +0 -33
  469. data/spec/dummy/config/puma.rb +0 -57
  470. data/spec/dummy/config/routes.rb +0 -4
  471. data/spec/dummy/config/secrets.yml +0 -32
  472. data/spec/dummy/config.ru +0 -6
  473. data/spec/dummy/log/test.log +0 -199
  474. data/spec/dummy/package.json +0 -5
  475. data/spec/dummy/public/404.html +0 -67
  476. data/spec/dummy/public/422.html +0 -67
  477. data/spec/dummy/public/500.html +0 -66
  478. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  479. data/spec/dummy/public/apple-touch-icon.png +0 -0
  480. data/spec/dummy/public/favicon.ico +0 -0
  481. data/spec/dummy/public/robots.txt +0 -1
  482. data/spec/dummy/test/application_system_test_case.rb +0 -6
  483. data/spec/dummy/test/system/action_cable_subscription_test.rb +0 -45
  484. data/spec/dummy/test/test_helper.rb +0 -4
  485. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4w/4wzXRZrAkwKdgYaSE0pid5eB-fer8vSfSku_NPg4rMA.cache +0 -0
  486. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7I/7IHVBiJT06QSpgLpLoJIxboQ0B-D_tMTxsvoezBTV3Q.cache +0 -1
  487. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8w/8wY_SKagj8wHuwGNAAf6JnQ8joMbC6cEYpHrTAI8Urc.cache +0 -1
  488. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/AK/AKzz1u6bGb4auXcrObA_g5LL-oV0ejNGa448AgAi_WQ.cache +0 -1
  489. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ET/ETW4uxvaYpruL8y6_ZptUH82ZowMaHIqvg5WexBFdEM.cache +0 -3
  490. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F1/F1TWpjjyA56k9Z90n5B3xRn7DUdGjX73QCkYC6k07JQ.cache +0 -0
  491. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F8/F8MUNRzORGFgr329fNM0xLaoWCXdv3BIalT7dsvLfjs.cache +0 -2
  492. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/KB/KB07ZaKNC5uXJ7TjLi-WqnY6g7dq8wWp_8N3HNjBNxg.cache +0 -2
  493. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ms/MsKSimH_UCB-H1tLvDABDHuvGciuoW6kVqQWDrXU5FQ.cache +0 -0
  494. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Mt/Mtci-Kim50aPOmeClD4AIicKn1d1WJ0n454IjSd94sk.cache +0 -0
  495. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/QH/QHt3Tc1Y6M66Oo_pDuMyWrQNs4Pp3SMeZR5K1wJj2Ts.cache +0 -1
  496. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/XU/XU4k1OXnfMils5SrirorPvDSyDSqiOWLZNtmAH1HH8k.cache +0 -0
  497. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ZI/ZIof7mZxWWCnraIFOCuV6a8QRWzKJXJnx2Xd7C0ZyX0.cache +0 -1
  498. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/cG/cGc_puuPS5pZKgUcy1Y_i1L6jl5UtsiIrMH59rTzR6c.cache +0 -3
  499. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/df/dfro_B6bx3KP1Go-7jEOqqZ2j4hVRseXIc3es9PKQno.cache +0 -1
  500. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jO/jO1DfbqnG0mTULsjJJANc3fefrG2zt7DIMmcptMT628.cache +0 -1
  501. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/pE/pE7gO6pQ-z187Swb4hT554wmqsq-cNzgPWLrCz-LQQQ.cache +0 -0
  502. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/r9/r9iU1l58a6rxkZSW5RSC52_tD-_UQuHxoMVnkfJ7Mhs.cache +0 -1
  503. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xi/xitPPFfPIyDMpaznV0sBBcw8eSCV8PJcLLWin78sCgE.cache +0 -0
  504. data/spec/dummy/tmp/screenshots/failures_test_it_handles_subscriptions.png +0 -0
  505. data/spec/fixtures/upgrader/account.original.rb +0 -19
  506. data/spec/fixtures/upgrader/account.transformed.rb +0 -20
  507. data/spec/fixtures/upgrader/blame_range.original.rb +0 -43
  508. data/spec/fixtures/upgrader/blame_range.transformed.rb +0 -30
  509. data/spec/fixtures/upgrader/date_time.original.rb +0 -24
  510. data/spec/fixtures/upgrader/date_time.transformed.rb +0 -23
  511. data/spec/fixtures/upgrader/delete_project.original.rb +0 -28
  512. data/spec/fixtures/upgrader/delete_project.transformed.rb +0 -27
  513. data/spec/fixtures/upgrader/gist_order_field.original.rb +0 -14
  514. data/spec/fixtures/upgrader/gist_order_field.transformed.rb +0 -13
  515. data/spec/fixtures/upgrader/increment_count.original.rb +0 -59
  516. data/spec/fixtures/upgrader/increment_count.transformed.rb +0 -50
  517. data/spec/fixtures/upgrader/photo.original.rb +0 -10
  518. data/spec/fixtures/upgrader/photo.transformed.rb +0 -12
  519. data/spec/fixtures/upgrader/release_order.original.rb +0 -15
  520. data/spec/fixtures/upgrader/release_order.transformed.rb +0 -14
  521. data/spec/fixtures/upgrader/starrable.original.rb +0 -49
  522. data/spec/fixtures/upgrader/starrable.transformed.rb +0 -46
  523. data/spec/fixtures/upgrader/subscribable.original.rb +0 -55
  524. data/spec/fixtures/upgrader/subscribable.transformed.rb +0 -51
  525. data/spec/fixtures/upgrader/type_x.original.rb +0 -65
  526. data/spec/fixtures/upgrader/type_x.transformed.rb +0 -56
  527. data/spec/graphql/analysis/analyze_query_spec.rb +0 -272
  528. data/spec/graphql/analysis/ast/field_usage_spec.rb +0 -51
  529. data/spec/graphql/analysis/ast/max_query_complexity_spec.rb +0 -120
  530. data/spec/graphql/analysis/ast/max_query_depth_spec.rb +0 -114
  531. data/spec/graphql/analysis/ast/query_complexity_spec.rb +0 -299
  532. data/spec/graphql/analysis/ast/query_depth_spec.rb +0 -108
  533. data/spec/graphql/analysis/ast_spec.rb +0 -269
  534. data/spec/graphql/analysis/field_usage_spec.rb +0 -62
  535. data/spec/graphql/analysis/max_query_complexity_spec.rb +0 -102
  536. data/spec/graphql/analysis/max_query_depth_spec.rb +0 -101
  537. data/spec/graphql/analysis/query_complexity_spec.rb +0 -301
  538. data/spec/graphql/analysis/query_depth_spec.rb +0 -81
  539. data/spec/graphql/argument_spec.rb +0 -159
  540. data/spec/graphql/authorization_spec.rb +0 -901
  541. data/spec/graphql/backtrace_spec.rb +0 -206
  542. data/spec/graphql/base_type_spec.rb +0 -171
  543. data/spec/graphql/boolean_type_spec.rb +0 -21
  544. data/spec/graphql/compatibility/execution_specification_spec.rb +0 -4
  545. data/spec/graphql/compatibility/lazy_execution_specification_spec.rb +0 -4
  546. data/spec/graphql/compatibility/query_parser_specification_spec.rb +0 -6
  547. data/spec/graphql/compatibility/schema_parser_specification_spec.rb +0 -6
  548. data/spec/graphql/define/assign_argument_spec.rb +0 -61
  549. data/spec/graphql/define/instance_definable_spec.rb +0 -203
  550. data/spec/graphql/directive/skip_directive_spec.rb +0 -9
  551. data/spec/graphql/directive_spec.rb +0 -295
  552. data/spec/graphql/enum_type_spec.rb +0 -158
  553. data/spec/graphql/execution/execute_spec.rb +0 -303
  554. data/spec/graphql/execution/instrumentation_spec.rb +0 -184
  555. data/spec/graphql/execution/interpreter_spec.rb +0 -485
  556. data/spec/graphql/execution/lazy/lazy_method_map_spec.rb +0 -57
  557. data/spec/graphql/execution/lazy_spec.rb +0 -240
  558. data/spec/graphql/execution/lookahead_spec.rb +0 -363
  559. data/spec/graphql/execution/multiplex_spec.rb +0 -211
  560. data/spec/graphql/execution/typecast_spec.rb +0 -47
  561. data/spec/graphql/execution_error_spec.rb +0 -325
  562. data/spec/graphql/field_spec.rb +0 -246
  563. data/spec/graphql/float_type_spec.rb +0 -16
  564. data/spec/graphql/function_spec.rb +0 -129
  565. data/spec/graphql/id_type_spec.rb +0 -33
  566. data/spec/graphql/input_object_type_spec.rb +0 -25
  567. data/spec/graphql/int_type_spec.rb +0 -35
  568. data/spec/graphql/interface_type_spec.rb +0 -196
  569. data/spec/graphql/internal_representation/print_spec.rb +0 -41
  570. data/spec/graphql/internal_representation/rewrite_spec.rb +0 -376
  571. data/spec/graphql/introspection/directive_type_spec.rb +0 -61
  572. data/spec/graphql/introspection/input_value_type_spec.rb +0 -105
  573. data/spec/graphql/introspection/introspection_query_spec.rb +0 -59
  574. data/spec/graphql/introspection/schema_type_spec.rb +0 -56
  575. data/spec/graphql/introspection/type_type_spec.rb +0 -155
  576. data/spec/graphql/language/block_string_spec.rb +0 -70
  577. data/spec/graphql/language/definition_slice_spec.rb +0 -226
  578. data/spec/graphql/language/document_from_schema_definition_spec.rb +0 -770
  579. data/spec/graphql/language/equality_spec.rb +0 -84
  580. data/spec/graphql/language/generation_spec.rb +0 -38
  581. data/spec/graphql/language/lexer_spec.rb +0 -135
  582. data/spec/graphql/language/nodes_spec.rb +0 -67
  583. data/spec/graphql/language/parser_spec.rb +0 -175
  584. data/spec/graphql/language/printer_spec.rb +0 -215
  585. data/spec/graphql/language/visitor_spec.rb +0 -400
  586. data/spec/graphql/list_type_spec.rb +0 -57
  587. data/spec/graphql/non_null_type_spec.rb +0 -48
  588. data/spec/graphql/object_type_spec.rb +0 -197
  589. data/spec/graphql/query/arguments_spec.rb +0 -346
  590. data/spec/graphql/query/context_spec.rb +0 -292
  591. data/spec/graphql/query/executor_spec.rb +0 -314
  592. data/spec/graphql/query/literal_input_spec.rb +0 -91
  593. data/spec/graphql/query/result_spec.rb +0 -29
  594. data/spec/graphql/query/serial_execution/value_resolution_spec.rb +0 -109
  595. data/spec/graphql/query_spec.rb +0 -800
  596. data/spec/graphql/rake_task_spec.rb +0 -59
  597. data/spec/graphql/scalar_type_spec.rb +0 -66
  598. data/spec/graphql/schema/argument_spec.rb +0 -127
  599. data/spec/graphql/schema/build_from_definition_spec.rb +0 -1187
  600. data/spec/graphql/schema/catchall_middleware_spec.rb +0 -35
  601. data/spec/graphql/schema/directive/feature_spec.rb +0 -81
  602. data/spec/graphql/schema/directive/transform_spec.rb +0 -39
  603. data/spec/graphql/schema/enum_spec.rb +0 -83
  604. data/spec/graphql/schema/enum_value_spec.rb +0 -24
  605. data/spec/graphql/schema/field_extension_spec.rb +0 -115
  606. data/spec/graphql/schema/field_spec.rb +0 -301
  607. data/spec/graphql/schema/finder_spec.rb +0 -135
  608. data/spec/graphql/schema/input_object_spec.rb +0 -238
  609. data/spec/graphql/schema/instrumentation_spec.rb +0 -43
  610. data/spec/graphql/schema/interface_spec.rb +0 -215
  611. data/spec/graphql/schema/introspection_system_spec.rb +0 -47
  612. data/spec/graphql/schema/list_spec.rb +0 -46
  613. data/spec/graphql/schema/loader_spec.rb +0 -286
  614. data/spec/graphql/schema/member/accepts_definition_spec.rb +0 -115
  615. data/spec/graphql/schema/member/build_type_spec.rb +0 -63
  616. data/spec/graphql/schema/member/scoped_spec.rb +0 -177
  617. data/spec/graphql/schema/member/type_system_helpers_spec.rb +0 -63
  618. data/spec/graphql/schema/middleware_chain_spec.rb +0 -57
  619. data/spec/graphql/schema/mutation_spec.rb +0 -150
  620. data/spec/graphql/schema/non_null_spec.rb +0 -46
  621. data/spec/graphql/schema/object_spec.rb +0 -244
  622. data/spec/graphql/schema/printer_spec.rb +0 -869
  623. data/spec/graphql/schema/relay_classic_mutation_spec.rb +0 -234
  624. data/spec/graphql/schema/rescue_middleware_spec.rb +0 -74
  625. data/spec/graphql/schema/resolver_spec.rb +0 -640
  626. data/spec/graphql/schema/scalar_spec.rb +0 -101
  627. data/spec/graphql/schema/subscription_spec.rb +0 -416
  628. data/spec/graphql/schema/timeout_middleware_spec.rb +0 -188
  629. data/spec/graphql/schema/traversal_spec.rb +0 -222
  630. data/spec/graphql/schema/type_expression_spec.rb +0 -39
  631. data/spec/graphql/schema/union_spec.rb +0 -72
  632. data/spec/graphql/schema/unique_within_type_spec.rb +0 -44
  633. data/spec/graphql/schema/validation_spec.rb +0 -355
  634. data/spec/graphql/schema/warden_spec.rb +0 -926
  635. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +0 -413
  636. data/spec/graphql/static_validation/rules/argument_names_are_unique_spec.rb +0 -44
  637. data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +0 -112
  638. data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +0 -35
  639. data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +0 -42
  640. data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +0 -167
  641. data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +0 -66
  642. data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +0 -740
  643. data/spec/graphql/static_validation/rules/fragment_names_are_unique_spec.rb +0 -28
  644. data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +0 -52
  645. data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +0 -42
  646. data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +0 -123
  647. data/spec/graphql/static_validation/rules/fragments_are_named_spec.rb +0 -24
  648. data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +0 -56
  649. data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +0 -61
  650. data/spec/graphql/static_validation/rules/mutation_root_exists_spec.rb +0 -39
  651. data/spec/graphql/static_validation/rules/no_definitions_are_present_spec.rb +0 -62
  652. data/spec/graphql/static_validation/rules/operation_names_are_valid_spec.rb +0 -82
  653. data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +0 -73
  654. data/spec/graphql/static_validation/rules/required_input_object_attributes_are_present_spec.rb +0 -58
  655. data/spec/graphql/static_validation/rules/subscription_root_exists_spec.rb +0 -34
  656. data/spec/graphql/static_validation/rules/unique_directives_per_location_spec.rb +0 -188
  657. data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +0 -196
  658. data/spec/graphql/static_validation/rules/variable_names_are_unique_spec.rb +0 -23
  659. data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +0 -236
  660. data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +0 -78
  661. data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +0 -81
  662. data/spec/graphql/static_validation/type_stack_spec.rb +0 -29
  663. data/spec/graphql/static_validation/validator_spec.rb +0 -204
  664. data/spec/graphql/string_type_spec.rb +0 -80
  665. data/spec/graphql/subscriptions/serialize_spec.rb +0 -49
  666. data/spec/graphql/subscriptions_spec.rb +0 -502
  667. data/spec/graphql/tracing/new_relic_tracing_spec.rb +0 -63
  668. data/spec/graphql/tracing/platform_tracing_spec.rb +0 -137
  669. data/spec/graphql/tracing/prometheus_tracing_spec.rb +0 -42
  670. data/spec/graphql/tracing/scout_tracing_spec.rb +0 -17
  671. data/spec/graphql/tracing/skylight_tracing_spec.rb +0 -63
  672. data/spec/graphql/tracing_spec.rb +0 -52
  673. data/spec/graphql/types/iso_8601_date_time_spec.rb +0 -137
  674. data/spec/graphql/union_type_spec.rb +0 -211
  675. data/spec/graphql/upgrader/member_spec.rb +0 -583
  676. data/spec/graphql/upgrader/schema_spec.rb +0 -82
  677. data/spec/integration/mongoid/graphql/relay/mongo_relation_connection_spec.rb +0 -528
  678. data/spec/integration/mongoid/spec_helper.rb +0 -2
  679. data/spec/integration/mongoid/star_trek/data.rb +0 -126
  680. data/spec/integration/mongoid/star_trek/schema.rb +0 -425
  681. data/spec/integration/rails/data.rb +0 -110
  682. data/spec/integration/rails/generators/base_generator_test.rb +0 -7
  683. data/spec/integration/rails/generators/graphql/enum_generator_spec.rb +0 -30
  684. data/spec/integration/rails/generators/graphql/install_generator_spec.rb +0 -218
  685. data/spec/integration/rails/generators/graphql/interface_generator_spec.rb +0 -34
  686. data/spec/integration/rails/generators/graphql/loader_generator_spec.rb +0 -59
  687. data/spec/integration/rails/generators/graphql/mutation_generator_spec.rb +0 -71
  688. data/spec/integration/rails/generators/graphql/object_generator_spec.rb +0 -54
  689. data/spec/integration/rails/generators/graphql/scalar_generator_spec.rb +0 -28
  690. data/spec/integration/rails/generators/graphql/union_generator_spec.rb +0 -67
  691. data/spec/integration/rails/graphql/input_object_type_spec.rb +0 -364
  692. data/spec/integration/rails/graphql/query/variables_spec.rb +0 -375
  693. data/spec/integration/rails/graphql/relay/array_connection_spec.rb +0 -290
  694. data/spec/integration/rails/graphql/relay/base_connection_spec.rb +0 -101
  695. data/spec/integration/rails/graphql/relay/connection_instrumentation_spec.rb +0 -80
  696. data/spec/integration/rails/graphql/relay/connection_resolve_spec.rb +0 -79
  697. data/spec/integration/rails/graphql/relay/connection_type_spec.rb +0 -106
  698. data/spec/integration/rails/graphql/relay/edge_spec.rb +0 -10
  699. data/spec/integration/rails/graphql/relay/mutation_spec.rb +0 -387
  700. data/spec/integration/rails/graphql/relay/node_spec.rb +0 -263
  701. data/spec/integration/rails/graphql/relay/page_info_spec.rb +0 -111
  702. data/spec/integration/rails/graphql/relay/range_add_spec.rb +0 -117
  703. data/spec/integration/rails/graphql/relay/relation_connection_spec.rb +0 -837
  704. data/spec/integration/rails/graphql/schema_spec.rb +0 -476
  705. data/spec/integration/rails/graphql/tracing/active_support_notifications_tracing_spec.rb +0 -62
  706. data/spec/integration/rails/spec_helper.rb +0 -25
  707. data/spec/integration/tmp/app/graphql/types/family_type.rb +0 -9
  708. data/spec/spec_helper.rb +0 -116
  709. data/spec/support/dummy/data.rb +0 -45
  710. data/spec/support/dummy/schema.rb +0 -492
  711. data/spec/support/error_bubbling_helpers.rb +0 -23
  712. data/spec/support/global_id.rb +0 -23
  713. data/spec/support/jazz.rb +0 -759
  714. data/spec/support/lazy_helpers.rb +0 -192
  715. data/spec/support/magic_cards/schema.graphql +0 -33
  716. data/spec/support/minimum_input_object.rb +0 -21
  717. data/spec/support/new_relic.rb +0 -27
  718. data/spec/support/parser/filename_example.graphql +0 -5
  719. data/spec/support/parser/filename_example_error_1.graphql +0 -4
  720. data/spec/support/parser/filename_example_error_2.graphql +0 -5
  721. data/spec/support/skylight.rb +0 -39
  722. data/spec/support/star_wars/schema.rb +0 -465
  723. data/spec/support/static_validation_helpers.rb +0 -32
@@ -1,24 +1,20 @@
1
1
  # frozen_string_literal: true
2
+ require "graphql/schema/addition"
3
+ require "graphql/schema/always_visible"
2
4
  require "graphql/schema/base_64_encoder"
3
- require "graphql/schema/catchall_middleware"
4
- require "graphql/schema/default_parse_error"
5
- require "graphql/schema/default_type_error"
5
+ require "graphql/schema/find_inherited_value"
6
6
  require "graphql/schema/finder"
7
7
  require "graphql/schema/invalid_type_error"
8
8
  require "graphql/schema/introspection_system"
9
9
  require "graphql/schema/late_bound_type"
10
- require "graphql/schema/middleware_chain"
11
10
  require "graphql/schema/null_mask"
12
- require "graphql/schema/possible_types"
13
- require "graphql/schema/rescue_middleware"
14
- require "graphql/schema/timeout_middleware"
15
- require "graphql/schema/traversal"
11
+ require "graphql/schema/timeout"
16
12
  require "graphql/schema/type_expression"
17
13
  require "graphql/schema/unique_within_type"
18
- require "graphql/schema/validation"
19
14
  require "graphql/schema/warden"
20
15
  require "graphql/schema/build_from_definition"
21
16
 
17
+ require "graphql/schema/validator"
22
18
  require "graphql/schema/member"
23
19
  require "graphql/schema/wrapper"
24
20
  require "graphql/schema/list"
@@ -34,13 +30,19 @@ require "graphql/schema/scalar"
34
30
  require "graphql/schema/object"
35
31
  require "graphql/schema/union"
36
32
  require "graphql/schema/directive"
33
+ require "graphql/schema/directive/deprecated"
37
34
  require "graphql/schema/directive/include"
35
+ require "graphql/schema/directive/one_of"
38
36
  require "graphql/schema/directive/skip"
39
37
  require "graphql/schema/directive/feature"
38
+ require "graphql/schema/directive/flagged"
40
39
  require "graphql/schema/directive/transform"
40
+ require "graphql/schema/directive/specified_by"
41
+ require "graphql/schema/type_membership"
41
42
 
42
43
  require "graphql/schema/resolver"
43
44
  require "graphql/schema/mutation"
45
+ require "graphql/schema/has_single_input_argument"
44
46
  require "graphql/schema/relay_classic_mutation"
45
47
  require "graphql/schema/subscription"
46
48
 
@@ -52,7 +54,6 @@ module GraphQL
52
54
  # - types for exposing your application
53
55
  # - query analyzers for assessing incoming queries (including max depth & max complexity restrictions)
54
56
  # - execution strategies for running incoming queries
55
- # - middleware for interacting with execution
56
57
  #
57
58
  # Schemas start with root types, {Schema#query}, {Schema#mutation} and {Schema#subscription}.
58
59
  # The schema will traverse the tree of fields & types, using those as starting points.
@@ -65,777 +66,535 @@ module GraphQL
65
66
  # `query_execution_strategy`, `mutation_execution_strategy` and `subscription_execution_strategy`
66
67
  # each apply to corresponding root types.
67
68
  #
68
- # A schema accepts a `Relay::GlobalNodeIdentification` instance for use with Relay IDs.
69
- #
70
69
  # @example defining a schema
71
- # MySchema = GraphQL::Schema.define do
70
+ # class MySchema < GraphQL::Schema
72
71
  # query QueryType
73
- # middleware PermissionMiddleware
74
- # rescue_from(ActiveRecord::RecordNotFound) { "Not found" }
75
72
  # # If types are only connected by way of interfaces, they must be added here
76
73
  # orphan_types ImageType, AudioType
77
74
  # end
78
75
  #
79
76
  class Schema
80
- extend Forwardable
81
- extend GraphQL::Schema::Member::AcceptsDefinition
82
- include GraphQL::Define::InstanceDefinable
83
- accepts_definitions \
84
- :query, :mutation, :subscription,
85
- :query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
86
- :max_depth, :max_complexity, :default_max_page_size,
87
- :orphan_types, :resolve_type, :type_error, :parse_error,
88
- :error_bubbling,
89
- :raise_definition_error,
90
- :object_from_id, :id_from_object,
91
- :default_mask,
92
- :cursor_encoder,
93
- directives: ->(schema, directives) { schema.directives = directives.reduce({}) { |m, d| m[d.name] = d; m } },
94
- directive: ->(schema, directive) { schema.directives[directive.graphql_name] = directive },
95
- instrument: ->(schema, type, instrumenter, after_built_ins: false) {
96
- if type == :field && after_built_ins
97
- type = :field_after_built_ins
98
- end
99
- schema.instrumenters[type] << instrumenter
100
- },
101
- query_analyzer: ->(schema, analyzer) {
102
- if analyzer == GraphQL::Authorization::Analyzer
103
- warn("The Authorization query analyzer is deprecated. Authorizing at query runtime is generally a better idea.")
104
- end
105
- schema.query_analyzers << analyzer
106
- },
107
- multiplex_analyzer: ->(schema, analyzer) { schema.multiplex_analyzers << analyzer },
108
- middleware: ->(schema, middleware) { schema.middleware << middleware },
109
- lazy_resolve: ->(schema, lazy_class, lazy_value_method) { schema.lazy_methods.set(lazy_class, lazy_value_method) },
110
- rescue_from: ->(schema, err_class, &block) { schema.rescue_from(err_class, &block) },
111
- tracer: ->(schema, tracer) { schema.tracers.push(tracer) }
112
-
113
- attr_accessor \
114
- :query, :mutation, :subscription,
115
- :query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
116
- :max_depth, :max_complexity, :default_max_page_size,
117
- :orphan_types, :directives,
118
- :query_analyzers, :multiplex_analyzers, :instrumenters, :lazy_methods,
119
- :cursor_encoder,
120
- :ast_node,
121
- :raise_definition_error,
122
- :introspection_namespace,
123
- :analysis_engine
124
-
125
- # [Boolean] True if this object bubbles validation errors up from a field into its parent InputObject, if there is one.
126
- attr_accessor :error_bubbling
127
-
128
- # Single, long-lived instance of the provided subscriptions class, if there is one.
129
- # @return [GraphQL::Subscriptions]
130
- attr_accessor :subscriptions
131
-
132
- # @return [MiddlewareChain] MiddlewareChain which is applied to fields during execution
133
- attr_accessor :middleware
134
-
135
- # @return [<#call(member, ctx)>] A callable for filtering members of the schema
136
- # @see {Query.new} for query-specific filters with `except:`
137
- attr_accessor :default_mask
138
-
139
- # @see {GraphQL::Query::Context} The parent class of these classes
140
- # @return [Class] Instantiated for each query
141
- attr_accessor :context_class
142
-
143
- class << self
144
- attr_writer :default_execution_strategy
145
- end
146
-
147
- def default_filter
148
- GraphQL::Filter.new(except: default_mask)
149
- end
77
+ extend GraphQL::Schema::Member::HasAstNode
78
+ extend GraphQL::Schema::FindInheritedValue
150
79
 
151
- # @return [Array<#trace(key, data)>] Tracers applied to every query
152
- # @see {Query#tracers} for query-specific tracers
153
- attr_reader :tracers
154
-
155
- DYNAMIC_FIELDS = ["__type", "__typename", "__schema"]
156
-
157
- attr_reader :static_validator, :object_from_id_proc, :id_from_object_proc, :resolve_type_proc
158
-
159
- def initialize
160
- @tracers = []
161
- @definition_error = nil
162
- @orphan_types = []
163
- @directives = self.class.default_directives
164
- @static_validator = GraphQL::StaticValidation::Validator.new(schema: self)
165
- @middleware = MiddlewareChain.new(final_step: GraphQL::Execution::Execute::FieldResolveStep)
166
- @query_analyzers = []
167
- @multiplex_analyzers = []
168
- @resolve_type_proc = nil
169
- @object_from_id_proc = nil
170
- @id_from_object_proc = nil
171
- @type_error_proc = DefaultTypeError
172
- @parse_error_proc = DefaultParseError
173
- @instrumenters = Hash.new { |h, k| h[k] = [] }
174
- @lazy_methods = GraphQL::Execution::Lazy::LazyMethodMap.new
175
- @lazy_methods.set(GraphQL::Execution::Lazy, :value)
176
- @cursor_encoder = Base64Encoder
177
- # Default to the built-in execution strategy:
178
- @analysis_engine = GraphQL::Analysis
179
- @query_execution_strategy = self.class.default_execution_strategy
180
- @mutation_execution_strategy = self.class.default_execution_strategy
181
- @subscription_execution_strategy = self.class.default_execution_strategy
182
- @default_mask = GraphQL::Schema::NullMask
183
- @rebuilding_artifacts = false
184
- @context_class = GraphQL::Query::Context
185
- @introspection_namespace = nil
186
- @introspection_system = nil
187
- @interpreter = false
188
- @error_bubbling = false
189
- end
190
-
191
- # @return [Boolean] True if using the new {GraphQL::Execution::Interpreter}
192
- def interpreter?
193
- @interpreter
80
+ class DuplicateNamesError < GraphQL::Error
81
+ attr_reader :duplicated_name
82
+ def initialize(duplicated_name:, duplicated_definition_1:, duplicated_definition_2:)
83
+ @duplicated_name = duplicated_name
84
+ super(
85
+ "Found two visible definitions for `#{duplicated_name}`: #{duplicated_definition_1}, #{duplicated_definition_2}"
86
+ )
87
+ end
194
88
  end
195
89
 
196
- # @api private
197
- attr_writer :interpreter
198
-
199
- def inspect
200
- "#<#{self.class.name} ...>"
90
+ class UnresolvedLateBoundTypeError < GraphQL::Error
91
+ attr_reader :type
92
+ def initialize(type:)
93
+ @type = type
94
+ super("Late bound type was never found: #{type.inspect}")
95
+ end
201
96
  end
202
97
 
203
- def initialize_copy(other)
204
- super
205
- @orphan_types = other.orphan_types.dup
206
- @directives = other.directives.dup
207
- @static_validator = GraphQL::StaticValidation::Validator.new(schema: self)
208
- @middleware = other.middleware.dup
209
- @query_analyzers = other.query_analyzers.dup
210
- @multiplex_analyzers = other.multiplex_analyzers.dup
211
- @tracers = other.tracers.dup
212
- @possible_types = GraphQL::Schema::PossibleTypes.new(self)
213
-
214
- @lazy_methods = other.lazy_methods.dup
98
+ # Error that is raised when [#Schema#from_definition] is passed an invalid schema definition string.
99
+ class InvalidDocumentError < Error; end;
215
100
 
216
- @instrumenters = Hash.new { |h, k| h[k] = [] }
217
- other.instrumenters.each do |key, insts|
218
- @instrumenters[key].concat(insts)
101
+ class << self
102
+ # Create schema with the result of an introspection query.
103
+ # @param introspection_result [Hash] A response from {GraphQL::Introspection::INTROSPECTION_QUERY}
104
+ # @return [Class<GraphQL::Schema>] the schema described by `input`
105
+ def from_introspection(introspection_result)
106
+ GraphQL::Schema::Loader.load(introspection_result)
107
+ end
108
+
109
+ # Create schema from an IDL schema or file containing an IDL definition.
110
+ # @param definition_or_path [String] A schema definition string, or a path to a file containing the definition
111
+ # @param default_resolve [<#call(type, field, obj, args, ctx)>] A callable for handling field resolution
112
+ # @param parser [Object] An object for handling definition string parsing (must respond to `parse`)
113
+ # @param using [Hash] Plugins to attach to the created schema with `use(key, value)`
114
+ # @return [Class] the schema described by `document`
115
+ def from_definition(definition_or_path, default_resolve: nil, parser: GraphQL.default_parser, using: {})
116
+ # If the file ends in `.graphql` or `.graphqls`, treat it like a filepath
117
+ if definition_or_path.end_with?(".graphql") || definition_or_path.end_with?(".graphqls")
118
+ GraphQL::Schema::BuildFromDefinition.from_definition_path(
119
+ self,
120
+ definition_or_path,
121
+ default_resolve: default_resolve,
122
+ parser: parser,
123
+ using: using,
124
+ )
125
+ else
126
+ GraphQL::Schema::BuildFromDefinition.from_definition(
127
+ self,
128
+ definition_or_path,
129
+ default_resolve: default_resolve,
130
+ parser: parser,
131
+ using: using,
132
+ )
133
+ end
219
134
  end
220
135
 
221
- if other.rescues?
222
- @rescue_middleware = other.rescue_middleware
136
+ def deprecated_graphql_definition
137
+ graphql_definition(silence_deprecation_warning: true)
223
138
  end
224
139
 
225
- # This will be rebuilt when it's requested
226
- # or during a later `define` call
227
- @types = nil
228
- @introspection_system = nil
229
- end
230
-
231
- def rescue_from(*args, &block)
232
- rescue_middleware.rescue_from(*args, &block)
233
- end
234
-
235
- def remove_handler(*args, &block)
236
- rescue_middleware.remove_handler(*args, &block)
237
- end
238
-
239
- def using_ast_analysis?
240
- @analysis_engine == GraphQL::Analysis::AST
241
- end
242
-
243
- # For forwards-compatibility with Schema classes
244
- alias :graphql_definition :itself
245
-
246
- # Validate a query string according to this schema.
247
- # @param string_or_document [String, GraphQL::Language::Nodes::Document]
248
- # @return [Array<GraphQL::StaticValidation::Error >]
249
- def validate(string_or_document, rules: nil)
250
- doc = if string_or_document.is_a?(String)
251
- GraphQL.parse(string_or_document)
252
- else
253
- string_or_document
254
- end
255
- query = GraphQL::Query.new(self, document: doc)
256
- validator_opts = { schema: self }
257
- rules && (validator_opts[:rules] = rules)
258
- validator = GraphQL::StaticValidation::Validator.new(validator_opts)
259
- res = validator.validate(query)
260
- res[:errors]
261
- end
262
-
263
- def define(**kwargs, &block)
264
- super
265
- ensure_defined
266
- # Assert that all necessary configs are present:
267
- validation_error = Validation.validate(self)
268
- validation_error && raise(NotImplementedError, validation_error)
269
- rebuild_artifacts
270
-
271
- @definition_error = nil
272
- nil
273
- rescue StandardError => err
274
- if @raise_definition_error || err.is_a?(CyclicalDefinitionError)
275
- raise
276
- else
277
- # Raise this error _later_ to avoid messing with Rails constant loading
278
- @definition_error = err
279
- end
280
- nil
281
- end
282
-
283
- # Attach `instrumenter` to this schema for instrumenting events of `instrumentation_type`.
284
- # @param instrumentation_type [Symbol]
285
- # @param instrumenter
286
- # @return [void]
287
- def instrument(instrumentation_type, instrumenter)
288
- @instrumenters[instrumentation_type] << instrumenter
289
- if instrumentation_type == :field
290
- rebuild_artifacts
140
+ # @return [GraphQL::Subscriptions]
141
+ def subscriptions(inherited: true)
142
+ defined?(@subscriptions) ? @subscriptions : (inherited ? find_inherited_value(:subscriptions, nil) : nil)
291
143
  end
292
- end
293
144
 
294
- # @return [Array<GraphQL::BaseType>] The root types of this schema
295
- def root_types
296
- @root_types ||= begin
297
- rebuild_artifacts
298
- @root_types
145
+ def subscriptions=(new_implementation)
146
+ @subscriptions = new_implementation
299
147
  end
300
- end
301
148
 
302
- # @see [GraphQL::Schema::Warden] Restricted access to members of a schema
303
- # @return [GraphQL::Schema::TypeMap] `{ name => type }` pairs of types in this schema
304
- def types
305
- @types ||= begin
306
- rebuild_artifacts
307
- @types
149
+ def trace_class(new_class = nil)
150
+ if new_class
151
+ trace_mode(:default, new_class)
152
+ backtrace_class = Class.new(new_class)
153
+ backtrace_class.include(GraphQL::Backtrace::Trace)
154
+ trace_mode(:default_backtrace, backtrace_class)
155
+ end
156
+ trace_class_for(:default)
157
+ end
158
+
159
+ # @return [Class] Return the trace class to use for this mode, looking one up on the superclass if this Schema doesn't have one defined.
160
+ def trace_class_for(mode)
161
+ @trace_modes ||= {}
162
+ @trace_modes[mode] ||= begin
163
+ case mode
164
+ when :default
165
+ superclass_base_class = if superclass.respond_to?(:trace_class_for)
166
+ superclass.trace_class_for(mode)
167
+ else
168
+ GraphQL::Tracing::Trace
169
+ end
170
+ Class.new(superclass_base_class)
171
+ when :default_backtrace
172
+ schema_base_class = trace_class_for(:default)
173
+ Class.new(schema_base_class) do
174
+ include(GraphQL::Backtrace::Trace)
175
+ end
176
+ else
177
+ mods = trace_modules_for(mode)
178
+ Class.new(trace_class_for(:default)) do
179
+ mods.any? && include(*mods)
180
+ end
181
+ end
182
+ end
308
183
  end
309
- end
310
184
 
311
- # @api private
312
- def introspection_system
313
- @introspection_system ||= begin
314
- rebuild_artifacts
315
- @introspection_system
185
+ # Configure `trace_class` to be used whenever `context: { trace_mode: mode_name }` is requested.
186
+ # `:default` is used when no `trace_mode: ...` is requested.
187
+ # @param mode_name [Symbol]
188
+ # @param trace_class [Class] subclass of GraphQL::Tracing::Trace
189
+ # @return void
190
+ def trace_mode(mode_name, trace_class)
191
+ @trace_modes ||= {}
192
+ @trace_modes[mode_name] = trace_class
193
+ nil
316
194
  end
317
- end
318
-
319
- # Returns a list of Arguments and Fields referencing a certain type
320
- # @param type_name [String]
321
- # @return [Hash]
322
- def references_to(type_name)
323
- rebuild_artifacts unless defined?(@type_reference_map)
324
- @type_reference_map.fetch(type_name, [])
325
- end
326
195
 
327
- # Returns a list of Union types in which a type is a member
328
- # @param type [GraphQL::ObjectType]
329
- # @return [Array<GraphQL::UnionType>] list of union types of which the type is a member
330
- def union_memberships(type)
331
- rebuild_artifacts unless defined?(@union_memberships)
332
- @union_memberships.fetch(type.name, [])
333
- end
334
-
335
- # Execute a query on itself. Raises an error if the schema definition is invalid.
336
- # @see {Query#initialize} for arguments.
337
- # @return [Hash] query result, ready to be serialized as JSON
338
- def execute(query_str = nil, **kwargs)
339
- if query_str
340
- kwargs[:query] = query_str
341
- end
342
- # Some of the query context _should_ be passed to the multiplex, too
343
- multiplex_context = if (ctx = kwargs[:context])
344
- {
345
- backtrace: ctx[:backtrace],
346
- tracers: ctx[:tracers],
347
- }
348
- else
349
- {}
196
+ def own_trace_modules
197
+ @own_trace_modules ||= Hash.new { |h, k| h[k] = [] }
350
198
  end
351
- # Since we're running one query, don't run a multiplex-level complexity analyzer
352
- all_results = multiplex([kwargs], max_complexity: nil, context: multiplex_context)
353
- all_results[0]
354
- end
355
-
356
- # Execute several queries on itself. Raises an error if the schema definition is invalid.
357
- # @example Run several queries at once
358
- # context = { ... }
359
- # queries = [
360
- # { query: params[:query_1], variables: params[:variables_1], context: context },
361
- # { query: params[:query_2], variables: params[:variables_2], context: context },
362
- # ]
363
- # results = MySchema.multiplex(queries)
364
- # render json: {
365
- # result_1: results[0],
366
- # result_2: results[1],
367
- # }
368
- #
369
- # @see {Query#initialize} for query keyword arguments
370
- # @see {Execution::Multiplex#run_queries} for multiplex keyword arguments
371
- # @param queries [Array<Hash>] Keyword arguments for each query
372
- # @param context [Hash] Multiplex-level context
373
- # @return [Array<Hash>] One result for each query in the input
374
- def multiplex(queries, **kwargs)
375
- with_definition_error_check {
376
- GraphQL::Execution::Multiplex.run_all(self, queries, **kwargs)
377
- }
378
- end
379
-
380
- # Search for a schema member using a string path
381
- # @example Finding a Field
382
- # Schema.find("Ensemble.musicians")
383
- #
384
- # @see {GraphQL::Schema::Finder} for more examples
385
- # @param path [String] A dot-separated path to the member
386
- # @raise [Schema::Finder::MemberNotFoundError] if path could not be found
387
- # @return [GraphQL::BaseType, GraphQL::Field, GraphQL::Argument, GraphQL::Directive] A GraphQL Schema Member
388
- def find(path)
389
- rebuild_artifacts unless defined?(@finder)
390
- @find_cache[path] ||= @finder.find(path)
391
- end
392
199
 
393
- # Resolve field named `field_name` for type `parent_type`.
394
- # Handles dynamic fields `__typename`, `__type` and `__schema`, too
395
- # @param parent_type [String, GraphQL::BaseType]
396
- # @param field_name [String]
397
- # @return [GraphQL::Field, nil] The field named `field_name` on `parent_type`
398
- # @see [GraphQL::Schema::Warden] Restricted access to members of a schema
399
- def get_field(parent_type, field_name)
400
- with_definition_error_check do
401
- parent_type_name = case parent_type
402
- when GraphQL::BaseType
403
- parent_type.name
404
- when String
405
- parent_type
406
- else
407
- raise "Unexpected parent_type: #{parent_type}"
200
+ # @return [Array<Module>] Modules added for tracing in `trace_mode`, including inherited ones
201
+ def trace_modules_for(trace_mode)
202
+ modules = own_trace_modules[trace_mode]
203
+ if superclass.respond_to?(:trace_modules_for)
204
+ modules += superclass.trace_modules_for(trace_mode)
408
205
  end
409
-
410
- defined_field = @instrumented_field_map[parent_type_name][field_name]
411
- if defined_field
412
- defined_field
413
- elsif parent_type == query && (entry_point_field = introspection_system.entry_point(name: field_name))
414
- entry_point_field
415
- elsif (dynamic_field = introspection_system.dynamic_field(name: field_name))
416
- dynamic_field
206
+ modules
207
+ end
208
+
209
+
210
+ # Returns the JSON response of {Introspection::INTROSPECTION_QUERY}.
211
+ # @see {#as_json}
212
+ # @return [String]
213
+ def to_json(**args)
214
+ JSON.pretty_generate(as_json(**args))
215
+ end
216
+
217
+ # Return the Hash response of {Introspection::INTROSPECTION_QUERY}.
218
+ # @param context [Hash]
219
+ # @param only [<#call(member, ctx)>]
220
+ # @param except [<#call(member, ctx)>]
221
+ # @param include_deprecated_args [Boolean] If true, deprecated arguments will be included in the JSON response
222
+ # @param include_schema_description [Boolean] If true, the schema's description will be queried and included in the response
223
+ # @param include_is_repeatable [Boolean] If true, `isRepeatable: true|false` will be included with the schema's directives
224
+ # @param include_specified_by_url [Boolean] If true, scalar types' `specifiedByUrl:` will be included in the response
225
+ # @param include_is_one_of [Boolean] If true, `isOneOf: true|false` will be included with input objects
226
+ # @return [Hash] GraphQL result
227
+ def as_json(context: {}, include_deprecated_args: true, include_schema_description: false, include_is_repeatable: false, include_specified_by_url: false, include_is_one_of: false)
228
+ introspection_query = Introspection.query(
229
+ include_deprecated_args: include_deprecated_args,
230
+ include_schema_description: include_schema_description,
231
+ include_is_repeatable: include_is_repeatable,
232
+ include_is_one_of: include_is_one_of,
233
+ include_specified_by_url: include_specified_by_url,
234
+ )
235
+
236
+ execute(introspection_query, context: context).to_h
237
+ end
238
+
239
+ # Return the GraphQL IDL for the schema
240
+ # @param context [Hash]
241
+ # @return [String]
242
+ def to_definition(context: {})
243
+ GraphQL::Schema::Printer.print_schema(self, context: context)
244
+ end
245
+
246
+ # Return the GraphQL::Language::Document IDL AST for the schema
247
+ # @return [GraphQL::Language::Document]
248
+ def to_document
249
+ GraphQL::Language::DocumentFromSchemaDefinition.new(self).document
250
+ end
251
+
252
+ # @return [String, nil]
253
+ def description(new_description = nil)
254
+ if new_description
255
+ @description = new_description
256
+ elsif defined?(@description)
257
+ @description
417
258
  else
418
- nil
259
+ find_inherited_value(:description, nil)
419
260
  end
420
261
  end
421
- end
422
-
423
- # Fields for this type, after instrumentation is applied
424
- # @return [Hash<String, GraphQL::Field>]
425
- def get_fields(type)
426
- @instrumented_field_map[type.graphql_name]
427
- end
428
-
429
- def type_from_ast(ast_node)
430
- GraphQL::Schema::TypeExpression.build_type(self.types, ast_node)
431
- end
432
-
433
- # @see [GraphQL::Schema::Warden] Restricted access to members of a schema
434
- # @param type_defn [GraphQL::InterfaceType, GraphQL::UnionType] the type whose members you want to retrieve
435
- # @return [Array<GraphQL::ObjectType>] types which belong to `type_defn` in this schema
436
- def possible_types(type_defn)
437
- @possible_types ||= GraphQL::Schema::PossibleTypes.new(self)
438
- @possible_types.possible_types(type_defn)
439
- end
440
262
 
441
- # @see [GraphQL::Schema::Warden] Resticted access to root types
442
- # @return [GraphQL::ObjectType, nil]
443
- def root_type_for_operation(operation)
444
- case operation
445
- when "query"
446
- query
447
- when "mutation"
448
- mutation
449
- when "subscription"
450
- subscription
451
- else
452
- raise ArgumentError, "unknown operation type: #{operation}"
263
+ def find(path)
264
+ if !@finder
265
+ @find_cache = {}
266
+ @finder ||= GraphQL::Schema::Finder.new(self)
267
+ end
268
+ @find_cache[path] ||= @finder.find(path)
453
269
  end
454
- end
455
270
 
456
- def execution_strategy_for_operation(operation)
457
- case operation
458
- when "query"
459
- query_execution_strategy
460
- when "mutation"
461
- mutation_execution_strategy
462
- when "subscription"
463
- subscription_execution_strategy
464
- else
465
- raise ArgumentError, "unknown operation type: #{operation}"
271
+ def static_validator
272
+ GraphQL::StaticValidation::Validator.new(schema: self)
466
273
  end
467
- end
468
274
 
469
- # Determine the GraphQL type for a given object.
470
- # This is required for unions and interfaces (including Relay's `Node` interface)
471
- # @see [GraphQL::Schema::Warden] Restricted access to members of a schema
472
- # @param type [GraphQL::UnionType, GraphQL:InterfaceType] the abstract type which is being resolved
473
- # @param object [Any] An application object which GraphQL is currently resolving on
474
- # @param ctx [GraphQL::Query::Context] The context for the current query
475
- # @return [GraphQL::ObjectType] The type for exposing `object` in GraphQL
476
- def resolve_type(type, object, ctx = :__undefined__)
477
- check_resolved_type(type, object, ctx) do |ok_type, ok_object, ok_ctx|
478
- if @resolve_type_proc.nil?
479
- raise(NotImplementedError, "Can't determine GraphQL type for: #{ok_object.inspect}, define `resolve_type (type, obj, ctx) -> { ... }` inside `Schema.define`.")
275
+ def use(plugin, **kwargs)
276
+ if kwargs.any?
277
+ plugin.use(self, **kwargs)
278
+ else
279
+ plugin.use(self)
480
280
  end
481
- @resolve_type_proc.call(ok_type, ok_object, ok_ctx)
281
+ own_plugins << [plugin, kwargs]
482
282
  end
483
- end
484
283
 
485
- # This is a compatibility hack so that instance-level and class-level
486
- # methods can get correctness checks without calling one another
487
- # @api private
488
- def check_resolved_type(type, object, ctx = :__undefined__)
489
- if ctx == :__undefined__
490
- # Old method signature
491
- ctx = object
492
- object = type
493
- type = nil
284
+ def plugins
285
+ find_inherited_value(:plugins, EMPTY_ARRAY) + own_plugins
286
+ end
287
+
288
+ # Build a map of `{ name => type }` and return it
289
+ # @return [Hash<String => Class>] A dictionary of type classes by their GraphQL name
290
+ # @see get_type Which is more efficient for finding _one type_ by name, because it doesn't merge hashes.
291
+ def types(context = GraphQL::Query::NullContext)
292
+ all_types = non_introspection_types.merge(introspection_system.types)
293
+ visible_types = {}
294
+ all_types.each do |k, v|
295
+ visible_types[k] =if v.is_a?(Array)
296
+ visible_t = nil
297
+ v.each do |t|
298
+ if t.visible?(context)
299
+ if visible_t.nil?
300
+ visible_t = t
301
+ else
302
+ raise DuplicateNamesError.new(
303
+ duplicated_name: k, duplicated_definition_1: visible_t.inspect, duplicated_definition_2: t.inspect
304
+ )
305
+ end
306
+ end
307
+ end
308
+ visible_t
309
+ else
310
+ v
311
+ end
312
+ end
313
+ visible_types
494
314
  end
495
315
 
496
- if object.is_a?(GraphQL::Schema::Object)
497
- object = object.object
498
- end
316
+ # @param type_name [String]
317
+ # @return [Module, nil] A type, or nil if there's no type called `type_name`
318
+ def get_type(type_name, context = GraphQL::Query::NullContext)
319
+ local_entry = own_types[type_name]
320
+ type_defn = case local_entry
321
+ when nil
322
+ nil
323
+ when Array
324
+ visible_t = nil
325
+ warden = Warden.from_context(context)
326
+ local_entry.each do |t|
327
+ if warden.visible_type?(t, context)
328
+ if visible_t.nil?
329
+ visible_t = t
330
+ else
331
+ raise DuplicateNamesError.new(
332
+ duplicated_name: type_name, duplicated_definition_1: visible_t.inspect, duplicated_definition_2: t.inspect
333
+ )
334
+ end
335
+ end
336
+ end
337
+ visible_t
338
+ when Module
339
+ local_entry
340
+ else
341
+ raise "Invariant: unexpected own_types[#{type_name.inspect}]: #{local_entry.inspect}"
342
+ end
499
343
 
500
- if type.respond_to?(:graphql_definition)
501
- type = type.graphql_definition
344
+ type_defn ||
345
+ introspection_system.types[type_name] || # todo context-specific introspection?
346
+ (superclass.respond_to?(:get_type) ? superclass.get_type(type_name, context) : nil)
502
347
  end
503
348
 
504
- # Prefer a type-local function; fall back to the schema-level function
505
- type_proc = type && type.resolve_type_proc
506
- type_result = if type_proc
507
- type_proc.call(object, ctx)
508
- else
509
- yield(type, object, ctx)
510
- end
349
+ # @api private
350
+ attr_writer :connections
511
351
 
512
- if type_result.nil?
513
- nil
514
- else
515
- after_lazy(type_result) do |resolved_type_result|
516
- if resolved_type_result.respond_to?(:graphql_definition)
517
- resolved_type_result = resolved_type_result.graphql_definition
518
- end
519
- if !resolved_type_result.is_a?(GraphQL::BaseType)
520
- type_str = "#{resolved_type_result} (#{resolved_type_result.class.name})"
521
- raise "resolve_type(#{object}) returned #{type_str}, but it should return a GraphQL type"
352
+ # @return [GraphQL::Pagination::Connections] if installed
353
+ def connections
354
+ if defined?(@connections)
355
+ @connections
356
+ else
357
+ inherited_connections = find_inherited_value(:connections, nil)
358
+ # This schema is part of an inheritance chain which is using new connections,
359
+ # make a new instance, so we don't pollute the upstream one.
360
+ if inherited_connections
361
+ @connections = Pagination::Connections.new(schema: self)
522
362
  else
523
- resolved_type_result
363
+ nil
524
364
  end
525
365
  end
526
366
  end
527
- end
528
367
 
529
- def resolve_type=(new_resolve_type_proc)
530
- callable = GraphQL::BackwardsCompatibility.wrap_arity(new_resolve_type_proc, from: 2, to: 3, last: true, name: "Schema#resolve_type(type, obj, ctx)")
531
- @resolve_type_proc = callable
532
- end
533
-
534
- # Fetch an application object by its unique id
535
- # @param id [String] A unique identifier, provided previously by this GraphQL schema
536
- # @param ctx [GraphQL::Query::Context] The context for the current query
537
- # @return [Any] The application object identified by `id`
538
- def object_from_id(id, ctx)
539
- if @object_from_id_proc.nil?
540
- raise(NotImplementedError, "Can't fetch an object for id \"#{id}\" because the schema's `object_from_id (id, ctx) -> { ... }` function is not defined")
541
- else
542
- @object_from_id_proc.call(id, ctx)
368
+ def new_connections?
369
+ !!connections
543
370
  end
544
- end
545
371
 
546
- # @param new_proc [#call] A new callable for fetching objects by ID
547
- def object_from_id=(new_proc)
548
- @object_from_id_proc = new_proc
549
- end
550
-
551
- # When we encounter a type error during query execution, we call this hook.
552
- #
553
- # You can use this hook to write a log entry,
554
- # add a {GraphQL::ExecutionError} to the response (with `ctx.add_error`)
555
- # or raise an exception and halt query execution.
556
- #
557
- # @example A `nil` is encountered by a non-null field
558
- # type_error ->(err, query_ctx) {
559
- # err.is_a?(GraphQL::InvalidNullError) # => true
560
- # }
561
- #
562
- # @example An object doesn't resolve to one of a {UnionType}'s members
563
- # type_error ->(err, query_ctx) {
564
- # err.is_a?(GraphQL::UnresolvedTypeError) # => true
565
- # }
566
- #
567
- # @see {DefaultTypeError} is the default behavior.
568
- # @param err [GraphQL::TypeError] The error encountered during execution
569
- # @param ctx [GraphQL::Query::Context] The context for the field where the error occurred
570
- # @return void
571
- def type_error(err, ctx)
572
- @type_error_proc.call(err, ctx)
573
- end
574
-
575
- # @param new_proc [#call] A new callable for handling type errors during execution
576
- def type_error=(new_proc)
577
- @type_error_proc = new_proc
578
- end
579
-
580
- # Can't delegate to `class`
581
- alias :_schema_class :class
582
- def_delegators :_schema_class, :visible?, :accessible?, :authorized?, :unauthorized_object, :unauthorized_field, :inaccessible_fields
583
- def_delegators :_schema_class, :directive
584
-
585
- # A function to call when {#execute} receives an invalid query string
586
- #
587
- # @see {DefaultParseError} is the default behavior.
588
- # @param err [GraphQL::ParseError] The error encountered during parsing
589
- # @param ctx [GraphQL::Query::Context] The context for the query where the error occurred
590
- # @return void
591
- def parse_error(err, ctx)
592
- @parse_error_proc.call(err, ctx)
593
- end
594
-
595
- # @param new_proc [#call] A new callable for handling parse errors during execution
596
- def parse_error=(new_proc)
597
- @parse_error_proc = new_proc
598
- end
599
-
600
- # Get a unique identifier from this object
601
- # @param object [Any] An application object
602
- # @param type [GraphQL::BaseType] The current type definition
603
- # @param ctx [GraphQL::Query::Context] the context for the current query
604
- # @return [String] a unique identifier for `object` which clients can use to refetch it
605
- def id_from_object(object, type, ctx)
606
- if @id_from_object_proc.nil?
607
- raise(NotImplementedError, "Can't generate an ID for #{object.inspect} of type #{type}, schema's `id_from_object` must be defined")
608
- else
609
- @id_from_object_proc.call(object, type, ctx)
372
+ def query(new_query_object = nil)
373
+ if new_query_object
374
+ if @query_object
375
+ raise GraphQL::Error, "Second definition of `query(...)` (#{new_query_object.inspect}) is invalid, already configured with #{@query_object.inspect}"
376
+ else
377
+ @query_object = new_query_object
378
+ add_type_and_traverse(new_query_object, root: true)
379
+ nil
380
+ end
381
+ else
382
+ @query_object || find_inherited_value(:query)
383
+ end
610
384
  end
611
- end
612
-
613
- # @param new_proc [#call] A new callable for generating unique IDs
614
- def id_from_object=(new_proc)
615
- @id_from_object_proc = new_proc
616
- end
617
-
618
- # Create schema with the result of an introspection query.
619
- # @param introspection_result [Hash] A response from {GraphQL::Introspection::INTROSPECTION_QUERY}
620
- # @return [GraphQL::Schema] the schema described by `input`
621
- def self.from_introspection(introspection_result)
622
- GraphQL::Schema::Loader.load(introspection_result)
623
- end
624
-
625
- # Create schema from an IDL schema or file containing an IDL definition.
626
- # @param definition_or_path [String] A schema definition string, or a path to a file containing the definition
627
- # @param default_resolve [<#call(type, field, obj, args, ctx)>] A callable for handling field resolution
628
- # @param parser [Object] An object for handling definition string parsing (must respond to `parse`)
629
- # @return [GraphQL::Schema] the schema described by `document`
630
- def self.from_definition(definition_or_path, default_resolve: BuildFromDefinition::DefaultResolve, parser: BuildFromDefinition::DefaultParser)
631
- # If the file ends in `.graphql`, treat it like a filepath
632
- definition = if definition_or_path.end_with?(".graphql")
633
- File.read(definition_or_path)
634
- else
635
- definition_or_path
636
- end
637
- GraphQL::Schema::BuildFromDefinition.from_definition(definition, default_resolve: default_resolve, parser: parser)
638
- end
639
-
640
- # Error that is raised when [#Schema#from_definition] is passed an invalid schema definition string.
641
- class InvalidDocumentError < Error; end;
642
-
643
- # @return [Symbol, nil] The method name to lazily resolve `obj`, or nil if `obj`'s class wasn't registered wtih {#lazy_resolve}.
644
- def lazy_method_name(obj)
645
- @lazy_methods.get(obj)
646
- end
647
-
648
- # @return [Boolean] True if this object should be lazily resolved
649
- def lazy?(obj)
650
- !!lazy_method_name(obj)
651
- end
652
-
653
- # Return the GraphQL IDL for the schema
654
- # @param context [Hash]
655
- # @param only [<#call(member, ctx)>]
656
- # @param except [<#call(member, ctx)>]
657
- # @return [String]
658
- def to_definition(only: nil, except: nil, context: {})
659
- GraphQL::Schema::Printer.print_schema(self, only: only, except: except, context: context)
660
- end
661
-
662
- # Return the GraphQL::Language::Document IDL AST for the schema
663
- # @return [GraphQL::Language::Document]
664
- def to_document
665
- GraphQL::Language::DocumentFromSchemaDefinition.new(self).document
666
- end
667
-
668
- # Return the Hash response of {Introspection::INTROSPECTION_QUERY}.
669
- # @param context [Hash]
670
- # @param only [<#call(member, ctx)>]
671
- # @param except [<#call(member, ctx)>]
672
- # @return [Hash] GraphQL result
673
- def as_json(only: nil, except: nil, context: {})
674
- execute(Introspection::INTROSPECTION_QUERY, only: only, except: except, context: context).to_h
675
- end
676
385
 
677
- # Returns the JSON response of {Introspection::INTROSPECTION_QUERY}.
678
- # @see {#as_json}
679
- # @return [String]
680
- def to_json(*args)
681
- JSON.pretty_generate(as_json(*args))
682
- end
683
-
684
- class << self
685
- extend Forwardable
686
- # For compatibility, these methods all:
687
- # - Cause the Schema instance to be created, if it hasn't been created yet
688
- # - Delegate to that instance
689
- # Eventually, the methods will be moved into this class, removing the need for the singleton.
690
- def_delegators :graphql_definition,
691
- # Schema structure
692
- :as_json, :to_json, :to_document, :to_definition,
693
- # Execution
694
- :execute, :multiplex,
695
- :static_validator, :introspection_system,
696
- :query_analyzers, :tracers, :instrumenters,
697
- :execution_strategy_for_operation,
698
- :validate, :multiplex_analyzers, :lazy?, :lazy_method_name, :after_lazy, :sync_lazy,
699
- # Configuration
700
- :analysis_engine, :analysis_engine=, :using_ast_analysis?, :interpreter?,
701
- :max_complexity=, :max_depth=,
702
- :error_bubbling=,
703
- :metadata,
704
- :default_mask,
705
- :default_filter, :redefine,
706
- :id_from_object_proc, :object_from_id_proc,
707
- :id_from_object=, :object_from_id=,
708
- :remove_handler,
709
- # Members
710
- :types, :get_fields, :find,
711
- :root_type_for_operation,
712
- :subscriptions,
713
- :union_memberships,
714
- :get_field, :root_types, :references_to, :type_from_ast,
715
- :possible_types
716
-
717
- def graphql_definition
718
- @graphql_definition ||= to_graphql
719
- end
720
-
721
- def use(plugin, options = {})
722
- plugins << [plugin, options]
386
+ def mutation(new_mutation_object = nil)
387
+ if new_mutation_object
388
+ if @mutation_object
389
+ raise GraphQL::Error, "Second definition of `mutation(...)` (#{new_mutation_object.inspect}) is invalid, already configured with #{@mutation_object.inspect}"
390
+ else
391
+ @mutation_object = new_mutation_object
392
+ add_type_and_traverse(new_mutation_object, root: true)
393
+ nil
394
+ end
395
+ else
396
+ @mutation_object || find_inherited_value(:mutation)
397
+ end
723
398
  end
724
399
 
725
- def plugins
726
- @plugins ||= []
727
- end
728
-
729
- def to_graphql
730
- schema_defn = self.new
731
- schema_defn.raise_definition_error = true
732
- schema_defn.query = query
733
- schema_defn.mutation = mutation
734
- schema_defn.subscription = subscription
735
- schema_defn.max_complexity = max_complexity
736
- schema_defn.error_bubbling = error_bubbling
737
- schema_defn.max_depth = max_depth
738
- schema_defn.default_max_page_size = default_max_page_size
739
- schema_defn.orphan_types = orphan_types
740
-
741
- prepped_dirs = {}
742
- directives.each { |k, v| prepped_dirs[k] = v.graphql_definition}
743
- schema_defn.directives = prepped_dirs
744
- schema_defn.introspection_namespace = introspection
745
- schema_defn.resolve_type = method(:resolve_type)
746
- schema_defn.object_from_id = method(:object_from_id)
747
- schema_defn.id_from_object = method(:id_from_object)
748
- schema_defn.type_error = method(:type_error)
749
- schema_defn.context_class = context_class
750
- schema_defn.cursor_encoder = cursor_encoder
751
- schema_defn.tracers.concat(defined_tracers)
752
- schema_defn.query_analyzers.concat(defined_query_analyzers)
753
-
754
- schema_defn.middleware.concat(defined_middleware)
755
- schema_defn.multiplex_analyzers.concat(defined_multiplex_analyzers)
756
- schema_defn.query_execution_strategy = query_execution_strategy
757
- schema_defn.mutation_execution_strategy = mutation_execution_strategy
758
- schema_defn.subscription_execution_strategy = subscription_execution_strategy
759
- defined_instrumenters.each do |step, insts|
760
- insts.each do |inst|
761
- schema_defn.instrumenters[step] << inst
400
+ def subscription(new_subscription_object = nil)
401
+ if new_subscription_object
402
+ if @subscription_object
403
+ raise GraphQL::Error, "Second definition of `subscription(...)` (#{new_subscription_object.inspect}) is invalid, already configured with #{@subscription_object.inspect}"
404
+ else
405
+ @subscription_object = new_subscription_object
406
+ add_subscription_extension_if_necessary
407
+ add_type_and_traverse(new_subscription_object, root: true)
408
+ nil
762
409
  end
410
+ else
411
+ @subscription_object || find_inherited_value(:subscription)
763
412
  end
764
- lazy_classes.each do |lazy_class, value_method|
765
- schema_defn.lazy_methods.set(lazy_class, value_method)
413
+ end
414
+
415
+ # @see [GraphQL::Schema::Warden] Restricted access to root types
416
+ # @return [GraphQL::ObjectType, nil]
417
+ def root_type_for_operation(operation)
418
+ case operation
419
+ when "query"
420
+ query
421
+ when "mutation"
422
+ mutation
423
+ when "subscription"
424
+ subscription
425
+ else
426
+ raise ArgumentError, "unknown operation type: #{operation}"
766
427
  end
767
- if @rescues
768
- @rescues.each do |err_class, handler|
769
- schema_defn.rescue_from(err_class, &handler)
770
- end
428
+ end
429
+
430
+ def root_types
431
+ @root_types
432
+ end
433
+
434
+ def warden_class
435
+ if defined?(@warden_class)
436
+ @warden_class
437
+ elsif superclass.respond_to?(:warden_class)
438
+ superclass.warden_class
439
+ else
440
+ GraphQL::Schema::Warden
771
441
  end
442
+ end
772
443
 
773
- if plugins.any?
774
- schema_plugins = plugins
775
- # TODO don't depend on .define
776
- schema_defn = schema_defn.redefine do
777
- schema_plugins.each do |plugin, options|
778
- if options.any?
779
- use(plugin, **options)
780
- else
781
- use(plugin)
444
+ attr_writer :warden_class
445
+
446
+ # @param type [Module] The type definition whose possible types you want to see
447
+ # @return [Hash<String, Module>] All possible types, if no `type` is given.
448
+ # @return [Array<Module>] Possible types for `type`, if it's given.
449
+ def possible_types(type = nil, context = GraphQL::Query::NullContext)
450
+ if type
451
+ # TODO duck-typing `.possible_types` would probably be nicer here
452
+ if type.kind.union?
453
+ type.possible_types(context: context)
454
+ else
455
+ stored_possible_types = own_possible_types[type.graphql_name]
456
+ visible_possible_types = if stored_possible_types && type.kind.interface?
457
+ stored_possible_types.select do |possible_type|
458
+ possible_type.interfaces(context).include?(type)
782
459
  end
460
+ else
461
+ stored_possible_types
783
462
  end
463
+ visible_possible_types ||
464
+ introspection_system.possible_types[type.graphql_name] ||
465
+ (
466
+ superclass.respond_to?(:possible_types) ?
467
+ superclass.possible_types(type, context) :
468
+ EMPTY_ARRAY
469
+ )
784
470
  end
471
+ else
472
+ find_inherited_value(:possible_types, EMPTY_HASH)
473
+ .merge(own_possible_types)
474
+ .merge(introspection_system.possible_types)
785
475
  end
786
- # Do this after `plugins` since Interpreter is a plugin
787
- if schema_defn.query_execution_strategy != GraphQL::Execution::Interpreter
788
- schema_defn.instrumenters[:query] << GraphQL::Schema::Member::Instrumentation
476
+ end
477
+
478
+ def union_memberships(type = nil)
479
+ if type
480
+ own_um = own_union_memberships.fetch(type.graphql_name, EMPTY_ARRAY)
481
+ inherited_um = find_inherited_value(:union_memberships, EMPTY_HASH).fetch(type.graphql_name, EMPTY_ARRAY)
482
+ own_um + inherited_um
483
+ else
484
+ joined_um = own_union_memberships.dup
485
+ find_inherited_value(:union_memberhips, EMPTY_HASH).each do |k, v|
486
+ um = joined_um[k] ||= []
487
+ um.concat(v)
488
+ end
489
+ joined_um
789
490
  end
790
- schema_defn.send(:rebuild_artifacts)
491
+ end
791
492
 
792
- schema_defn
493
+ # @api private
494
+ # @see GraphQL::Dataloader
495
+ def dataloader_class
496
+ @dataloader_class || GraphQL::Dataloader::NullDataloader
793
497
  end
794
498
 
795
- def query(new_query_object = nil)
796
- if new_query_object
797
- @query_object = new_query_object
499
+ attr_writer :dataloader_class
500
+
501
+ def references_to(to_type = nil, from: nil)
502
+ @own_references_to ||= Hash.new { |h, k| h[k] = [] }
503
+ if to_type
504
+ if !to_type.is_a?(String)
505
+ to_type = to_type.graphql_name
506
+ end
507
+
508
+ if from
509
+ @own_references_to[to_type] << from
510
+ else
511
+ own_refs = @own_references_to[to_type]
512
+ inherited_refs = find_inherited_value(:references_to, EMPTY_HASH)[to_type] || EMPTY_ARRAY
513
+ own_refs + inherited_refs
514
+ end
798
515
  else
799
- @query_object.respond_to?(:graphql_definition) ? @query_object.graphql_definition : @query_object
516
+ # `@own_references_to` can be quite large for big schemas,
517
+ # and generally speaking, we won't inherit any values.
518
+ # So optimize the most common case -- don't create a duplicate Hash.
519
+ inherited_value = find_inherited_value(:references_to, EMPTY_HASH)
520
+ if inherited_value.any?
521
+ inherited_value.merge(@own_references_to)
522
+ else
523
+ @own_references_to
524
+ end
800
525
  end
801
526
  end
802
527
 
803
- def mutation(new_mutation_object = nil)
804
- if new_mutation_object
805
- @mutation_object = new_mutation_object
528
+ def type_from_ast(ast_node, context: nil)
529
+ type_owner = context ? context.warden : self
530
+ GraphQL::Schema::TypeExpression.build_type(type_owner, ast_node)
531
+ end
532
+
533
+ def get_field(type_or_name, field_name, context = GraphQL::Query::NullContext)
534
+ parent_type = case type_or_name
535
+ when LateBoundType
536
+ get_type(type_or_name.name, context)
537
+ when String
538
+ get_type(type_or_name, context)
539
+ when Module
540
+ type_or_name
806
541
  else
807
- @mutation_object.respond_to?(:graphql_definition) ? @mutation_object.graphql_definition : @mutation_object
542
+ raise GraphQL::InvariantError, "Unexpected field owner for #{field_name.inspect}: #{type_or_name.inspect} (#{type_or_name.class})"
808
543
  end
809
- end
810
544
 
811
- def subscription(new_subscription_object = nil)
812
- if new_subscription_object
813
- @subscription_object = new_subscription_object
545
+ if parent_type.kind.fields? && (field = parent_type.get_field(field_name, context))
546
+ field
547
+ elsif parent_type == query && (entry_point_field = introspection_system.entry_point(name: field_name))
548
+ entry_point_field
549
+ elsif (dynamic_field = introspection_system.dynamic_field(name: field_name))
550
+ dynamic_field
814
551
  else
815
- @subscription_object.respond_to?(:graphql_definition) ? @subscription_object.graphql_definition : @subscription_object
552
+ nil
816
553
  end
817
554
  end
818
555
 
556
+ def get_fields(type, context = GraphQL::Query::NullContext)
557
+ type.fields(context)
558
+ end
559
+
819
560
  def introspection(new_introspection_namespace = nil)
820
561
  if new_introspection_namespace
821
562
  @introspection = new_introspection_namespace
563
+ # reset this cached value:
564
+ @introspection_system = nil
822
565
  else
823
- @introspection
566
+ @introspection || find_inherited_value(:introspection)
567
+ end
568
+ end
569
+
570
+ def introspection_system
571
+ if !@introspection_system
572
+ @introspection_system = Schema::IntrospectionSystem.new(self)
573
+ @introspection_system.resolve_late_bindings
824
574
  end
575
+ @introspection_system
825
576
  end
826
577
 
827
578
  def cursor_encoder(new_encoder = nil)
828
579
  if new_encoder
829
580
  @cursor_encoder = new_encoder
830
581
  end
831
- @cursor_encoder || Base64Encoder
582
+ @cursor_encoder || find_inherited_value(:cursor_encoder, Base64Encoder)
832
583
  end
833
584
 
834
585
  def default_max_page_size(new_default_max_page_size = nil)
835
586
  if new_default_max_page_size
836
587
  @default_max_page_size = new_default_max_page_size
837
588
  else
838
- @default_max_page_size
589
+ @default_max_page_size || find_inherited_value(:default_max_page_size)
590
+ end
591
+ end
592
+
593
+ def default_page_size(new_default_page_size = nil)
594
+ if new_default_page_size
595
+ @default_page_size = new_default_page_size
596
+ else
597
+ @default_page_size || find_inherited_value(:default_page_size)
839
598
  end
840
599
  end
841
600
 
@@ -843,7 +602,7 @@ module GraphQL
843
602
  if new_query_execution_strategy
844
603
  @query_execution_strategy = new_query_execution_strategy
845
604
  else
846
- @query_execution_strategy || self.default_execution_strategy
605
+ @query_execution_strategy || find_inherited_value(:query_execution_strategy, self.default_execution_strategy)
847
606
  end
848
607
  end
849
608
 
@@ -851,7 +610,7 @@ module GraphQL
851
610
  if new_mutation_execution_strategy
852
611
  @mutation_execution_strategy = new_mutation_execution_strategy
853
612
  else
854
- @mutation_execution_strategy || self.default_execution_strategy
613
+ @mutation_execution_strategy || find_inherited_value(:mutation_execution_strategy, self.default_execution_strategy)
855
614
  end
856
615
  end
857
616
 
@@ -859,39 +618,159 @@ module GraphQL
859
618
  if new_subscription_execution_strategy
860
619
  @subscription_execution_strategy = new_subscription_execution_strategy
861
620
  else
862
- @subscription_execution_strategy || self.default_execution_strategy
621
+ @subscription_execution_strategy || find_inherited_value(:subscription_execution_strategy, self.default_execution_strategy)
622
+ end
623
+ end
624
+
625
+ attr_writer :validate_timeout
626
+
627
+ def validate_timeout(new_validate_timeout = nil)
628
+ if new_validate_timeout
629
+ @validate_timeout = new_validate_timeout
630
+ elsif defined?(@validate_timeout)
631
+ @validate_timeout
632
+ else
633
+ find_inherited_value(:validate_timeout)
863
634
  end
864
635
  end
865
636
 
637
+ # Validate a query string according to this schema.
638
+ # @param string_or_document [String, GraphQL::Language::Nodes::Document]
639
+ # @return [Array<GraphQL::StaticValidation::Error >]
640
+ def validate(string_or_document, rules: nil, context: nil)
641
+ doc = if string_or_document.is_a?(String)
642
+ GraphQL.parse(string_or_document)
643
+ else
644
+ string_or_document
645
+ end
646
+ query = GraphQL::Query.new(self, document: doc, context: context)
647
+ validator_opts = { schema: self }
648
+ rules && (validator_opts[:rules] = rules)
649
+ validator = GraphQL::StaticValidation::Validator.new(**validator_opts)
650
+ res = validator.validate(query, timeout: validate_timeout, max_errors: validate_max_errors)
651
+ res[:errors]
652
+ end
653
+
654
+ attr_writer :validate_max_errors
655
+
656
+ def validate_max_errors(new_validate_max_errors = nil)
657
+ if new_validate_max_errors
658
+ @validate_max_errors = new_validate_max_errors
659
+ elsif defined?(@validate_max_errors)
660
+ @validate_max_errors
661
+ else
662
+ find_inherited_value(:validate_max_errors)
663
+ end
664
+ end
665
+
666
+ attr_writer :max_complexity
667
+
866
668
  def max_complexity(max_complexity = nil)
867
669
  if max_complexity
868
670
  @max_complexity = max_complexity
869
- else
671
+ elsif defined?(@max_complexity)
870
672
  @max_complexity
673
+ else
674
+ find_inherited_value(:max_complexity)
871
675
  end
872
676
  end
873
677
 
678
+ attr_writer :analysis_engine
679
+
680
+ def analysis_engine
681
+ @analysis_engine || find_inherited_value(:analysis_engine, self.default_analysis_engine)
682
+ end
683
+
684
+ def using_ast_analysis?
685
+ true
686
+ end
687
+
688
+ def interpreter?
689
+ true
690
+ end
691
+
692
+ attr_writer :interpreter
693
+
874
694
  def error_bubbling(new_error_bubbling = nil)
875
695
  if !new_error_bubbling.nil?
876
696
  @error_bubbling = new_error_bubbling
877
697
  else
878
- @error_bubbling
698
+ @error_bubbling.nil? ? find_inherited_value(:error_bubbling) : @error_bubbling
879
699
  end
880
700
  end
881
701
 
702
+ attr_writer :error_bubbling
703
+
704
+ attr_writer :max_depth
705
+
882
706
  def max_depth(new_max_depth = nil)
883
707
  if new_max_depth
884
708
  @max_depth = new_max_depth
885
- else
709
+ elsif defined?(@max_depth)
886
710
  @max_depth
711
+ else
712
+ find_inherited_value(:max_depth)
713
+ end
714
+ end
715
+
716
+ def disable_introspection_entry_points
717
+ @disable_introspection_entry_points = true
718
+ # TODO: this clears the cache made in `def types`. But this is not a great solution.
719
+ @introspection_system = nil
720
+ end
721
+
722
+ def disable_schema_introspection_entry_point
723
+ @disable_schema_introspection_entry_point = true
724
+ # TODO: this clears the cache made in `def types`. But this is not a great solution.
725
+ @introspection_system = nil
726
+ end
727
+
728
+ def disable_type_introspection_entry_point
729
+ @disable_type_introspection_entry_point = true
730
+ # TODO: this clears the cache made in `def types`. But this is not a great solution.
731
+ @introspection_system = nil
732
+ end
733
+
734
+ def disable_introspection_entry_points?
735
+ if instance_variable_defined?(:@disable_introspection_entry_points)
736
+ @disable_introspection_entry_points
737
+ else
738
+ find_inherited_value(:disable_introspection_entry_points?, false)
739
+ end
740
+ end
741
+
742
+ def disable_schema_introspection_entry_point?
743
+ if instance_variable_defined?(:@disable_schema_introspection_entry_point)
744
+ @disable_schema_introspection_entry_point
745
+ else
746
+ find_inherited_value(:disable_schema_introspection_entry_point?, false)
747
+ end
748
+ end
749
+
750
+ def disable_type_introspection_entry_point?
751
+ if instance_variable_defined?(:@disable_type_introspection_entry_point)
752
+ @disable_type_introspection_entry_point
753
+ else
754
+ find_inherited_value(:disable_type_introspection_entry_point?, false)
887
755
  end
888
756
  end
889
757
 
890
758
  def orphan_types(*new_orphan_types)
891
759
  if new_orphan_types.any?
892
- @orphan_types = new_orphan_types.flatten
760
+ new_orphan_types = new_orphan_types.flatten
761
+ add_type_and_traverse(new_orphan_types, root: false)
762
+ own_orphan_types.concat(new_orphan_types.flatten)
763
+ end
764
+
765
+ inherited_ot = find_inherited_value(:orphan_types, nil)
766
+ if inherited_ot
767
+ if own_orphan_types.any?
768
+ inherited_ot + own_orphan_types
769
+ else
770
+ inherited_ot
771
+ end
893
772
  else
894
- @orphan_types || []
773
+ own_orphan_types
895
774
  end
896
775
  end
897
776
 
@@ -899,7 +778,15 @@ module GraphQL
899
778
  if superclass <= GraphQL::Schema
900
779
  superclass.default_execution_strategy
901
780
  else
902
- @default_execution_strategy ||= GraphQL::Execution::Execute
781
+ @default_execution_strategy ||= GraphQL::Execution::Interpreter
782
+ end
783
+ end
784
+
785
+ def default_analysis_engine
786
+ if superclass <= GraphQL::Schema
787
+ superclass.default_analysis_engine
788
+ else
789
+ @default_analysis_engine ||= GraphQL::Analysis::AST
903
790
  end
904
791
  end
905
792
 
@@ -907,14 +794,73 @@ module GraphQL
907
794
  if new_context_class
908
795
  @context_class = new_context_class
909
796
  else
910
- @context_class || GraphQL::Query::Context
797
+ @context_class || find_inherited_value(:context_class, GraphQL::Query::Context)
911
798
  end
912
799
  end
913
800
 
914
801
  def rescue_from(*err_classes, &handler_block)
915
- @rescues ||= {}
916
802
  err_classes.each do |err_class|
917
- @rescues[err_class] = handler_block
803
+ Execution::Errors.register_rescue_from(err_class, error_handlers[:subclass_handlers], handler_block)
804
+ end
805
+ end
806
+
807
+ NEW_HANDLER_HASH = ->(h, k) {
808
+ h[k] = {
809
+ class: k,
810
+ handler: nil,
811
+ subclass_handlers: Hash.new(&NEW_HANDLER_HASH),
812
+ }
813
+ }
814
+
815
+ def error_handlers
816
+ @error_handlers ||= {
817
+ class: nil,
818
+ handler: nil,
819
+ subclass_handlers: Hash.new(&NEW_HANDLER_HASH),
820
+ }
821
+ end
822
+
823
+ # @api private
824
+ def handle_or_reraise(context, err)
825
+ handler = Execution::Errors.find_handler_for(self, err.class)
826
+ if handler
827
+ obj = context[:current_object]
828
+ args = context[:current_arguments]
829
+ args = args && args.respond_to?(:keyword_arguments) ? args.keyword_arguments : nil
830
+ field = context[:current_field]
831
+ if obj.is_a?(GraphQL::Schema::Object)
832
+ obj = obj.object
833
+ end
834
+ handler[:handler].call(err, obj, args, context, field)
835
+ else
836
+ raise err
837
+ end
838
+ end
839
+
840
+ # rubocop:disable Lint/DuplicateMethods
841
+ module ResolveTypeWithType
842
+ def resolve_type(type, obj, ctx)
843
+ maybe_lazy_resolve_type_result = if type.is_a?(Module) && type.respond_to?(:resolve_type)
844
+ type.resolve_type(obj, ctx)
845
+ else
846
+ super
847
+ end
848
+
849
+ after_lazy(maybe_lazy_resolve_type_result) do |resolve_type_result|
850
+ if resolve_type_result.is_a?(Array) && resolve_type_result.size == 2
851
+ resolved_type = resolve_type_result[0]
852
+ resolved_value = resolve_type_result[1]
853
+ else
854
+ resolved_type = resolve_type_result
855
+ resolved_value = obj
856
+ end
857
+
858
+ if resolved_type.nil? || (resolved_type.is_a?(Module) && resolved_type.respond_to?(:kind))
859
+ [resolved_type, resolved_value]
860
+ else
861
+ raise ".resolve_type should return a type definition, but got #{resolved_type.inspect} (#{resolved_type.class}) from `resolve_type(#{type}, #{obj}, #{ctx})`"
862
+ end
863
+ end
918
864
  end
919
865
  end
920
866
 
@@ -922,36 +868,38 @@ module GraphQL
922
868
  if type.kind.object?
923
869
  type
924
870
  else
925
- raise NotImplementedError, "#{self.name}.resolve_type(type, obj, ctx) must be implemented to use Union types or Interface types (tried to resolve: #{type.name})"
871
+ raise GraphQL::RequiredImplementationMissingError, "#{self.name}.resolve_type(type, obj, ctx) must be implemented to use Union types or Interface types (tried to resolve: #{type.name})"
872
+ end
873
+ end
874
+ # rubocop:enable Lint/DuplicateMethods
875
+
876
+ def inherited(child_class)
877
+ if self == GraphQL::Schema
878
+ child_class.directives(default_directives.values)
926
879
  end
880
+ child_class.singleton_class.prepend(ResolveTypeWithType)
881
+ super
927
882
  end
928
883
 
929
884
  def object_from_id(node_id, ctx)
930
- raise NotImplementedError, "#{self.name}.object_from_id(node_id, ctx) must be implemented to load by ID (tried to load from id `#{node_id}`)"
885
+ raise GraphQL::RequiredImplementationMissingError, "#{self.name}.object_from_id(node_id, ctx) must be implemented to load by ID (tried to load from id `#{node_id}`)"
931
886
  end
932
887
 
933
888
  def id_from_object(object, type, ctx)
934
- raise NotImplementedError, "#{self.name}.id_from_object(object, type, ctx) must be implemented to create global ids (tried to create an id for `#{object.inspect}`)"
889
+ raise GraphQL::RequiredImplementationMissingError, "#{self.name}.id_from_object(object, type, ctx) must be implemented to create global ids (tried to create an id for `#{object.inspect}`)"
935
890
  end
936
891
 
937
- def visible?(member, context)
938
- call_on_type_class(member, :visible?, context, default: true)
892
+ def visible?(member, ctx)
893
+ member.visible?(ctx)
939
894
  end
940
895
 
941
- def accessible?(member, context)
942
- call_on_type_class(member, :accessible?, context, default: true)
896
+ def schema_directive(dir_class, **options)
897
+ @own_schema_directives ||= []
898
+ Member::HasDirectives.add_directive(self, @own_schema_directives, dir_class, options)
943
899
  end
944
900
 
945
- # This hook is called when a client tries to access one or more
946
- # fields that fail the `accessible?` check.
947
- #
948
- # By default, an error is added to the response. Override this hook to
949
- # track metrics or return a different error to the client.
950
- #
951
- # @param error [InaccessibleFieldsError] The analysis error for this check
952
- # @return [AnalysisError, nil] Return an error to skip the query
953
- def inaccessible_fields(error)
954
- error
901
+ def schema_directives
902
+ Member::HasDirectives.get_directives(self, @own_schema_directives, :schema_directives)
955
903
  end
956
904
 
957
905
  # This hook is called when an object fails an `authorized?` check.
@@ -989,221 +937,400 @@ module GraphQL
989
937
  unauthorized_object(unauthorized_error)
990
938
  end
991
939
 
992
- def type_error(type_err, ctx)
993
- DefaultTypeError.call(type_err, ctx)
940
+ def type_error(type_error, ctx)
941
+ case type_error
942
+ when GraphQL::InvalidNullError
943
+ ctx.errors << type_error
944
+ when GraphQL::UnresolvedTypeError, GraphQL::StringEncodingError, GraphQL::IntegerEncodingError
945
+ raise type_error
946
+ when GraphQL::IntegerDecodingError
947
+ nil
948
+ end
949
+ end
950
+
951
+ # A function to call when {#execute} receives an invalid query string
952
+ #
953
+ # The default is to add the error to `context.errors`
954
+ # @param parse_err [GraphQL::ParseError] The error encountered during parsing
955
+ # @param ctx [GraphQL::Query::Context] The context for the query where the error occurred
956
+ # @return void
957
+ def parse_error(parse_err, ctx)
958
+ ctx.errors.push(parse_err)
994
959
  end
995
960
 
996
961
  def lazy_resolve(lazy_class, value_method)
997
- lazy_classes[lazy_class] = value_method
962
+ lazy_methods.set(lazy_class, value_method)
998
963
  end
999
964
 
1000
965
  def instrument(instrument_step, instrumenter, options = {})
1001
- step = if instrument_step == :field && options[:after_built_ins]
1002
- :field_after_built_ins
1003
- else
1004
- instrument_step
1005
- end
1006
- defined_instrumenters[step] << instrumenter
966
+ own_instrumenters[instrument_step] << instrumenter
1007
967
  end
1008
968
 
1009
- def directives(new_directives = nil)
1010
- if new_directives
1011
- @directives = new_directives.reduce({}) { |m, d| m[d.name] = d; m }
969
+ # Add several directives at once
970
+ # @param new_directives [Class]
971
+ def directives(*new_directives)
972
+ if new_directives.any?
973
+ new_directives.flatten.each { |d| directive(d) }
1012
974
  end
1013
975
 
1014
- @directives ||= default_directives
976
+ inherited_dirs = find_inherited_value(:directives, default_directives)
977
+ if own_directives.any?
978
+ inherited_dirs.merge(own_directives)
979
+ else
980
+ inherited_dirs
981
+ end
1015
982
  end
1016
983
 
984
+ # Attach a single directive to this schema
985
+ # @param new_directive [Class]
986
+ # @return void
1017
987
  def directive(new_directive)
1018
- directives[new_directive.graphql_name] = new_directive
988
+ add_type_and_traverse(new_directive, root: false)
1019
989
  end
1020
990
 
1021
991
  def default_directives
1022
- {
1023
- "include" => GraphQL::Directive::IncludeDirective,
1024
- "skip" => GraphQL::Directive::SkipDirective,
1025
- "deprecated" => GraphQL::Directive::DeprecatedDirective,
1026
- }
992
+ @default_directives ||= {
993
+ "include" => GraphQL::Schema::Directive::Include,
994
+ "skip" => GraphQL::Schema::Directive::Skip,
995
+ "deprecated" => GraphQL::Schema::Directive::Deprecated,
996
+ "oneOf" => GraphQL::Schema::Directive::OneOf,
997
+ "specifiedBy" => GraphQL::Schema::Directive::SpecifiedBy,
998
+ }.freeze
1027
999
  end
1028
1000
 
1029
1001
  def tracer(new_tracer)
1030
- defined_tracers << new_tracer
1002
+ if !(trace_class_for(:default) < GraphQL::Tracing::CallLegacyTracers)
1003
+ trace_with(GraphQL::Tracing::CallLegacyTracers)
1004
+ end
1005
+
1006
+ own_tracers << new_tracer
1031
1007
  end
1032
1008
 
1033
- def query_analyzer(new_analyzer)
1034
- if new_analyzer == GraphQL::Authorization::Analyzer
1035
- warn("The Authorization query analyzer is deprecated. Authorizing at query runtime is generally a better idea.")
1036
- end
1037
- defined_query_analyzers << new_analyzer
1009
+ def tracers
1010
+ find_inherited_value(:tracers, EMPTY_ARRAY) + own_tracers
1038
1011
  end
1039
1012
 
1040
- def middleware(new_middleware = nil)
1041
- if new_middleware
1042
- defined_middleware << new_middleware
1013
+ # Mix `trace_mod` into this schema's `Trace` class so that its methods
1014
+ # will be called at runtime.
1015
+ #
1016
+ # @param trace_mod [Module] A module that implements tracing methods
1017
+ # @param mode [Symbol] Trace module will only be used for this trade mode
1018
+ # @param options [Hash] Keywords that will be passed to the tracing class during `#initialize`
1019
+ # @return [void]
1020
+ def trace_with(trace_mod, mode: :default, **options)
1021
+ if mode.is_a?(Array)
1022
+ mode.each { |m| trace_with(trace_mod, mode: m, **options) }
1043
1023
  else
1044
- graphql_definition.middleware
1024
+ tc = trace_class_for(mode)
1025
+ tc.include(trace_mod)
1026
+ if mode != :default
1027
+ own_trace_modules[mode] << trace_mod
1028
+ end
1029
+ t_opts = trace_options_for(mode)
1030
+ t_opts.merge!(options)
1045
1031
  end
1032
+ nil
1046
1033
  end
1047
1034
 
1048
- def multiplex_analyzer(new_analyzer)
1049
- defined_multiplex_analyzers << new_analyzer
1035
+ # The options hash for this trace mode
1036
+ # @return [Hash]
1037
+ def trace_options_for(mode)
1038
+ @trace_options_for_mode ||= {}
1039
+ @trace_options_for_mode[mode] ||= begin
1040
+ if superclass.respond_to?(:trace_options_for)
1041
+ superclass.trace_options_for(mode).dup
1042
+ else
1043
+ {}
1044
+ end
1045
+ end
1050
1046
  end
1051
1047
 
1052
- private
1048
+ # Create a trace instance which will include the trace modules specified for the optional mode.
1049
+ #
1050
+ # @param mode [Symbol] Trace modules for this trade mode will be included
1051
+ # @param options [Hash] Keywords that will be passed to the tracing class during `#initialize`
1052
+ # @return [Tracing::Trace]
1053
+ def new_trace(mode: nil, **options)
1054
+ target = options[:query] || options[:multiplex]
1055
+ mode ||= target && target.context[:trace_mode]
1056
+
1057
+ trace_mode = if mode
1058
+ mode
1059
+ elsif target && target.context[:backtrace]
1060
+ :default_backtrace
1061
+ else
1062
+ :default
1063
+ end
1053
1064
 
1054
- def lazy_classes
1055
- @lazy_classes ||= {}
1065
+ base_trace_options = trace_options_for(trace_mode)
1066
+ trace_options = base_trace_options.merge(options)
1067
+ trace_class_for_mode = trace_class_for(trace_mode)
1068
+ trace_class_for_mode.new(**trace_options)
1056
1069
  end
1057
1070
 
1058
- def defined_instrumenters
1059
- @defined_instrumenters ||= Hash.new { |h,k| h[k] = [] }
1071
+ def query_analyzer(new_analyzer)
1072
+ own_query_analyzers << new_analyzer
1060
1073
  end
1061
1074
 
1062
- def defined_tracers
1063
- @defined_tracers ||= []
1075
+ def query_analyzers
1076
+ find_inherited_value(:query_analyzers, EMPTY_ARRAY) + own_query_analyzers
1064
1077
  end
1065
1078
 
1066
- def defined_query_analyzers
1067
- @defined_query_analyzers ||= []
1079
+ def multiplex_analyzer(new_analyzer)
1080
+ own_multiplex_analyzers << new_analyzer
1068
1081
  end
1069
1082
 
1070
- def defined_middleware
1071
- @defined_middleware ||= []
1083
+ def multiplex_analyzers
1084
+ find_inherited_value(:multiplex_analyzers, EMPTY_ARRAY) + own_multiplex_analyzers
1072
1085
  end
1073
1086
 
1074
- def defined_multiplex_analyzers
1075
- @defined_multiplex_analyzers ||= []
1087
+ def sanitized_printer(new_sanitized_printer = nil)
1088
+ if new_sanitized_printer
1089
+ @own_sanitized_printer = new_sanitized_printer
1090
+ else
1091
+ @own_sanitized_printer || GraphQL::Language::SanitizedPrinter
1092
+ end
1076
1093
  end
1077
1094
 
1078
- # Given this schema member, find the class-based definition object
1079
- # whose `method_name` should be treated as an application hook
1080
- # @see {.visible?}
1081
- # @see {.accessible?}
1082
- # @see {.authorized?}
1083
- def call_on_type_class(member, method_name, *args, default:)
1084
- member = if member.respond_to?(:metadata) && member.metadata
1085
- member.metadata[:type_class] || member
1095
+ # Execute a query on itself.
1096
+ # @see {Query#initialize} for arguments.
1097
+ # @return [Hash] query result, ready to be serialized as JSON
1098
+ def execute(query_str = nil, **kwargs)
1099
+ if query_str
1100
+ kwargs[:query] = query_str
1101
+ end
1102
+ # Some of the query context _should_ be passed to the multiplex, too
1103
+ multiplex_context = if (ctx = kwargs[:context])
1104
+ {
1105
+ backtrace: ctx[:backtrace],
1106
+ tracers: ctx[:tracers],
1107
+ trace: ctx[:trace],
1108
+ dataloader: ctx[:dataloader],
1109
+ trace_mode: ctx[:trace_mode],
1110
+ }
1086
1111
  else
1087
- member
1112
+ {}
1113
+ end
1114
+ # Since we're running one query, don't run a multiplex-level complexity analyzer
1115
+ all_results = multiplex([kwargs], max_complexity: nil, context: multiplex_context)
1116
+ all_results[0]
1117
+ end
1118
+
1119
+ # Execute several queries on itself, concurrently.
1120
+ #
1121
+ # @example Run several queries at once
1122
+ # context = { ... }
1123
+ # queries = [
1124
+ # { query: params[:query_1], variables: params[:variables_1], context: context },
1125
+ # { query: params[:query_2], variables: params[:variables_2], context: context },
1126
+ # ]
1127
+ # results = MySchema.multiplex(queries)
1128
+ # render json: {
1129
+ # result_1: results[0],
1130
+ # result_2: results[1],
1131
+ # }
1132
+ #
1133
+ # @see {Query#initialize} for query keyword arguments
1134
+ # @see {Execution::Multiplex#run_all} for multiplex keyword arguments
1135
+ # @param queries [Array<Hash>] Keyword arguments for each query
1136
+ # @param context [Hash] Multiplex-level context
1137
+ # @return [Array<Hash>] One result for each query in the input
1138
+ def multiplex(queries, **kwargs)
1139
+ GraphQL::Execution::Interpreter.run_all(self, queries, **kwargs)
1140
+ end
1141
+
1142
+ def instrumenters
1143
+ inherited_instrumenters = find_inherited_value(:instrumenters) || Hash.new { |h,k| h[k] = [] }
1144
+ inherited_instrumenters.merge(own_instrumenters) do |_step, inherited, own|
1145
+ inherited + own
1088
1146
  end
1147
+ end
1089
1148
 
1090
- if member.respond_to?(:relay_node_type) && (t = member.relay_node_type)
1091
- member = t
1149
+ # @api private
1150
+ def add_subscription_extension_if_necessary
1151
+ if !defined?(@subscription_extension_added) && subscription && self.subscriptions
1152
+ @subscription_extension_added = true
1153
+ subscription.all_field_definitions.each do |field|
1154
+ if !field.extensions.any? { |ext| ext.is_a?(Subscriptions::DefaultSubscriptionResolveExtension) }
1155
+ field.extension(Subscriptions::DefaultSubscriptionResolveExtension)
1156
+ end
1157
+ end
1092
1158
  end
1159
+ end
1160
+
1161
+ def query_stack_error(query, err)
1162
+ query.context.errors.push(GraphQL::ExecutionError.new("This query is too large to execute."))
1163
+ end
1093
1164
 
1094
- if member.respond_to?(method_name)
1095
- member.public_send(method_name, *args)
1165
+ # Call the given block at the right time, either:
1166
+ # - Right away, if `value` is not registered with `lazy_resolve`
1167
+ # - After resolving `value`, if it's registered with `lazy_resolve` (eg, `Promise`)
1168
+ # @api private
1169
+ def after_lazy(value, &block)
1170
+ if lazy?(value)
1171
+ GraphQL::Execution::Lazy.new do
1172
+ result = sync_lazy(value)
1173
+ # The returned result might also be lazy, so check it, too
1174
+ after_lazy(result, &block)
1175
+ end
1096
1176
  else
1097
- default
1177
+ yield(value) if block_given?
1098
1178
  end
1099
1179
  end
1100
- end
1101
1180
 
1181
+ # Override this method to handle lazy objects in a custom way.
1182
+ # @param value [Object] an instance of a class registered with {.lazy_resolve}
1183
+ # @return [Object] A GraphQL-ready (non-lazy) object
1184
+ # @api private
1185
+ def sync_lazy(value)
1186
+ lazy_method = lazy_method_name(value)
1187
+ if lazy_method
1188
+ synced_value = value.public_send(lazy_method)
1189
+ sync_lazy(synced_value)
1190
+ else
1191
+ value
1192
+ end
1193
+ end
1102
1194
 
1103
- def self.inherited(child_class)
1104
- child_class.singleton_class.class_eval do
1105
- prepend(MethodWrappers)
1195
+ # @return [Symbol, nil] The method name to lazily resolve `obj`, or nil if `obj`'s class wasn't registered with {#lazy_resolve}.
1196
+ def lazy_method_name(obj)
1197
+ lazy_methods.get(obj)
1106
1198
  end
1107
- end
1108
1199
 
1109
- module MethodWrappers
1110
- # Wrap the user-provided resolve-type in a correctness check
1111
- def resolve_type(type, obj, ctx = :__undefined__)
1112
- graphql_definition.check_resolved_type(type, obj, ctx) do |ok_type, ok_obj, ok_ctx|
1113
- super(ok_type, ok_obj, ok_ctx)
1114
- end
1200
+ # @return [Boolean] True if this object should be lazily resolved
1201
+ def lazy?(obj)
1202
+ !!lazy_method_name(obj)
1115
1203
  end
1116
- end
1117
1204
 
1118
- # Call the given block at the right time, either:
1119
- # - Right away, if `value` is not registered with `lazy_resolve`
1120
- # - After resolving `value`, if it's registered with `lazy_resolve` (eg, `Promise`)
1121
- # @api private
1122
- def after_lazy(value)
1123
- if lazy?(value)
1124
- GraphQL::Execution::Lazy.new do
1125
- result = sync_lazy(value)
1126
- # The returned result might also be lazy, so check it, too
1127
- after_lazy(result) do |final_result|
1128
- yield(final_result) if block_given?
1205
+ # Return a lazy if any of `maybe_lazies` are lazy,
1206
+ # otherwise, call the block eagerly and return the result.
1207
+ # @param maybe_lazies [Array]
1208
+ # @api private
1209
+ def after_any_lazies(maybe_lazies)
1210
+ if maybe_lazies.any? { |l| lazy?(l) }
1211
+ GraphQL::Execution::Lazy.all(maybe_lazies).then do |result|
1212
+ yield result
1129
1213
  end
1214
+ else
1215
+ yield maybe_lazies
1130
1216
  end
1131
- else
1132
- yield(value) if block_given?
1133
1217
  end
1134
- end
1135
1218
 
1136
- # Override this method to handle lazy objects in a custom way.
1137
- # @param value [Object] an instance of a class registered with {.lazy_resolve}
1138
- # @param ctx [GraphQL::Query::Context] the context for this query
1139
- # @return [Object] A GraphQL-ready (non-lazy) object
1140
- def self.sync_lazy(value)
1141
- if block_given?
1142
- # This was already hit by the instance, just give it back
1143
- yield(value)
1144
- else
1145
- # This was called directly on the class, hit the instance
1146
- # which has the lazy method map
1147
- self.graphql_definition.sync_lazy(value)
1219
+ private
1220
+
1221
+ # @param t [Module, Array<Module>]
1222
+ # @return [void]
1223
+ def add_type_and_traverse(t, root:)
1224
+ if root
1225
+ @root_types ||= []
1226
+ @root_types << t
1227
+ end
1228
+ new_types = Array(t)
1229
+ addition = Schema::Addition.new(schema: self, own_types: own_types, new_types: new_types)
1230
+ addition.types.each do |name, types_entry| # rubocop:disable Development/ContextIsPassedCop -- build-time, not query-time
1231
+ if (prev_entry = own_types[name])
1232
+ prev_entries = case prev_entry
1233
+ when Array
1234
+ prev_entry
1235
+ when Module
1236
+ own_types[name] = [prev_entry]
1237
+ else
1238
+ raise "Invariant: unexpected prev_entry at #{name.inspect} when adding #{t.inspect}"
1239
+ end
1240
+
1241
+ case types_entry
1242
+ when Array
1243
+ prev_entries.concat(types_entry)
1244
+ prev_entries.uniq! # in case any are being re-visited
1245
+ when Module
1246
+ if !prev_entries.include?(types_entry)
1247
+ prev_entries << types_entry
1248
+ end
1249
+ else
1250
+ raise "Invariant: unexpected types_entry at #{name} when adding #{t.inspect}"
1251
+ end
1252
+ else
1253
+ if types_entry.is_a?(Array)
1254
+ types_entry.uniq!
1255
+ end
1256
+ own_types[name] = types_entry
1257
+ end
1258
+ end
1259
+
1260
+ own_possible_types.merge!(addition.possible_types) { |key, old_val, new_val| old_val + new_val }
1261
+ own_union_memberships.merge!(addition.union_memberships)
1262
+
1263
+ addition.references.each { |thing, pointers|
1264
+ pointers.each { |pointer| references_to(thing, from: pointer) }
1265
+ }
1266
+
1267
+ addition.directives.each { |dir_class| own_directives[dir_class.graphql_name] = dir_class }
1268
+
1269
+ addition.arguments_with_default_values.each do |arg|
1270
+ arg.validate_default_value
1271
+ end
1148
1272
  end
1149
- end
1150
1273
 
1151
- # @see Schema.sync_lazy for a hook to override
1152
- # @api private
1153
- def sync_lazy(value)
1154
- self.class.sync_lazy(value) { |v|
1155
- lazy_method = lazy_method_name(v)
1156
- if lazy_method
1157
- synced_value = value.public_send(lazy_method)
1158
- sync_lazy(synced_value)
1159
- else
1160
- v
1274
+ def lazy_methods
1275
+ if !defined?(@lazy_methods)
1276
+ if inherited_map = find_inherited_value(:lazy_methods)
1277
+ # this isn't _completely_ inherited :S (Things added after `dup` won't work)
1278
+ @lazy_methods = inherited_map.dup
1279
+ else
1280
+ @lazy_methods = GraphQL::Execution::Lazy::LazyMethodMap.new
1281
+ @lazy_methods.set(GraphQL::Execution::Lazy, :value)
1282
+ @lazy_methods.set(GraphQL::Dataloader::Request, :load)
1283
+ end
1161
1284
  end
1162
- }
1163
- end
1285
+ @lazy_methods
1286
+ end
1164
1287
 
1165
- protected
1288
+ def own_types
1289
+ @own_types ||= {}
1290
+ end
1166
1291
 
1167
- def rescues?
1168
- !!@rescue_middleware
1169
- end
1292
+ def non_introspection_types
1293
+ find_inherited_value(:non_introspection_types, EMPTY_HASH).merge(own_types)
1294
+ end
1170
1295
 
1171
- # Lazily create a middleware and add it to the schema
1172
- # (Don't add it if it's not used)
1173
- def rescue_middleware
1174
- @rescue_middleware ||= GraphQL::Schema::RescueMiddleware.new.tap { |m| middleware.insert(0, m) }
1175
- end
1296
+ def own_plugins
1297
+ @own_plugins ||= []
1298
+ end
1176
1299
 
1177
- private
1178
-
1179
- def rebuild_artifacts
1180
- if @rebuilding_artifacts
1181
- raise CyclicalDefinitionError, "Part of the schema build process re-triggered the schema build process, causing an infinite loop. Avoid using Schema#types, Schema#possible_types, and Schema#get_field during schema build."
1182
- else
1183
- @rebuilding_artifacts = true
1184
- @introspection_system = Schema::IntrospectionSystem.new(self)
1185
- traversal = Traversal.new(self)
1186
- @types = traversal.type_map
1187
- @root_types = [query, mutation, subscription]
1188
- @instrumented_field_map = traversal.instrumented_field_map
1189
- @type_reference_map = traversal.type_reference_map
1190
- @union_memberships = traversal.union_memberships
1191
- @find_cache = {}
1192
- @finder = Finder.new(self)
1193
- end
1194
- ensure
1195
- @rebuilding_artifacts = false
1196
- end
1300
+ def own_orphan_types
1301
+ @own_orphan_types ||= []
1302
+ end
1197
1303
 
1198
- class CyclicalDefinitionError < GraphQL::Error
1199
- end
1304
+ def own_possible_types
1305
+ @own_possible_types ||= {}
1306
+ end
1200
1307
 
1201
- def with_definition_error_check
1202
- if @definition_error
1203
- raise @definition_error
1204
- else
1205
- yield
1308
+ def own_union_memberships
1309
+ @own_union_memberships ||= {}
1310
+ end
1311
+
1312
+ def own_directives
1313
+ @own_directives ||= {}
1314
+ end
1315
+
1316
+ def own_instrumenters
1317
+ @own_instrumenters ||= Hash.new { |h,k| h[k] = [] }
1318
+ end
1319
+
1320
+ def own_tracers
1321
+ @own_tracers ||= []
1322
+ end
1323
+
1324
+ def own_query_analyzers
1325
+ @defined_query_analyzers ||= []
1326
+ end
1327
+
1328
+ def own_multiplex_analyzers
1329
+ @own_multiplex_analyzers ||= []
1206
1330
  end
1207
1331
  end
1332
+
1333
+ # Install these here so that subclasses will also install it.
1334
+ self.connections = GraphQL::Pagination::Connections.new(schema: self)
1208
1335
  end
1209
1336
  end