graphql 1.12.12 → 2.2.14

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 (392) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/core.rb +3 -8
  3. data/lib/generators/graphql/enum_generator.rb +4 -10
  4. data/lib/generators/graphql/field_extractor.rb +31 -0
  5. data/lib/generators/graphql/input_generator.rb +50 -0
  6. data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
  7. data/lib/generators/graphql/{templates → install/templates}/base_mutation.erb +2 -0
  8. data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +2 -0
  9. data/lib/generators/graphql/install_generator.rb +14 -4
  10. data/lib/generators/graphql/interface_generator.rb +7 -7
  11. data/lib/generators/graphql/mutation_create_generator.rb +22 -0
  12. data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
  13. data/lib/generators/graphql/mutation_generator.rb +5 -30
  14. data/lib/generators/graphql/mutation_update_generator.rb +22 -0
  15. data/lib/generators/graphql/object_generator.rb +10 -38
  16. data/lib/generators/graphql/orm_mutations_base.rb +40 -0
  17. data/lib/generators/graphql/relay.rb +23 -12
  18. data/lib/generators/graphql/scalar_generator.rb +4 -2
  19. data/lib/generators/graphql/templates/base_argument.erb +2 -0
  20. data/lib/generators/graphql/templates/base_connection.erb +2 -0
  21. data/lib/generators/graphql/templates/base_edge.erb +2 -0
  22. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  23. data/lib/generators/graphql/templates/base_field.erb +2 -0
  24. data/lib/generators/graphql/templates/base_input_object.erb +2 -0
  25. data/lib/generators/graphql/templates/base_interface.erb +2 -0
  26. data/lib/generators/graphql/templates/base_object.erb +2 -0
  27. data/lib/generators/graphql/templates/base_resolver.erb +6 -0
  28. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  29. data/lib/generators/graphql/templates/base_union.erb +2 -0
  30. data/lib/generators/graphql/templates/enum.erb +5 -1
  31. data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
  32. data/lib/generators/graphql/templates/input.erb +9 -0
  33. data/lib/generators/graphql/templates/interface.erb +4 -2
  34. data/lib/generators/graphql/templates/loader.erb +2 -0
  35. data/lib/generators/graphql/templates/mutation.erb +3 -1
  36. data/lib/generators/graphql/templates/mutation_create.erb +20 -0
  37. data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
  38. data/lib/generators/graphql/templates/mutation_update.erb +21 -0
  39. data/lib/generators/graphql/templates/node_type.erb +2 -0
  40. data/lib/generators/graphql/templates/object.erb +4 -2
  41. data/lib/generators/graphql/templates/query_type.erb +2 -0
  42. data/lib/generators/graphql/templates/scalar.erb +3 -1
  43. data/lib/generators/graphql/templates/schema.erb +19 -2
  44. data/lib/generators/graphql/templates/union.erb +4 -2
  45. data/lib/generators/graphql/type_generator.rb +46 -10
  46. data/lib/generators/graphql/union_generator.rb +5 -5
  47. data/lib/graphql/analysis/ast/analyzer.rb +7 -0
  48. data/lib/graphql/analysis/ast/field_usage.rb +55 -1
  49. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
  50. data/lib/graphql/analysis/ast/query_complexity.rb +88 -140
  51. data/lib/graphql/analysis/ast/query_depth.rb +7 -3
  52. data/lib/graphql/analysis/ast/visitor.rb +50 -42
  53. data/lib/graphql/analysis/ast.rb +26 -23
  54. data/lib/graphql/analysis.rb +0 -7
  55. data/lib/graphql/backtrace/table.rb +4 -22
  56. data/lib/graphql/backtrace/trace.rb +93 -0
  57. data/lib/graphql/backtrace/tracer.rb +8 -6
  58. data/lib/graphql/backtrace.rb +3 -8
  59. data/lib/graphql/coercion_error.rb +1 -9
  60. data/lib/graphql/dataloader/async_dataloader.rb +85 -0
  61. data/lib/graphql/dataloader/null_dataloader.rb +3 -1
  62. data/lib/graphql/dataloader/request.rb +5 -0
  63. data/lib/graphql/dataloader/source.rb +120 -31
  64. data/lib/graphql/dataloader.rb +168 -142
  65. data/lib/graphql/date_encoding_error.rb +16 -0
  66. data/lib/graphql/dig.rb +1 -1
  67. data/lib/graphql/duration_encoding_error.rb +16 -0
  68. data/lib/graphql/execution/errors.rb +12 -81
  69. data/lib/graphql/execution/interpreter/arguments.rb +2 -2
  70. data/lib/graphql/execution/interpreter/arguments_cache.rb +36 -34
  71. data/lib/graphql/execution/interpreter/resolve.rb +32 -2
  72. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +170 -0
  73. data/lib/graphql/execution/interpreter/runtime.rb +414 -341
  74. data/lib/graphql/execution/interpreter.rb +122 -80
  75. data/lib/graphql/execution/lazy.rb +11 -21
  76. data/lib/graphql/execution/lookahead.rb +125 -54
  77. data/lib/graphql/execution/multiplex.rb +4 -172
  78. data/lib/graphql/execution.rb +11 -4
  79. data/lib/graphql/integer_encoding_error.rb +18 -2
  80. data/lib/graphql/introspection/directive_location_enum.rb +2 -2
  81. data/lib/graphql/introspection/directive_type.rb +5 -3
  82. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  83. data/lib/graphql/introspection/entry_points.rb +11 -18
  84. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  85. data/lib/graphql/introspection/field_type.rb +3 -3
  86. data/lib/graphql/introspection/input_value_type.rb +10 -4
  87. data/lib/graphql/introspection/schema_type.rb +12 -5
  88. data/lib/graphql/introspection/type_type.rb +25 -12
  89. data/lib/graphql/introspection.rb +6 -2
  90. data/lib/graphql/language/block_string.rb +37 -25
  91. data/lib/graphql/language/definition_slice.rb +1 -1
  92. data/lib/graphql/language/document_from_schema_definition.rb +78 -65
  93. data/lib/graphql/language/lexer.rb +345 -1467
  94. data/lib/graphql/language/nodes.rb +145 -91
  95. data/lib/graphql/language/parser.rb +701 -1921
  96. data/lib/graphql/language/printer.rb +351 -155
  97. data/lib/graphql/language/sanitized_printer.rb +25 -27
  98. data/lib/graphql/language/static_visitor.rb +167 -0
  99. data/lib/graphql/language/token.rb +0 -4
  100. data/lib/graphql/language/visitor.rb +188 -141
  101. data/lib/graphql/language.rb +1 -0
  102. data/lib/graphql/load_application_object_failed_error.rb +5 -1
  103. data/lib/graphql/name_validator.rb +0 -4
  104. data/lib/graphql/pagination/active_record_relation_connection.rb +37 -8
  105. data/lib/graphql/pagination/array_connection.rb +8 -6
  106. data/lib/graphql/pagination/connection.rb +61 -7
  107. data/lib/graphql/pagination/connections.rb +22 -23
  108. data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
  109. data/lib/graphql/pagination/relation_connection.rb +60 -28
  110. data/lib/graphql/query/context/scoped_context.rb +101 -0
  111. data/lib/graphql/query/context.rb +109 -189
  112. data/lib/graphql/query/input_validation_result.rb +10 -1
  113. data/lib/graphql/query/null_context.rb +14 -29
  114. data/lib/graphql/query/validation_pipeline.rb +15 -39
  115. data/lib/graphql/query/variable_validation_error.rb +2 -2
  116. data/lib/graphql/query/variables.rb +35 -17
  117. data/lib/graphql/query.rb +78 -65
  118. data/lib/graphql/railtie.rb +8 -109
  119. data/lib/graphql/rake_task/validate.rb +1 -1
  120. data/lib/graphql/rake_task.rb +30 -11
  121. data/lib/graphql/relay/range_add.rb +9 -16
  122. data/lib/graphql/relay.rb +0 -15
  123. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  124. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  125. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  126. data/lib/graphql/rubocop.rb +4 -0
  127. data/lib/graphql/schema/addition.rb +78 -45
  128. data/lib/graphql/schema/always_visible.rb +10 -0
  129. data/lib/graphql/schema/argument.rb +134 -80
  130. data/lib/graphql/schema/base_64_encoder.rb +3 -5
  131. data/lib/graphql/schema/build_from_definition.rb +60 -38
  132. data/lib/graphql/schema/directive/feature.rb +1 -1
  133. data/lib/graphql/schema/directive/flagged.rb +2 -2
  134. data/lib/graphql/schema/directive/include.rb +1 -1
  135. data/lib/graphql/schema/directive/one_of.rb +24 -0
  136. data/lib/graphql/schema/directive/skip.rb +1 -1
  137. data/lib/graphql/schema/directive/specified_by.rb +14 -0
  138. data/lib/graphql/schema/directive/transform.rb +2 -2
  139. data/lib/graphql/schema/directive.rb +33 -21
  140. data/lib/graphql/schema/enum.rb +93 -46
  141. data/lib/graphql/schema/enum_value.rb +4 -21
  142. data/lib/graphql/schema/field/connection_extension.rb +6 -16
  143. data/lib/graphql/schema/field/scope_extension.rb +8 -1
  144. data/lib/graphql/schema/field.rb +432 -337
  145. data/lib/graphql/schema/field_extension.rb +86 -2
  146. data/lib/graphql/schema/find_inherited_value.rb +3 -7
  147. data/lib/graphql/schema/finder.rb +5 -5
  148. data/lib/graphql/schema/has_single_input_argument.rb +156 -0
  149. data/lib/graphql/schema/input_object.rb +88 -90
  150. data/lib/graphql/schema/interface.rb +19 -59
  151. data/lib/graphql/schema/introspection_system.rb +6 -9
  152. data/lib/graphql/schema/late_bound_type.rb +8 -2
  153. data/lib/graphql/schema/list.rb +18 -7
  154. data/lib/graphql/schema/loader.rb +3 -3
  155. data/lib/graphql/schema/member/base_dsl_methods.rb +18 -19
  156. data/lib/graphql/schema/member/build_type.rb +16 -13
  157. data/lib/graphql/schema/member/has_arguments.rb +288 -84
  158. data/lib/graphql/schema/member/has_ast_node.rb +12 -0
  159. data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
  160. data/lib/graphql/schema/member/has_directives.rb +81 -61
  161. data/lib/graphql/schema/member/has_fields.rb +149 -31
  162. data/lib/graphql/schema/member/has_interfaces.rb +143 -0
  163. data/lib/graphql/schema/member/has_validators.rb +32 -6
  164. data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
  165. data/lib/graphql/schema/member/scoped.rb +19 -0
  166. data/lib/graphql/schema/member/type_system_helpers.rb +17 -0
  167. data/lib/graphql/schema/member/validates_input.rb +6 -6
  168. data/lib/graphql/schema/member.rb +1 -6
  169. data/lib/graphql/schema/mutation.rb +0 -9
  170. data/lib/graphql/schema/non_null.rb +7 -7
  171. data/lib/graphql/schema/object.rb +30 -119
  172. data/lib/graphql/schema/printer.rb +23 -25
  173. data/lib/graphql/schema/relay_classic_mutation.rb +13 -90
  174. data/lib/graphql/schema/resolver/has_payload_type.rb +46 -11
  175. data/lib/graphql/schema/resolver.rb +101 -102
  176. data/lib/graphql/schema/scalar.rb +20 -21
  177. data/lib/graphql/schema/subscription.rb +45 -17
  178. data/lib/graphql/schema/timeout.rb +25 -29
  179. data/lib/graphql/schema/type_expression.rb +1 -1
  180. data/lib/graphql/schema/type_membership.rb +21 -4
  181. data/lib/graphql/schema/union.rb +15 -15
  182. data/lib/graphql/schema/unique_within_type.rb +1 -1
  183. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  184. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  185. data/lib/graphql/schema/validator/exclusion_validator.rb +3 -1
  186. data/lib/graphql/schema/validator/format_validator.rb +4 -5
  187. data/lib/graphql/schema/validator/inclusion_validator.rb +3 -1
  188. data/lib/graphql/schema/validator/length_validator.rb +5 -3
  189. data/lib/graphql/schema/validator/numericality_validator.rb +13 -2
  190. data/lib/graphql/schema/validator/required_validator.rb +29 -15
  191. data/lib/graphql/schema/validator.rb +35 -27
  192. data/lib/graphql/schema/warden.rb +259 -132
  193. data/lib/graphql/schema/wrapper.rb +0 -5
  194. data/lib/graphql/schema.rb +658 -989
  195. data/lib/graphql/static_validation/all_rules.rb +3 -1
  196. data/lib/graphql/static_validation/base_visitor.rb +14 -28
  197. data/lib/graphql/static_validation/definition_dependencies.rb +7 -2
  198. data/lib/graphql/static_validation/error.rb +3 -1
  199. data/lib/graphql/static_validation/literal_validator.rb +21 -4
  200. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  201. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -1
  202. data/lib/graphql/static_validation/rules/directives_are_defined.rb +11 -5
  203. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +13 -13
  204. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
  205. data/lib/graphql/static_validation/rules/fields_will_merge.rb +54 -28
  206. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
  207. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
  208. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  209. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  210. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  211. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  212. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +5 -3
  213. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +4 -4
  214. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +13 -7
  215. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +1 -1
  216. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +13 -7
  217. data/lib/graphql/static_validation/validation_context.rb +16 -6
  218. data/lib/graphql/static_validation/validator.rb +11 -27
  219. data/lib/graphql/static_validation.rb +0 -3
  220. data/lib/graphql/string_encoding_error.rb +13 -3
  221. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +46 -9
  222. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +38 -1
  223. data/lib/graphql/subscriptions/event.rb +75 -37
  224. data/lib/graphql/subscriptions/serialize.rb +25 -3
  225. data/lib/graphql/subscriptions.rb +59 -47
  226. data/lib/graphql/testing/helpers.rb +129 -0
  227. data/lib/graphql/testing.rb +2 -0
  228. data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
  229. data/lib/graphql/tracing/active_support_notifications_tracing.rb +6 -20
  230. data/lib/graphql/tracing/appoptics_trace.rb +251 -0
  231. data/lib/graphql/tracing/appoptics_tracing.rb +2 -2
  232. data/lib/graphql/tracing/appsignal_trace.rb +77 -0
  233. data/lib/graphql/tracing/appsignal_tracing.rb +15 -0
  234. data/lib/graphql/tracing/data_dog_trace.rb +183 -0
  235. data/lib/graphql/tracing/data_dog_tracing.rb +25 -15
  236. data/lib/graphql/{execution/instrumentation.rb → tracing/legacy_hooks_trace.rb} +10 -28
  237. data/lib/graphql/tracing/legacy_trace.rb +69 -0
  238. data/lib/graphql/tracing/new_relic_trace.rb +75 -0
  239. data/lib/graphql/tracing/notifications_trace.rb +45 -0
  240. data/lib/graphql/tracing/notifications_tracing.rb +59 -0
  241. data/lib/graphql/tracing/platform_trace.rb +118 -0
  242. data/lib/graphql/tracing/platform_tracing.rb +46 -49
  243. data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +4 -2
  244. data/lib/graphql/tracing/prometheus_trace.rb +89 -0
  245. data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
  246. data/lib/graphql/tracing/scout_trace.rb +72 -0
  247. data/lib/graphql/tracing/sentry_trace.rb +112 -0
  248. data/lib/graphql/tracing/statsd_trace.rb +56 -0
  249. data/lib/graphql/tracing/trace.rb +76 -0
  250. data/lib/graphql/tracing.rb +20 -41
  251. data/lib/graphql/type_kinds.rb +6 -3
  252. data/lib/graphql/types/big_int.rb +5 -1
  253. data/lib/graphql/types/int.rb +1 -1
  254. data/lib/graphql/types/iso_8601_date.rb +17 -6
  255. data/lib/graphql/types/iso_8601_date_time.rb +12 -1
  256. data/lib/graphql/types/iso_8601_duration.rb +77 -0
  257. data/lib/graphql/types/relay/base_connection.rb +16 -6
  258. data/lib/graphql/types/relay/connection_behaviors.rb +82 -32
  259. data/lib/graphql/types/relay/edge_behaviors.rb +36 -7
  260. data/lib/graphql/types/relay/has_node_field.rb +2 -2
  261. data/lib/graphql/types/relay/has_nodes_field.rb +2 -2
  262. data/lib/graphql/types/relay/node_behaviors.rb +12 -2
  263. data/lib/graphql/types/relay/page_info_behaviors.rb +7 -2
  264. data/lib/graphql/types/relay.rb +0 -3
  265. data/lib/graphql/types/string.rb +2 -2
  266. data/lib/graphql/types.rb +1 -0
  267. data/lib/graphql/unauthorized_error.rb +1 -1
  268. data/lib/graphql/version.rb +1 -1
  269. data/lib/graphql.rb +33 -95
  270. data/readme.md +13 -6
  271. metadata +102 -185
  272. data/lib/graphql/analysis/analyze_query.rb +0 -98
  273. data/lib/graphql/analysis/field_usage.rb +0 -45
  274. data/lib/graphql/analysis/max_query_complexity.rb +0 -26
  275. data/lib/graphql/analysis/max_query_depth.rb +0 -26
  276. data/lib/graphql/analysis/query_complexity.rb +0 -88
  277. data/lib/graphql/analysis/query_depth.rb +0 -43
  278. data/lib/graphql/analysis/reducer_state.rb +0 -48
  279. data/lib/graphql/argument.rb +0 -131
  280. data/lib/graphql/authorization.rb +0 -82
  281. data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
  282. data/lib/graphql/backwards_compatibility.rb +0 -61
  283. data/lib/graphql/base_type.rb +0 -230
  284. data/lib/graphql/boolean_type.rb +0 -2
  285. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  286. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  287. data/lib/graphql/compatibility/execution_specification.rb +0 -436
  288. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  289. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
  290. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  291. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  292. data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
  293. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
  294. data/lib/graphql/compatibility.rb +0 -5
  295. data/lib/graphql/define/assign_argument.rb +0 -12
  296. data/lib/graphql/define/assign_connection.rb +0 -13
  297. data/lib/graphql/define/assign_enum_value.rb +0 -18
  298. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  299. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  300. data/lib/graphql/define/assign_object_field.rb +0 -42
  301. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  302. data/lib/graphql/define/instance_definable.rb +0 -240
  303. data/lib/graphql/define/no_definition_error.rb +0 -7
  304. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  305. data/lib/graphql/define/type_definer.rb +0 -31
  306. data/lib/graphql/define.rb +0 -31
  307. data/lib/graphql/deprecated_dsl.rb +0 -47
  308. data/lib/graphql/deprecation.rb +0 -13
  309. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  310. data/lib/graphql/directive/include_directive.rb +0 -2
  311. data/lib/graphql/directive/skip_directive.rb +0 -2
  312. data/lib/graphql/directive.rb +0 -111
  313. data/lib/graphql/enum_type.rb +0 -129
  314. data/lib/graphql/execution/execute.rb +0 -333
  315. data/lib/graphql/execution/flatten.rb +0 -40
  316. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  317. data/lib/graphql/execution/typecast.rb +0 -50
  318. data/lib/graphql/field/resolve.rb +0 -59
  319. data/lib/graphql/field.rb +0 -226
  320. data/lib/graphql/filter.rb +0 -53
  321. data/lib/graphql/float_type.rb +0 -2
  322. data/lib/graphql/function.rb +0 -128
  323. data/lib/graphql/id_type.rb +0 -2
  324. data/lib/graphql/input_object_type.rb +0 -138
  325. data/lib/graphql/int_type.rb +0 -2
  326. data/lib/graphql/interface_type.rb +0 -72
  327. data/lib/graphql/internal_representation/document.rb +0 -27
  328. data/lib/graphql/internal_representation/node.rb +0 -206
  329. data/lib/graphql/internal_representation/print.rb +0 -51
  330. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  331. data/lib/graphql/internal_representation/scope.rb +0 -88
  332. data/lib/graphql/internal_representation/visit.rb +0 -36
  333. data/lib/graphql/internal_representation.rb +0 -7
  334. data/lib/graphql/language/lexer.rl +0 -262
  335. data/lib/graphql/language/parser.y +0 -543
  336. data/lib/graphql/list_type.rb +0 -80
  337. data/lib/graphql/non_null_type.rb +0 -71
  338. data/lib/graphql/object_type.rb +0 -130
  339. data/lib/graphql/query/arguments.rb +0 -189
  340. data/lib/graphql/query/arguments_cache.rb +0 -24
  341. data/lib/graphql/query/executor.rb +0 -52
  342. data/lib/graphql/query/literal_input.rb +0 -136
  343. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  344. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  345. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  346. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  347. data/lib/graphql/query/serial_execution.rb +0 -40
  348. data/lib/graphql/relay/array_connection.rb +0 -83
  349. data/lib/graphql/relay/base_connection.rb +0 -189
  350. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  351. data/lib/graphql/relay/connection_resolve.rb +0 -43
  352. data/lib/graphql/relay/connection_type.rb +0 -41
  353. data/lib/graphql/relay/edge.rb +0 -27
  354. data/lib/graphql/relay/edge_type.rb +0 -19
  355. data/lib/graphql/relay/edges_instrumentation.rb +0 -40
  356. data/lib/graphql/relay/global_id_resolve.rb +0 -18
  357. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  358. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  359. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  360. data/lib/graphql/relay/mutation/result.rb +0 -38
  361. data/lib/graphql/relay/mutation.rb +0 -106
  362. data/lib/graphql/relay/node.rb +0 -39
  363. data/lib/graphql/relay/page_info.rb +0 -7
  364. data/lib/graphql/relay/relation_connection.rb +0 -188
  365. data/lib/graphql/relay/type_extensions.rb +0 -32
  366. data/lib/graphql/scalar_type.rb +0 -91
  367. data/lib/graphql/schema/base_64_bp.rb +0 -26
  368. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  369. data/lib/graphql/schema/default_parse_error.rb +0 -10
  370. data/lib/graphql/schema/default_type_error.rb +0 -17
  371. data/lib/graphql/schema/member/accepts_definition.rb +0 -152
  372. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -31
  373. data/lib/graphql/schema/member/instrumentation.rb +0 -131
  374. data/lib/graphql/schema/middleware_chain.rb +0 -82
  375. data/lib/graphql/schema/possible_types.rb +0 -44
  376. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  377. data/lib/graphql/schema/timeout_middleware.rb +0 -88
  378. data/lib/graphql/schema/traversal.rb +0 -228
  379. data/lib/graphql/schema/validation.rb +0 -313
  380. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  381. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  382. data/lib/graphql/static_validation/type_stack.rb +0 -216
  383. data/lib/graphql/string_type.rb +0 -2
  384. data/lib/graphql/subscriptions/instrumentation.rb +0 -79
  385. data/lib/graphql/subscriptions/subscription_root.rb +0 -76
  386. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  387. data/lib/graphql/types/relay/default_relay.rb +0 -27
  388. data/lib/graphql/types/relay/node_field.rb +0 -25
  389. data/lib/graphql/types/relay/nodes_field.rb +0 -27
  390. data/lib/graphql/union_type.rb +0 -115
  391. data/lib/graphql/upgrader/member.rb +0 -937
  392. data/lib/graphql/upgrader/schema.rb +0 -38
@@ -2,20 +2,12 @@
2
2
  module GraphQL
3
3
  class Schema
4
4
  class Argument
5
- if !String.method_defined?(:-@)
6
- using GraphQL::StringDedupBackport
7
- end
8
-
9
- include GraphQL::Schema::Member::CachedGraphQLDefinition
10
- include GraphQL::Schema::Member::AcceptsDefinition
11
5
  include GraphQL::Schema::Member::HasPath
12
6
  include GraphQL::Schema::Member::HasAstNode
13
7
  include GraphQL::Schema::Member::HasDirectives
14
8
  include GraphQL::Schema::Member::HasDeprecationReason
15
9
  include GraphQL::Schema::Member::HasValidators
16
- include GraphQL::Schema::FindInheritedValue::EmptyObjects
17
-
18
- NO_DEFAULT = :__no_default__
10
+ include GraphQL::EmptyObjects
19
11
 
20
12
  # @return [String] the GraphQL name for this argument, camelized unless `camelize: false` is provided
21
13
  attr_reader :name
@@ -24,8 +16,14 @@ module GraphQL
24
16
  # @return [GraphQL::Schema::Field, Class] The field or input object this argument belongs to
25
17
  attr_reader :owner
26
18
 
27
- # @return [Symbol] A method to call to transform this value before sending it to field resolution method
28
- attr_reader :prepare
19
+ # @param new_prepare [Method, Proc]
20
+ # @return [Symbol] A method or proc to call to transform this value before sending it to field resolution method
21
+ def prepare(new_prepare = NOT_CONFIGURED)
22
+ if new_prepare != NOT_CONFIGURED
23
+ @prepare = new_prepare
24
+ end
25
+ @prepare
26
+ end
29
27
 
30
28
  # @return [Symbol] This argument's name in Ruby keyword arguments
31
29
  attr_reader :keyword
@@ -41,24 +39,31 @@ module GraphQL
41
39
  # @param arg_name [Symbol]
42
40
  # @param type_expr
43
41
  # @param desc [String]
44
- # @param required [Boolean] if true, this argument is non-null; if false, this argument is nullable
42
+ # @param required [Boolean, :nullable] if true, this argument is non-null; if false, this argument is nullable. If `:nullable`, then the argument must be provided, though it may be `null`.
45
43
  # @param description [String]
46
44
  # @param default_value [Object]
47
45
  # @param as [Symbol] Override the keyword name when passed to a method
48
46
  # @param prepare [Symbol] A method to call to transform this argument's valuebefore sending it to field resolution
49
47
  # @param camelize [Boolean] if true, the name will be camelized when building the schema
50
48
  # @param from_resolver [Boolean] if true, a Resolver class defined this argument
51
- # @param method_access [Boolean] If false, don't build method access on legacy {Query::Arguments} instances.
52
49
  # @param directives [Hash{Class => Hash}]
53
50
  # @param deprecation_reason [String]
54
51
  # @param validates [Hash, nil] Options for building validators, if any should be applied
55
- def initialize(arg_name = nil, type_expr = nil, desc = nil, required:, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value: NO_DEFAULT, as: nil, from_resolver: false, camelize: true, prepare: nil, method_access: true, owner:, validates: nil, directives: nil, deprecation_reason: nil, &definition_block)
52
+ # @param replace_null_with_default [Boolean] if `true`, incoming values of `null` will be replaced with the configured `default_value`
53
+ def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value: NOT_CONFIGURED, as: nil, from_resolver: false, camelize: true, prepare: nil, owner:, validates: nil, directives: nil, deprecation_reason: nil, replace_null_with_default: false, &definition_block)
56
54
  arg_name ||= name
57
55
  @name = -(camelize ? Member::BuildType.camelize(arg_name.to_s) : arg_name.to_s)
58
56
  @type_expr = type_expr || type
59
57
  @description = desc || description
60
- @null = !required
58
+ @null = required != true
61
59
  @default_value = default_value
60
+ if replace_null_with_default
61
+ if !default_value?
62
+ raise ArgumentError, "`replace_null_with_default: true` requires a default value, please provide one with `default_value: ...`"
63
+ end
64
+ @replace_null_with_default = true
65
+ end
66
+
62
67
  @owner = owner
63
68
  @as = as
64
69
  @loads = loads
@@ -66,7 +71,6 @@ module GraphQL
66
71
  @prepare = prepare
67
72
  @ast_node = ast_node
68
73
  @from_resolver = from_resolver
69
- @method_access = method_access
70
74
  self.deprecation_reason = deprecation_reason
71
75
 
72
76
  if directives
@@ -75,7 +79,13 @@ module GraphQL
75
79
  end
76
80
  end
77
81
 
78
- self.validates(validates)
82
+ if validates && !validates.empty?
83
+ self.validates(validates)
84
+ end
85
+
86
+ if required == :nullable
87
+ self.owner.validates(required: { argument: arg_name })
88
+ end
79
89
 
80
90
  if definition_block
81
91
  if definition_block.arity == 1
@@ -86,12 +96,26 @@ module GraphQL
86
96
  end
87
97
  end
88
98
 
99
+ def inspect
100
+ "#<#{self.class} #{path}: #{type.to_type_signature}#{description ? " @description=#{description.inspect}" : ""}>"
101
+ end
102
+
103
+ # @param default_value [Object] The value to use when the client doesn't provide one
89
104
  # @return [Object] the value used when the client doesn't provide a value for this argument
90
- attr_reader :default_value
105
+ def default_value(new_default_value = NOT_CONFIGURED)
106
+ if new_default_value != NOT_CONFIGURED
107
+ @default_value = new_default_value
108
+ end
109
+ @default_value
110
+ end
91
111
 
92
112
  # @return [Boolean] True if this argument has a default value
93
113
  def default_value?
94
- @default_value != NO_DEFAULT
114
+ @default_value != NOT_CONFIGURED
115
+ end
116
+
117
+ def replace_null_with_default?
118
+ @replace_null_with_default
95
119
  end
96
120
 
97
121
  attr_writer :description
@@ -123,10 +147,6 @@ module GraphQL
123
147
  true
124
148
  end
125
149
 
126
- def accessible?(context)
127
- true
128
- end
129
-
130
150
  def authorized?(obj, value, ctx)
131
151
  authorized_as_type?(obj, value, ctx, as_type: type)
132
152
  end
@@ -147,38 +167,13 @@ module GraphQL
147
167
  end
148
168
  end
149
169
  elsif as_type.kind.input_object?
150
- as_type.arguments.each do |_name, input_obj_arg|
151
- input_obj_arg = input_obj_arg.type_class
152
- # TODO: this skips input objects whose values were alread replaced with application objects.
153
- # See: https://github.com/rmosolgo/graphql-ruby/issues/2633
154
- if value.respond_to?(:key?) && value.key?(input_obj_arg.keyword) && !input_obj_arg.authorized?(obj, value[input_obj_arg.keyword], ctx)
155
- return false
156
- end
157
- end
170
+ return as_type.authorized?(obj, value, ctx)
158
171
  end
159
172
  # None of the early-return conditions were activated,
160
173
  # so this is authorized.
161
174
  true
162
175
  end
163
176
 
164
- def to_graphql
165
- argument = GraphQL::Argument.new
166
- argument.name = @name
167
- argument.type = -> { type }
168
- argument.description = @description
169
- argument.metadata[:type_class] = self
170
- argument.as = @as
171
- argument.ast_node = ast_node
172
- argument.method_access = @method_access
173
- if NO_DEFAULT != @default_value
174
- argument.default_value = @default_value
175
- end
176
- if self.deprecation_reason
177
- argument.deprecation_reason = self.deprecation_reason
178
- end
179
- argument
180
- end
181
-
182
177
  def type=(new_type)
183
178
  validate_input_type(new_type)
184
179
  # This isn't true for LateBoundTypes, but we can assume those will
@@ -203,8 +198,8 @@ module GraphQL
203
198
 
204
199
  def statically_coercible?
205
200
  return @statically_coercible if defined?(@statically_coercible)
206
-
207
- @statically_coercible = !@prepare.is_a?(String) && !@prepare.is_a?(Symbol)
201
+ requires_parent_object = @prepare.is_a?(String) || @prepare.is_a?(Symbol) || @own_validators
202
+ @statically_coercible = !requires_parent_object
208
203
  end
209
204
 
210
205
  # Apply the {prepare} configuration to `value`, using methods from `obj`.
@@ -226,8 +221,13 @@ module GraphQL
226
221
  #
227
222
  # This will have to be called later, when the runtime object _is_ available.
228
223
  value
229
- else
224
+ elsif obj.respond_to?(@prepare)
230
225
  obj.public_send(@prepare, value)
226
+ elsif owner.respond_to?(@prepare)
227
+ owner.public_send(@prepare, value, context || obj.context)
228
+ else
229
+ raise "Invalid prepare for #{@owner.name}.name: #{@prepare.inspect}. "\
230
+ "Could not find prepare method #{@prepare} on #{obj.class} or #{owner}."
231
231
  end
232
232
  elsif @prepare.respond_to?(:call)
233
233
  @prepare.call(value, context || obj.context)
@@ -255,50 +255,104 @@ module GraphQL
255
255
  return
256
256
  end
257
257
 
258
+ if value.nil? && replace_null_with_default?
259
+ value = default_value
260
+ default_used = true
261
+ end
262
+
258
263
  loaded_value = nil
259
- coerced_value = context.schema.error_handler.with_error_handling(context) do
264
+ coerced_value = begin
260
265
  type.coerce_input(value, context)
266
+ rescue StandardError => err
267
+ context.schema.handle_or_reraise(context, err)
261
268
  end
262
269
 
263
- # TODO this should probably be inside after_lazy
264
- if loads && !from_resolver?
265
- loaded_value = if type.list?
266
- loaded_values = coerced_value.map { |val| owner.load_application_object(self, loads, val, context) }
267
- context.schema.after_any_lazies(loaded_values) { |result| result }
268
- else
269
- context.query.with_error_handling do
270
- owner.load_application_object(self, loads, coerced_value, context)
270
+ # If this isn't lazy, then the block returns eagerly and assigns the result here
271
+ # If it _is_ lazy, then we write the lazy to the hash, then update it later
272
+ argument_values[arg_key] = context.query.after_lazy(coerced_value) do |resolved_coerced_value|
273
+ owner.validate_directive_argument(self, resolved_coerced_value)
274
+ prepared_value = begin
275
+ prepare_value(parent_object, resolved_coerced_value, context: context)
276
+ rescue StandardError => err
277
+ context.schema.handle_or_reraise(context, err)
278
+ end
279
+
280
+ if loads && !from_resolver?
281
+ loaded_value = begin
282
+ load_and_authorize_value(owner, prepared_value, context)
283
+ rescue StandardError => err
284
+ context.schema.handle_or_reraise(context, err)
271
285
  end
272
286
  end
273
- end
274
287
 
275
- coerced_value = if loaded_value
276
- loaded_value
277
- else
278
- coerced_value
288
+ maybe_loaded_value = loaded_value || prepared_value
289
+ context.query.after_lazy(maybe_loaded_value) do |resolved_loaded_value|
290
+ # TODO code smell to access such a deeply-nested constant in a distant module
291
+ argument_values[arg_key] = GraphQL::Execution::Interpreter::ArgumentValue.new(
292
+ value: resolved_loaded_value,
293
+ definition: self,
294
+ default_used: default_used,
295
+ )
296
+ end
279
297
  end
298
+ end
280
299
 
281
- # If this isn't lazy, then the block returns eagerly and assigns the result here
282
- # If it _is_ lazy, then we write the lazy to the hash, then update it later
283
- argument_values[arg_key] = context.schema.after_lazy(coerced_value) do |coerced_value|
284
- owner.validate_directive_argument(self, coerced_value)
285
- prepared_value = context.schema.error_handler.with_error_handling(context) do
286
- prepare_value(parent_object, coerced_value, context: context)
300
+ def load_and_authorize_value(load_method_owner, coerced_value, context)
301
+ if coerced_value.nil?
302
+ return nil
303
+ end
304
+ arg_load_method = "load_#{keyword}"
305
+ if load_method_owner.respond_to?(arg_load_method)
306
+ custom_loaded_value = if load_method_owner.is_a?(Class)
307
+ load_method_owner.public_send(arg_load_method, coerced_value, context)
308
+ else
309
+ load_method_owner.public_send(arg_load_method, coerced_value)
287
310
  end
288
-
289
- # TODO code smell to access such a deeply-nested constant in a distant module
290
- argument_values[arg_key] = GraphQL::Execution::Interpreter::ArgumentValue.new(
291
- value: prepared_value,
292
- definition: self,
293
- default_used: default_used,
294
- )
311
+ context.query.after_lazy(custom_loaded_value) do |custom_value|
312
+ if loads
313
+ if type.list?
314
+ loaded_values = custom_value.each_with_index.map { |custom_val, idx|
315
+ id = coerced_value[idx]
316
+ load_method_owner.authorize_application_object(self, id, context, custom_val)
317
+ }
318
+ context.schema.after_any_lazies(loaded_values, &:itself)
319
+ else
320
+ load_method_owner.authorize_application_object(self, coerced_value, context, custom_loaded_value)
321
+ end
322
+ else
323
+ custom_value
324
+ end
325
+ end
326
+ elsif loads
327
+ if type.list?
328
+ loaded_values = coerced_value.map { |val| load_method_owner.load_and_authorize_application_object(self, val, context) }
329
+ context.schema.after_any_lazies(loaded_values, &:itself)
330
+ else
331
+ load_method_owner.load_and_authorize_application_object(self, coerced_value, context)
332
+ end
333
+ else
334
+ coerced_value
295
335
  end
296
336
  end
297
337
 
298
338
  # @api private
299
339
  def validate_default_value
300
340
  coerced_default_value = begin
301
- type.coerce_isolated_result(default_value) unless default_value.nil?
341
+ # This is weird, but we should accept single-item default values for list-type arguments.
342
+ # If we used `coerce_isolated_input` below, it would do this for us, but it's not really
343
+ # the right thing here because we expect default values in application format (Ruby values)
344
+ # not GraphQL format (scalar values).
345
+ #
346
+ # But I don't think Schema::List#coerce_result should apply wrapping to single-item lists.
347
+ prepped_default_value = if default_value.nil?
348
+ nil
349
+ elsif (type.kind.list? || (type.kind.non_null? && type.of_type.list?)) && !default_value.respond_to?(:map)
350
+ [default_value]
351
+ else
352
+ default_value
353
+ end
354
+
355
+ type.coerce_isolated_result(prepped_default_value) unless prepped_default_value.nil?
302
356
  rescue GraphQL::Schema::Enum::UnresolvedValueError
303
357
  # It raises this, which is helpful at runtime, but not here...
304
358
  default_value
@@ -1,18 +1,16 @@
1
1
  # frozen_string_literal: true
2
-
3
- require 'graphql/schema/base_64_bp'
4
-
2
+ require "base64"
5
3
  module GraphQL
6
4
  class Schema
7
5
  # @api private
8
6
  module Base64Encoder
9
7
  def self.encode(unencoded_text, nonce: false)
10
- Base64Bp.urlsafe_encode64(unencoded_text, padding: false)
8
+ Base64.urlsafe_encode64(unencoded_text, padding: false)
11
9
  end
12
10
 
13
11
  def self.decode(encoded_text, nonce: false)
14
12
  # urlsafe_decode64 is for forward compatibility
15
- Base64Bp.urlsafe_decode64(encoded_text)
13
+ Base64.urlsafe_decode64(encoded_text)
16
14
  rescue ArgumentError
17
15
  raise GraphQL::ExecutionError, "Invalid input: #{encoded_text.inspect}"
18
16
  end
@@ -3,32 +3,28 @@ require "graphql/schema/build_from_definition/resolve_map"
3
3
 
4
4
  module GraphQL
5
5
  class Schema
6
- # TODO Populate `.directive(...)` from here
7
6
  module BuildFromDefinition
8
- if !String.method_defined?(:-@)
9
- using GraphQL::StringDedupBackport
10
- end
11
-
12
7
  class << self
13
8
  # @see {Schema.from_definition}
14
- def from_definition(definition_string, parser: GraphQL.default_parser, **kwargs)
15
- from_document(parser.parse(definition_string), **kwargs)
9
+ def from_definition(schema_superclass, definition_string, parser: GraphQL.default_parser, **kwargs)
10
+ from_document(schema_superclass, parser.parse(definition_string), **kwargs)
16
11
  end
17
12
 
18
- def from_definition_path(definition_path, parser: GraphQL.default_parser, **kwargs)
19
- from_document(parser.parse_file(definition_path), **kwargs)
13
+ def from_definition_path(schema_superclass, definition_path, parser: GraphQL.default_parser, **kwargs)
14
+ from_document(schema_superclass, parser.parse_file(definition_path), **kwargs)
20
15
  end
21
16
 
22
- def from_document(document, default_resolve:, using: {}, relay: false)
23
- Builder.build(document, default_resolve: default_resolve || {}, relay: relay, using: using)
17
+ def from_document(schema_superclass, document, default_resolve:, using: {}, relay: false)
18
+ Builder.build(schema_superclass, document, default_resolve: default_resolve || {}, relay: relay, using: using)
24
19
  end
25
20
  end
26
21
 
27
22
  # @api private
28
23
  module Builder
24
+ include GraphQL::EmptyObjects
29
25
  extend self
30
26
 
31
- def build(document, default_resolve:, using: {}, relay:)
27
+ def build(schema_superclass, document, default_resolve:, using: {}, relay:)
32
28
  raise InvalidDocumentError.new('Must provide a document ast.') if !document || !document.is_a?(GraphQL::Language::Nodes::Document)
33
29
 
34
30
  if default_resolve.is_a?(Hash)
@@ -41,34 +37,43 @@ module GraphQL
41
37
  end
42
38
  schema_definition = schema_defns.first
43
39
  types = {}
44
- directives = {}
40
+ directives = schema_superclass.directives.dup
45
41
  type_resolver = build_resolve_type(types, directives, ->(type_name) { types[type_name] ||= Schema::LateBoundType.new(type_name)})
46
42
  # Make a different type resolver because we need to coerce directive arguments
47
43
  # _while_ building the schema.
48
44
  # It will dig for a type if it encounters a custom type. This could be a problem if there are cycles.
49
45
  directive_type_resolver = nil
50
- directive_type_resolver = build_resolve_type(GraphQL::Schema::BUILT_IN_TYPES, directives, ->(type_name) {
46
+ directive_type_resolver = build_resolve_type(types, directives, ->(type_name) {
51
47
  types[type_name] ||= begin
52
48
  defn = document.definitions.find { |d| d.respond_to?(:name) && d.name == type_name }
53
- build_definition_from_node(defn, directive_type_resolver, default_resolve)
49
+ if defn
50
+ build_definition_from_node(defn, directive_type_resolver, default_resolve)
51
+ elsif (built_in_defn = GraphQL::Schema::BUILT_IN_TYPES[type_name])
52
+ built_in_defn
53
+ else
54
+ raise "No definition for #{type_name.inspect} found in schema document or built-in types. Add a definition for it or remove it."
55
+ end
54
56
  end
55
57
  })
56
58
 
59
+ directives.merge!(GraphQL::Schema.default_directives)
57
60
  document.definitions.each do |definition|
58
61
  if definition.is_a?(GraphQL::Language::Nodes::DirectiveDefinition)
59
62
  directives[definition.name] = build_directive(definition, directive_type_resolver)
60
63
  end
61
64
  end
62
65
 
63
- directives = GraphQL::Schema.default_directives.merge(directives)
64
-
65
66
  # In case any directives referenced built-in types for their arguments:
66
67
  replace_late_bound_types_with_built_in(types)
67
68
 
69
+ schema_extensions = nil
68
70
  document.definitions.each do |definition|
69
71
  case definition
70
72
  when GraphQL::Language::Nodes::SchemaDefinition, GraphQL::Language::Nodes::DirectiveDefinition
71
73
  nil # already handled
74
+ when GraphQL::Language::Nodes::SchemaExtension
75
+ schema_extensions ||= []
76
+ schema_extensions << definition
72
77
  else
73
78
  # It's possible that this was already loaded by the directives
74
79
  prev_type = types[definition.name]
@@ -95,6 +100,16 @@ module GraphQL
95
100
  raise InvalidDocumentError.new("Specified subscription type \"#{schema_definition.subscription}\" not found in document.") unless types[schema_definition.subscription]
96
101
  subscription_root_type = types[schema_definition.subscription]
97
102
  end
103
+
104
+ if schema_definition.query.nil? &&
105
+ schema_definition.mutation.nil? &&
106
+ schema_definition.subscription.nil?
107
+ # This schema may have been given with directives only,
108
+ # check for defaults:
109
+ query_root_type = types['Query']
110
+ mutation_root_type = types['Mutation']
111
+ subscription_root_type = types['Subscription']
112
+ end
98
113
  else
99
114
  query_root_type = types['Query']
100
115
  mutation_root_type = types['Mutation']
@@ -103,7 +118,9 @@ module GraphQL
103
118
 
104
119
  raise InvalidDocumentError.new('Must provide schema definition with query type or a type named Query.') unless query_root_type
105
120
 
106
- Class.new(GraphQL::Schema) do
121
+ builder = self
122
+
123
+ schema_class = Class.new(schema_superclass) do
107
124
  begin
108
125
  # Add these first so that there's some chance of resolving late-bound types
109
126
  orphan_types types.values
@@ -130,6 +147,7 @@ module GraphQL
130
147
 
131
148
  if schema_definition
132
149
  ast_node(schema_definition)
150
+ builder.build_directives(self, schema_definition, type_resolver)
133
151
  end
134
152
 
135
153
  using.each do |plugin, options|
@@ -157,6 +175,14 @@ module GraphQL
157
175
  child_class.definition_default_resolve = self.definition_default_resolve
158
176
  end
159
177
  end
178
+
179
+ if schema_extensions
180
+ schema_extensions.each do |ext|
181
+ build_directives(schema_class, ext, type_resolver)
182
+ end
183
+ end
184
+
185
+ schema_class
160
186
  end
161
187
 
162
188
  NullResolveType = ->(type, obj, ctx) {
@@ -196,13 +222,18 @@ module GraphQL
196
222
 
197
223
  def build_directives(definition, ast_node, type_resolver)
198
224
  dirs = prepare_directives(ast_node, type_resolver)
199
- dirs.each do |dir_class, options|
200
- definition.directive(dir_class, **options)
225
+ dirs.each do |(dir_class, options)|
226
+ if definition.respond_to?(:schema_directive)
227
+ # it's a schema
228
+ definition.schema_directive(dir_class, **options)
229
+ else
230
+ definition.directive(dir_class, **options)
231
+ end
201
232
  end
202
233
  end
203
234
 
204
235
  def prepare_directives(ast_node, type_resolver)
205
- dirs = {}
236
+ dirs = []
206
237
  ast_node.directives.each do |dir_node|
207
238
  if dir_node.name == "deprecated"
208
239
  # This is handled using `deprecation_reason`
@@ -210,10 +241,10 @@ module GraphQL
210
241
  else
211
242
  dir_class = type_resolver.call(dir_node.name)
212
243
  if dir_class.nil?
213
- raise ArgumentError, "No definition for @#{dir_node.name} on #{ast_node.name} at #{ast_node.line}:#{ast_node.col}"
244
+ raise ArgumentError, "No definition for @#{dir_node.name} #{ast_node.respond_to?(:name) ? "on #{ast_node.name} " : ""}at #{ast_node.line}:#{ast_node.col}"
214
245
  end
215
246
  options = args_to_kwargs(dir_class, dir_node)
216
- dirs[dir_class] = options
247
+ dirs << [dir_class, options]
217
248
  end
218
249
  end
219
250
  dirs
@@ -344,8 +375,6 @@ module GraphQL
344
375
  end
345
376
  end
346
377
 
347
- NO_DEFAULT_VALUE = {}.freeze
348
-
349
378
  def build_arguments(type_class, arguments, type_resolver)
350
379
  builder = self
351
380
 
@@ -353,7 +382,7 @@ module GraphQL
353
382
  default_value_kwargs = if !argument_defn.default_value.nil?
354
383
  { default_value: builder.build_default_value(argument_defn.default_value) }
355
384
  else
356
- NO_DEFAULT_VALUE
385
+ EMPTY_HASH
357
386
  end
358
387
 
359
388
  type_class.argument(
@@ -364,7 +393,6 @@ module GraphQL
364
393
  deprecation_reason: builder.build_deprecation_reason(argument_defn.directives),
365
394
  ast_node: argument_defn,
366
395
  camelize: false,
367
- method_access: false,
368
396
  directives: prepare_directives(argument_defn, type_resolver),
369
397
  **default_value_kwargs
370
398
  )
@@ -376,6 +404,7 @@ module GraphQL
376
404
  Class.new(GraphQL::Schema::Directive) do
377
405
  graphql_name(directive_definition.name)
378
406
  description(directive_definition.description)
407
+ repeatable(directive_definition.repeatable)
379
408
  locations(*directive_definition.locations.map { |location| location.name.to_sym })
380
409
  ast_node(directive_definition)
381
410
  builder.build_arguments(self, directive_definition.arguments, type_resolver)
@@ -388,6 +417,10 @@ module GraphQL
388
417
  include GraphQL::Schema::Interface
389
418
  graphql_name(interface_type_definition.name)
390
419
  description(interface_type_definition.description)
420
+ interface_type_definition.interfaces.each do |interface_name|
421
+ interface_defn = type_resolver.call(interface_name)
422
+ implements(interface_defn)
423
+ end
391
424
  ast_node(interface_type_definition)
392
425
  builder.build_directives(self, interface_type_definition, type_resolver)
393
426
 
@@ -399,14 +432,12 @@ module GraphQL
399
432
  builder = self
400
433
 
401
434
  field_definitions.each do |field_definition|
402
- type_name = resolve_type_name(field_definition.type)
403
435
  resolve_method_name = -"resolve_field_#{field_definition.name}"
404
436
  schema_field_defn = owner.field(
405
437
  field_definition.name,
406
438
  description: field_definition.description,
407
439
  type: type_resolver.call(field_definition.type),
408
440
  null: true,
409
- connection: type_name.end_with?("Connection"),
410
441
  connection_extension: nil,
411
442
  deprecation_reason: build_deprecation_reason(field_definition.directives),
412
443
  ast_node: field_definition,
@@ -454,15 +485,6 @@ module GraphQL
454
485
  }
455
486
  resolve_type_proc
456
487
  end
457
-
458
- def resolve_type_name(type)
459
- case type
460
- when GraphQL::Language::Nodes::TypeName
461
- return type.name
462
- else
463
- resolve_type_name(type.of_type)
464
- end
465
- end
466
488
  end
467
489
 
468
490
  private_constant :Builder
@@ -42,7 +42,7 @@ module GraphQL
42
42
  GraphQL::Schema::Directive::INLINE_FRAGMENT
43
43
  )
44
44
 
45
- argument :flag, String, required: true,
45
+ argument :flag, String,
46
46
  description: "The name of the feature to check before continuing"
47
47
 
48
48
  # Implement the Directive API
@@ -35,7 +35,7 @@ module GraphQL
35
35
  GraphQL::Schema::Directive::INPUT_FIELD_DEFINITION,
36
36
  )
37
37
 
38
- argument :by, [String], "Flags to check for this schema member", required: true
38
+ argument :by, [String], "Flags to check for this schema member"
39
39
 
40
40
  module VisibleByFlag
41
41
  def self.included(schema_class)
@@ -44,7 +44,7 @@ module GraphQL
44
44
 
45
45
  def visible?(context)
46
46
  if dir = self.directives.find { |d| d.is_a?(Flagged) }
47
- relevant_flags = (f = context[:flags]) && dir.arguments[:by] & f
47
+ relevant_flags = (f = context[:flags]) && dir.arguments[:by] & f # rubocop:disable Development/ContextIsPassedCop -- definition-related
48
48
  relevant_flags && relevant_flags.any? && super
49
49
  else
50
50
  super
@@ -11,7 +11,7 @@ module GraphQL
11
11
  GraphQL::Schema::Directive::INLINE_FRAGMENT
12
12
  )
13
13
 
14
- argument :if, Boolean, required: true,
14
+ argument :if, Boolean,
15
15
  description: "Included when true."
16
16
 
17
17
  default_directive true
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ class Schema
4
+ class Directive < GraphQL::Schema::Member
5
+ class OneOf < GraphQL::Schema::Directive
6
+ description "Requires that exactly one field must be supplied and that field must not be `null`."
7
+ locations(GraphQL::Schema::Directive::INPUT_OBJECT)
8
+ default_directive true
9
+
10
+ def initialize(...)
11
+ super
12
+
13
+ owner.extend(IsOneOf)
14
+ end
15
+
16
+ module IsOneOf
17
+ def one_of?
18
+ true
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -11,7 +11,7 @@ module GraphQL
11
11
  GraphQL::Schema::Directive::INLINE_FRAGMENT
12
12
  )
13
13
 
14
- argument :if, Boolean, required: true,
14
+ argument :if, Boolean,
15
15
  description: "Skipped when true."
16
16
 
17
17
  default_directive true