graphql 1.9.21 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (397) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/core.rb +21 -10
  3. data/lib/generators/graphql/enum_generator.rb +4 -10
  4. data/lib/generators/graphql/field_extractor.rb +31 -0
  5. data/lib/generators/graphql/input_generator.rb +50 -0
  6. data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
  7. data/lib/generators/graphql/{templates → install/templates}/base_mutation.erb +2 -0
  8. data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +2 -0
  9. data/lib/generators/graphql/install_generator.rb +44 -7
  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 +63 -0
  19. data/lib/generators/graphql/relay_generator.rb +21 -0
  20. data/lib/generators/graphql/scalar_generator.rb +4 -2
  21. data/lib/generators/graphql/templates/base_argument.erb +2 -0
  22. data/lib/generators/graphql/templates/base_connection.erb +8 -0
  23. data/lib/generators/graphql/templates/base_edge.erb +8 -0
  24. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  25. data/lib/generators/graphql/templates/base_field.erb +2 -0
  26. data/lib/generators/graphql/templates/base_input_object.erb +2 -0
  27. data/lib/generators/graphql/templates/base_interface.erb +2 -0
  28. data/lib/generators/graphql/templates/base_object.erb +2 -0
  29. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  30. data/lib/generators/graphql/templates/base_union.erb +2 -0
  31. data/lib/generators/graphql/templates/enum.erb +7 -1
  32. data/lib/generators/graphql/templates/graphql_controller.erb +16 -12
  33. data/lib/generators/graphql/templates/input.erb +9 -0
  34. data/lib/generators/graphql/templates/interface.erb +6 -2
  35. data/lib/generators/graphql/templates/loader.erb +2 -0
  36. data/lib/generators/graphql/templates/mutation.erb +3 -1
  37. data/lib/generators/graphql/templates/mutation_create.erb +20 -0
  38. data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
  39. data/lib/generators/graphql/templates/mutation_update.erb +21 -0
  40. data/lib/generators/graphql/templates/node_type.erb +9 -0
  41. data/lib/generators/graphql/templates/object.erb +7 -3
  42. data/lib/generators/graphql/templates/query_type.erb +3 -3
  43. data/lib/generators/graphql/templates/scalar.erb +5 -1
  44. data/lib/generators/graphql/templates/schema.erb +22 -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/field_usage.rb +29 -2
  49. data/lib/graphql/analysis/ast/query_complexity.rb +175 -68
  50. data/lib/graphql/analysis/ast/query_depth.rb +0 -1
  51. data/lib/graphql/analysis/ast/visitor.rb +17 -8
  52. data/lib/graphql/analysis/ast.rb +14 -14
  53. data/lib/graphql/analysis.rb +0 -7
  54. data/lib/graphql/backtrace/inspect_result.rb +0 -1
  55. data/lib/graphql/backtrace/table.rb +37 -16
  56. data/lib/graphql/backtrace/traced_error.rb +0 -1
  57. data/lib/graphql/backtrace/tracer.rb +39 -9
  58. data/lib/graphql/backtrace.rb +20 -17
  59. data/lib/graphql/dataloader/null_dataloader.rb +22 -0
  60. data/lib/graphql/dataloader/request.rb +19 -0
  61. data/lib/graphql/dataloader/request_all.rb +19 -0
  62. data/lib/graphql/dataloader/source.rb +155 -0
  63. data/lib/graphql/dataloader.rb +308 -0
  64. data/lib/graphql/date_encoding_error.rb +16 -0
  65. data/lib/graphql/deprecation.rb +9 -0
  66. data/lib/graphql/dig.rb +1 -1
  67. data/lib/graphql/execution/directive_checks.rb +2 -2
  68. data/lib/graphql/execution/errors.rb +108 -14
  69. data/lib/graphql/execution/instrumentation.rb +1 -1
  70. data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
  71. data/lib/graphql/execution/interpreter/arguments.rb +88 -0
  72. data/lib/graphql/execution/interpreter/arguments_cache.rb +105 -0
  73. data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
  74. data/lib/graphql/execution/interpreter/resolve.rb +37 -25
  75. data/lib/graphql/execution/interpreter/runtime.rb +715 -387
  76. data/lib/graphql/execution/interpreter.rb +32 -31
  77. data/lib/graphql/execution/lazy/lazy_method_map.rb +4 -0
  78. data/lib/graphql/execution/lazy.rb +5 -1
  79. data/lib/graphql/execution/lookahead.rb +32 -114
  80. data/lib/graphql/execution/multiplex.rb +60 -92
  81. data/lib/graphql/execution.rb +11 -3
  82. data/lib/graphql/filter.rb +1 -1
  83. data/lib/graphql/integer_decoding_error.rb +17 -0
  84. data/lib/graphql/integer_encoding_error.rb +18 -2
  85. data/lib/graphql/introspection/base_object.rb +2 -5
  86. data/lib/graphql/introspection/directive_location_enum.rb +2 -2
  87. data/lib/graphql/introspection/directive_type.rb +11 -5
  88. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  89. data/lib/graphql/introspection/entry_points.rb +5 -18
  90. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  91. data/lib/graphql/introspection/field_type.rb +9 -5
  92. data/lib/graphql/introspection/input_value_type.rb +41 -11
  93. data/lib/graphql/introspection/introspection_query.rb +6 -92
  94. data/lib/graphql/introspection/schema_type.rb +10 -10
  95. data/lib/graphql/introspection/type_type.rb +27 -17
  96. data/lib/graphql/introspection.rb +99 -0
  97. data/lib/graphql/invalid_null_error.rb +18 -0
  98. data/lib/graphql/language/block_string.rb +20 -5
  99. data/lib/graphql/language/cache.rb +37 -0
  100. data/lib/graphql/language/definition_slice.rb +21 -10
  101. data/lib/graphql/language/document_from_schema_definition.rb +99 -63
  102. data/lib/graphql/language/lexer.rb +53 -27
  103. data/lib/graphql/language/lexer.rl +5 -3
  104. data/lib/graphql/language/nodes.rb +64 -93
  105. data/lib/graphql/language/parser.rb +929 -896
  106. data/lib/graphql/language/parser.y +125 -102
  107. data/lib/graphql/language/printer.rb +11 -2
  108. data/lib/graphql/language/sanitized_printer.rb +222 -0
  109. data/lib/graphql/language/token.rb +0 -4
  110. data/lib/graphql/language/visitor.rb +2 -2
  111. data/lib/graphql/language.rb +3 -1
  112. data/lib/graphql/name_validator.rb +2 -7
  113. data/lib/graphql/pagination/active_record_relation_connection.rb +85 -0
  114. data/lib/graphql/pagination/array_connection.rb +77 -0
  115. data/lib/graphql/pagination/connection.rb +226 -0
  116. data/lib/graphql/pagination/connections.rb +134 -0
  117. data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
  118. data/lib/graphql/pagination/relation_connection.rb +226 -0
  119. data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
  120. data/lib/graphql/pagination.rb +6 -0
  121. data/lib/graphql/parse_error.rb +0 -1
  122. data/lib/graphql/query/context.rb +51 -190
  123. data/lib/graphql/query/fingerprint.rb +26 -0
  124. data/lib/graphql/query/input_validation_result.rb +23 -6
  125. data/lib/graphql/query/literal_input.rb +26 -11
  126. data/lib/graphql/query/null_context.rb +24 -8
  127. data/lib/graphql/query/validation_pipeline.rb +12 -38
  128. data/lib/graphql/query/variable_validation_error.rb +2 -2
  129. data/lib/graphql/query/variables.rb +26 -9
  130. data/lib/graphql/query.rb +62 -32
  131. data/lib/graphql/railtie.rb +6 -102
  132. data/lib/graphql/rake_task/validate.rb +3 -0
  133. data/lib/graphql/rake_task.rb +12 -9
  134. data/lib/graphql/relay/range_add.rb +23 -9
  135. data/lib/graphql/relay.rb +0 -15
  136. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  137. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  138. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  139. data/lib/graphql/rubocop.rb +4 -0
  140. data/lib/graphql/schema/addition.rb +240 -0
  141. data/lib/graphql/schema/argument.rb +262 -28
  142. data/lib/graphql/schema/base_64_encoder.rb +2 -0
  143. data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
  144. data/lib/graphql/schema/build_from_definition/resolve_map.rb +13 -5
  145. data/lib/graphql/schema/build_from_definition.rb +319 -220
  146. data/lib/graphql/schema/built_in_types.rb +5 -5
  147. data/lib/graphql/schema/directive/deprecated.rb +18 -0
  148. data/lib/graphql/schema/directive/feature.rb +1 -1
  149. data/lib/graphql/schema/directive/flagged.rb +57 -0
  150. data/lib/graphql/schema/directive/include.rb +2 -2
  151. data/lib/graphql/schema/directive/skip.rb +2 -2
  152. data/lib/graphql/schema/directive/transform.rb +14 -2
  153. data/lib/graphql/schema/directive.rb +117 -14
  154. data/lib/graphql/schema/enum.rb +115 -22
  155. data/lib/graphql/schema/enum_value.rb +16 -21
  156. data/lib/graphql/schema/field/connection_extension.rb +46 -20
  157. data/lib/graphql/schema/field/scope_extension.rb +1 -1
  158. data/lib/graphql/schema/field.rb +376 -291
  159. data/lib/graphql/schema/field_extension.rb +89 -2
  160. data/lib/graphql/schema/find_inherited_value.rb +17 -1
  161. data/lib/graphql/schema/finder.rb +16 -14
  162. data/lib/graphql/schema/input_object.rb +147 -60
  163. data/lib/graphql/schema/interface.rb +28 -43
  164. data/lib/graphql/schema/introspection_system.rb +101 -38
  165. data/lib/graphql/schema/late_bound_type.rb +3 -2
  166. data/lib/graphql/schema/list.rb +46 -3
  167. data/lib/graphql/schema/loader.rb +144 -102
  168. data/lib/graphql/schema/member/base_dsl_methods.rb +33 -32
  169. data/lib/graphql/schema/member/build_type.rb +23 -14
  170. data/lib/graphql/schema/member/has_arguments.rb +212 -23
  171. data/lib/graphql/schema/member/has_ast_node.rb +20 -0
  172. data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
  173. data/lib/graphql/schema/member/has_directives.rb +98 -0
  174. data/lib/graphql/schema/member/has_fields.rb +99 -34
  175. data/lib/graphql/schema/member/has_interfaces.rb +88 -0
  176. data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
  177. data/lib/graphql/schema/member/has_validators.rb +31 -0
  178. data/lib/graphql/schema/member/type_system_helpers.rb +3 -3
  179. data/lib/graphql/schema/member/validates_input.rb +33 -0
  180. data/lib/graphql/schema/member.rb +11 -6
  181. data/lib/graphql/schema/mutation.rb +4 -9
  182. data/lib/graphql/schema/non_null.rb +34 -4
  183. data/lib/graphql/schema/object.rb +38 -65
  184. data/lib/graphql/schema/printer.rb +16 -35
  185. data/lib/graphql/schema/relay_classic_mutation.rb +57 -32
  186. data/lib/graphql/schema/resolver/has_payload_type.rb +34 -4
  187. data/lib/graphql/schema/resolver.rb +133 -79
  188. data/lib/graphql/schema/scalar.rb +40 -15
  189. data/lib/graphql/schema/subscription.rb +57 -21
  190. data/lib/graphql/schema/timeout.rb +29 -15
  191. data/lib/graphql/schema/type_expression.rb +21 -13
  192. data/lib/graphql/schema/type_membership.rb +19 -5
  193. data/lib/graphql/schema/union.rb +39 -14
  194. data/lib/graphql/schema/unique_within_type.rb +1 -2
  195. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  196. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  197. data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
  198. data/lib/graphql/schema/validator/format_validator.rb +48 -0
  199. data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
  200. data/lib/graphql/schema/validator/length_validator.rb +59 -0
  201. data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
  202. data/lib/graphql/schema/validator/required_validator.rb +82 -0
  203. data/lib/graphql/schema/validator.rb +171 -0
  204. data/lib/graphql/schema/warden.rb +182 -32
  205. data/lib/graphql/schema/wrapper.rb +0 -5
  206. data/lib/graphql/schema.rb +687 -891
  207. data/lib/graphql/static_validation/all_rules.rb +2 -0
  208. data/lib/graphql/static_validation/base_visitor.rb +21 -31
  209. data/lib/graphql/static_validation/definition_dependencies.rb +0 -1
  210. data/lib/graphql/static_validation/error.rb +3 -1
  211. data/lib/graphql/static_validation/literal_validator.rb +51 -26
  212. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +45 -83
  213. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
  214. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +35 -26
  215. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
  216. data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
  217. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +14 -14
  218. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +4 -4
  219. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -5
  220. data/lib/graphql/static_validation/rules/fields_will_merge.rb +94 -51
  221. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
  222. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  223. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
  224. data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
  225. data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
  226. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  227. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  228. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -2
  229. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +9 -10
  230. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
  231. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +12 -13
  232. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +19 -14
  233. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  234. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +5 -3
  235. data/lib/graphql/static_validation/type_stack.rb +2 -2
  236. data/lib/graphql/static_validation/validation_context.rb +13 -3
  237. data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
  238. data/lib/graphql/static_validation/validator.rb +31 -19
  239. data/lib/graphql/static_validation.rb +1 -2
  240. data/lib/graphql/string_encoding_error.rb +13 -3
  241. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +123 -22
  242. data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
  243. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +58 -0
  244. data/lib/graphql/subscriptions/event.rb +85 -31
  245. data/lib/graphql/subscriptions/instrumentation.rb +0 -47
  246. data/lib/graphql/subscriptions/serialize.rb +53 -6
  247. data/lib/graphql/subscriptions.rb +111 -52
  248. data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -17
  249. data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
  250. data/lib/graphql/tracing/appsignal_tracing.rb +23 -0
  251. data/lib/graphql/tracing/data_dog_tracing.rb +14 -1
  252. data/lib/graphql/tracing/new_relic_tracing.rb +9 -12
  253. data/lib/graphql/tracing/notifications_tracing.rb +59 -0
  254. data/lib/graphql/tracing/platform_tracing.rb +57 -29
  255. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
  256. data/lib/graphql/tracing/prometheus_tracing.rb +8 -0
  257. data/lib/graphql/tracing/scout_tracing.rb +19 -0
  258. data/lib/graphql/tracing/statsd_tracing.rb +42 -0
  259. data/lib/graphql/tracing.rb +15 -36
  260. data/lib/graphql/types/big_int.rb +5 -1
  261. data/lib/graphql/types/int.rb +10 -3
  262. data/lib/graphql/types/iso_8601_date.rb +16 -8
  263. data/lib/graphql/types/iso_8601_date_time.rb +32 -10
  264. data/lib/graphql/types/relay/base_connection.rb +6 -88
  265. data/lib/graphql/types/relay/base_edge.rb +2 -34
  266. data/lib/graphql/types/relay/connection_behaviors.rb +170 -0
  267. data/lib/graphql/types/relay/default_relay.rb +21 -0
  268. data/lib/graphql/types/relay/edge_behaviors.rb +64 -0
  269. data/lib/graphql/types/relay/has_node_field.rb +41 -0
  270. data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
  271. data/lib/graphql/types/relay/node.rb +2 -4
  272. data/lib/graphql/types/relay/node_behaviors.rb +19 -0
  273. data/lib/graphql/types/relay/page_info.rb +2 -14
  274. data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
  275. data/lib/graphql/types/relay.rb +11 -5
  276. data/lib/graphql/types/string.rb +8 -2
  277. data/lib/graphql/unauthorized_error.rb +2 -2
  278. data/lib/graphql/unresolved_type_error.rb +2 -2
  279. data/lib/graphql/version.rb +1 -1
  280. data/lib/graphql.rb +41 -58
  281. data/readme.md +3 -6
  282. metadata +97 -231
  283. data/lib/graphql/analysis/analyze_query.rb +0 -91
  284. data/lib/graphql/analysis/field_usage.rb +0 -45
  285. data/lib/graphql/analysis/max_query_complexity.rb +0 -26
  286. data/lib/graphql/analysis/max_query_depth.rb +0 -26
  287. data/lib/graphql/analysis/query_complexity.rb +0 -88
  288. data/lib/graphql/analysis/query_depth.rb +0 -43
  289. data/lib/graphql/analysis/reducer_state.rb +0 -48
  290. data/lib/graphql/argument.rb +0 -159
  291. data/lib/graphql/authorization.rb +0 -82
  292. data/lib/graphql/backwards_compatibility.rb +0 -60
  293. data/lib/graphql/base_type.rb +0 -226
  294. data/lib/graphql/boolean_type.rb +0 -2
  295. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  296. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  297. data/lib/graphql/compatibility/execution_specification.rb +0 -435
  298. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  299. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -213
  300. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -91
  301. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  302. data/lib/graphql/compatibility/query_parser_specification.rb +0 -264
  303. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -680
  304. data/lib/graphql/compatibility.rb +0 -5
  305. data/lib/graphql/define/assign_argument.rb +0 -12
  306. data/lib/graphql/define/assign_connection.rb +0 -13
  307. data/lib/graphql/define/assign_enum_value.rb +0 -18
  308. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  309. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  310. data/lib/graphql/define/assign_object_field.rb +0 -42
  311. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  312. data/lib/graphql/define/instance_definable.rb +0 -311
  313. data/lib/graphql/define/no_definition_error.rb +0 -7
  314. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  315. data/lib/graphql/define/type_definer.rb +0 -31
  316. data/lib/graphql/define.rb +0 -31
  317. data/lib/graphql/deprecated_dsl.rb +0 -42
  318. data/lib/graphql/directive/deprecated_directive.rb +0 -13
  319. data/lib/graphql/directive/include_directive.rb +0 -2
  320. data/lib/graphql/directive/skip_directive.rb +0 -2
  321. data/lib/graphql/directive.rb +0 -104
  322. data/lib/graphql/enum_type.rb +0 -193
  323. data/lib/graphql/execution/execute.rb +0 -326
  324. data/lib/graphql/execution/flatten.rb +0 -40
  325. data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
  326. data/lib/graphql/execution/typecast.rb +0 -50
  327. data/lib/graphql/field/resolve.rb +0 -59
  328. data/lib/graphql/field.rb +0 -330
  329. data/lib/graphql/float_type.rb +0 -2
  330. data/lib/graphql/function.rb +0 -153
  331. data/lib/graphql/id_type.rb +0 -2
  332. data/lib/graphql/input_object_type.rb +0 -154
  333. data/lib/graphql/int_type.rb +0 -2
  334. data/lib/graphql/interface_type.rb +0 -86
  335. data/lib/graphql/internal_representation/document.rb +0 -27
  336. data/lib/graphql/internal_representation/node.rb +0 -206
  337. data/lib/graphql/internal_representation/print.rb +0 -51
  338. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  339. data/lib/graphql/internal_representation/scope.rb +0 -88
  340. data/lib/graphql/internal_representation/visit.rb +0 -36
  341. data/lib/graphql/internal_representation.rb +0 -7
  342. data/lib/graphql/list_type.rb +0 -80
  343. data/lib/graphql/literal_validation_error.rb +0 -6
  344. data/lib/graphql/non_null_type.rb +0 -81
  345. data/lib/graphql/object_type.rb +0 -141
  346. data/lib/graphql/query/arguments.rb +0 -187
  347. data/lib/graphql/query/arguments_cache.rb +0 -25
  348. data/lib/graphql/query/executor.rb +0 -53
  349. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  350. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  351. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  352. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  353. data/lib/graphql/query/serial_execution.rb +0 -39
  354. data/lib/graphql/relay/array_connection.rb +0 -85
  355. data/lib/graphql/relay/base_connection.rb +0 -172
  356. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  357. data/lib/graphql/relay/connection_resolve.rb +0 -43
  358. data/lib/graphql/relay/connection_type.rb +0 -40
  359. data/lib/graphql/relay/edge.rb +0 -27
  360. data/lib/graphql/relay/edge_type.rb +0 -18
  361. data/lib/graphql/relay/edges_instrumentation.rb +0 -40
  362. data/lib/graphql/relay/global_id_resolve.rb +0 -18
  363. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  364. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  365. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  366. data/lib/graphql/relay/mutation/result.rb +0 -38
  367. data/lib/graphql/relay/mutation.rb +0 -190
  368. data/lib/graphql/relay/node.rb +0 -36
  369. data/lib/graphql/relay/page_info.rb +0 -7
  370. data/lib/graphql/relay/relation_connection.rb +0 -190
  371. data/lib/graphql/relay/type_extensions.rb +0 -30
  372. data/lib/graphql/scalar_type.rb +0 -133
  373. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  374. data/lib/graphql/schema/default_parse_error.rb +0 -10
  375. data/lib/graphql/schema/default_type_error.rb +0 -15
  376. data/lib/graphql/schema/member/accepts_definition.rb +0 -152
  377. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -26
  378. data/lib/graphql/schema/member/instrumentation.rb +0 -132
  379. data/lib/graphql/schema/middleware_chain.rb +0 -82
  380. data/lib/graphql/schema/possible_types.rb +0 -39
  381. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  382. data/lib/graphql/schema/timeout_middleware.rb +0 -86
  383. data/lib/graphql/schema/traversal.rb +0 -228
  384. data/lib/graphql/schema/validation.rb +0 -303
  385. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  386. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  387. data/lib/graphql/string_type.rb +0 -2
  388. data/lib/graphql/subscriptions/subscription_root.rb +0 -74
  389. data/lib/graphql/tracing/skylight_tracing.rb +0 -62
  390. data/lib/graphql/types/relay/base_field.rb +0 -22
  391. data/lib/graphql/types/relay/base_interface.rb +0 -29
  392. data/lib/graphql/types/relay/base_object.rb +0 -26
  393. data/lib/graphql/types/relay/node_field.rb +0 -43
  394. data/lib/graphql/types/relay/nodes_field.rb +0 -45
  395. data/lib/graphql/union_type.rb +0 -135
  396. data/lib/graphql/upgrader/member.rb +0 -936
  397. data/lib/graphql/upgrader/schema.rb +0 -37
@@ -14,14 +14,14 @@ module GraphQL
14
14
  schema = ctx.schema
15
15
  @context = ctx
16
16
 
17
- @provided_variables = GraphQL::Argument.deep_stringify(provided_variables)
17
+ @provided_variables = deep_stringify(provided_variables)
18
18
  @errors = []
19
19
  @storage = ast_variables.each_with_object({}) do |ast_variable, memo|
20
20
  # Find the right value for this variable:
21
21
  # - First, use the value provided at runtime
22
22
  # - Then, fall back to the default value from the query string
23
23
  # If it's still nil, raise an error if it's required.
24
- variable_type = schema.type_from_ast(ast_variable.type)
24
+ variable_type = schema.type_from_ast(ast_variable.type, context: ctx)
25
25
  if variable_type.nil?
26
26
  # Pass -- it will get handled by a validator
27
27
  else
@@ -29,21 +29,21 @@ module GraphQL
29
29
  default_value = ast_variable.default_value
30
30
  provided_value = @provided_variables[variable_name]
31
31
  value_was_provided = @provided_variables.key?(variable_name)
32
-
33
32
  begin
34
33
  validation_result = variable_type.validate_input(provided_value, ctx)
35
34
  if validation_result.valid?
36
35
  if value_was_provided
37
36
  # Add the variable if a value was provided
38
- memo[variable_name] = schema.error_handler.with_error_handling(context) do
39
- variable_type.coerce_input(provided_value, ctx)
40
- end
37
+ memo[variable_name] = provided_value
41
38
  elsif default_value != nil
42
- # Add the variable if it wasn't provided but it has a default value (including `null`)
43
- memo[variable_name] = GraphQL::Query::LiteralInput.coerce(variable_type, default_value, self)
39
+ memo[variable_name] = if default_value.is_a?(Language::Nodes::NullValue)
40
+ nil
41
+ else
42
+ default_value
43
+ end
44
44
  end
45
45
  end
46
- rescue GraphQL::CoercionError, GraphQL::ExecutionError => ex
46
+ rescue GraphQL::ExecutionError => ex
47
47
  # TODO: This should really include the path to the problematic node in the variable value
48
48
  # like InputValidationResults generated by validate_non_null_input but unfortunately we don't
49
49
  # have this information available in the coerce_input call chain. Note this path is the path
@@ -60,6 +60,23 @@ module GraphQL
60
60
  end
61
61
 
62
62
  def_delegators :@storage, :length, :key?, :[], :fetch, :to_h
63
+
64
+ private
65
+
66
+ def deep_stringify(val)
67
+ case val
68
+ when Array
69
+ val.map { |v| deep_stringify(v) }
70
+ when Hash
71
+ new_val = {}
72
+ val.each do |k, v|
73
+ new_val[k.to_s] = deep_stringify(v)
74
+ end
75
+ new_val
76
+ else
77
+ val
78
+ end
79
+ end
63
80
  end
64
81
  end
65
82
  end
data/lib/graphql/query.rb CHANGED
@@ -1,12 +1,9 @@
1
1
  # frozen_string_literal: true
2
- require "graphql/query/arguments"
3
- require "graphql/query/arguments_cache"
4
2
  require "graphql/query/context"
5
- require "graphql/query/executor"
3
+ require "graphql/query/fingerprint"
6
4
  require "graphql/query/literal_input"
7
5
  require "graphql/query/null_context"
8
6
  require "graphql/query/result"
9
- require "graphql/query/serial_execution"
10
7
  require "graphql/query/variables"
11
8
  require "graphql/query/input_validation_result"
12
9
  require "graphql/query/variable_validation_error"
@@ -78,19 +75,19 @@ module GraphQL
78
75
  # @param max_complexity [Numeric] the maximum field complexity for this query (falls back to schema-level value)
79
76
  # @param except [<#call(schema_member, context)>] If provided, objects will be hidden from the schema when `.call(schema_member, context)` returns truthy
80
77
  # @param only [<#call(schema_member, context)>] If provided, objects will be hidden from the schema when `.call(schema_member, context)` returns false
81
- def initialize(schema, query_string = nil, query: nil, document: nil, context: nil, variables: nil, validate: true, subscription_topic: nil, operation_name: nil, root_value: nil, max_depth: schema.max_depth, max_complexity: schema.max_complexity, except: nil, only: nil)
78
+ def initialize(schema, query_string = nil, query: nil, document: nil, context: nil, variables: nil, validate: true, subscription_topic: nil, operation_name: nil, root_value: nil, max_depth: schema.max_depth, max_complexity: schema.max_complexity, except: nil, only: nil, warden: nil)
82
79
  # Even if `variables: nil` is passed, use an empty hash for simpler logic
83
80
  variables ||= {}
84
81
  @schema = schema
85
82
  @filter = schema.default_filter.merge(except: except, only: only)
86
83
  @context = schema.context_class.new(query: self, object: root_value, values: context)
84
+ @warden = warden
87
85
  @subscription_topic = subscription_topic
88
86
  @root_value = root_value
89
87
  @fragments = nil
90
88
  @operations = nil
91
89
  @validate = validate
92
- # TODO: remove support for global tracers
93
- @tracers = schema.tracers + GraphQL::Tracing.tracers + (context ? context.fetch(:tracers, []) : [])
90
+ @tracers = schema.tracers + (context ? context.fetch(:tracers, []) : [])
94
91
  # Support `ctx[:backtrace] = true` for wrapping backtraces
95
92
  if context && context[:backtrace] && !@tracers.include?(GraphQL::Backtrace::Tracer)
96
93
  @tracers << GraphQL::Backtrace::Tracer
@@ -100,7 +97,7 @@ module GraphQL
100
97
  if variables.is_a?(String)
101
98
  raise ArgumentError, "Query variables should be a Hash, not a String. Try JSON.parse to prepare variables."
102
99
  else
103
- @provided_variables = variables
100
+ @provided_variables = variables || {}
104
101
  end
105
102
 
106
103
  @query_string = query_string || query
@@ -110,6 +107,10 @@ module GraphQL
110
107
  raise ArgumentError, "Query should only be provided a query string or a document, not both."
111
108
  end
112
109
 
110
+ if @query_string && !@query_string.is_a?(String)
111
+ raise ArgumentError, "Query string argument should be a String, got #{@query_string.class.name} instead."
112
+ end
113
+
113
114
  # A two-layer cache of type resolution:
114
115
  # { abstract_type => { value => resolved_type } }
115
116
  @resolved_types_cache = Hash.new do |h1, k1|
@@ -118,8 +119,6 @@ module GraphQL
118
119
  end
119
120
  end
120
121
 
121
- @arguments_cache = ArgumentsCache.build(self)
122
-
123
122
  # Trying to execute a document
124
123
  # with no operations returns an empty hash
125
124
  @ast_variables = []
@@ -144,7 +143,11 @@ module GraphQL
144
143
  @query_string ||= (document ? document.to_query_string : nil)
145
144
  end
146
145
 
147
- def_delegators :@schema, :interpreter?
146
+ def interpreter?
147
+ true
148
+ end
149
+
150
+ attr_accessor :multiplex
148
151
 
149
152
  def subscription_update?
150
153
  @subscription_topic && subscription?
@@ -156,7 +159,6 @@ module GraphQL
156
159
  @lookahead ||= begin
157
160
  ast_node = selected_operation
158
161
  root_type = warden.root_type_for_operation(ast_node.operation_type || "query")
159
- root_type = root_type.metadata[:type_class] || raise("Invariant: `lookahead` only works with class-based types")
160
162
  GraphQL::Execution::Lookahead.new(query: self, root_type: root_type, ast_nodes: [ast_node])
161
163
  end
162
164
  end
@@ -186,9 +188,7 @@ module GraphQL
186
188
  # @return [Hash] A GraphQL response, with `"data"` and/or `"errors"` keys
187
189
  def result
188
190
  if !@executed
189
- with_prepared_ast {
190
- Execution::Multiplex.run_queries(@schema, [self], context: @context)
191
- }
191
+ Execution::Multiplex.run_all(@schema, [self], context: @context)
192
192
  end
193
193
  @result ||= Query::Result.new(query: self, values: @result_values)
194
194
  end
@@ -226,28 +226,60 @@ module GraphQL
226
226
  end
227
227
  end
228
228
 
229
- def irep_selection
230
- @selection ||= begin
231
- if selected_operation && internal_representation
232
- internal_representation.operation_definitions[selected_operation.name]
233
- else
234
- nil
235
- end
236
- end
229
+ # Node-level cache for calculating arguments. Used during execution and query analysis.
230
+ # @param ast_node [GraphQL::Language::Nodes::AbstractNode]
231
+ # @param definition [GraphQL::Schema::Field]
232
+ # @param parent_object [GraphQL::Schema::Object]
233
+ # @return Hash{Symbol => Object}
234
+ def arguments_for(ast_node, definition, parent_object: nil)
235
+ arguments_cache.fetch(ast_node, definition, parent_object)
237
236
  end
238
237
 
239
- # Node-level cache for calculating arguments. Used during execution and query analysis.
240
- # @api private
241
- # @return [GraphQL::Query::Arguments] Arguments for this node, merging default values, literal values and query variables
242
- def arguments_for(irep_or_ast_node, definition)
243
- @arguments_cache[irep_or_ast_node][definition]
238
+ def arguments_cache
239
+ @arguments_cache ||= Execution::Interpreter::ArgumentsCache.new(self)
240
+ end
241
+
242
+ # A version of the given query string, with:
243
+ # - Variables inlined to the query
244
+ # - Strings replaced with `<REDACTED>`
245
+ # @return [String, nil] Returns nil if the query is invalid.
246
+ def sanitized_query_string(inline_variables: true)
247
+ with_prepared_ast {
248
+ schema.sanitized_printer.new(self, inline_variables: inline_variables).sanitized_query_string
249
+ }
250
+ end
251
+
252
+ # This contains a few components:
253
+ #
254
+ # - The selected operation name (or `anonymous`)
255
+ # - The fingerprint of the query string
256
+ # - The number of given variables (for readability)
257
+ # - The fingerprint of the given variables
258
+ #
259
+ # This fingerprint can be used to track runs of the same operation-variables combination over time.
260
+ #
261
+ # @see operation_fingerprint
262
+ # @see variables_fingerprint
263
+ # @return [String] An opaque hash identifying this operation-variables combination
264
+ def fingerprint
265
+ @fingerprint ||= "#{operation_fingerprint}/#{variables_fingerprint}"
266
+ end
267
+
268
+ # @return [String] An opaque hash for identifying this query's given query string and selected operation
269
+ def operation_fingerprint
270
+ @operation_fingerprint ||= "#{selected_operation_name || "anonymous"}/#{Fingerprint.generate(query_string)}"
271
+ end
272
+
273
+ # @return [String] An opaque hash for identifying this query's given a variable values (not including defaults)
274
+ def variables_fingerprint
275
+ @variables_fingerprint ||= "#{provided_variables.size}/#{Fingerprint.generate(provided_variables.to_json)}"
244
276
  end
245
277
 
246
278
  def validation_pipeline
247
279
  with_prepared_ast { @validation_pipeline }
248
280
  end
249
281
 
250
- def_delegators :validation_pipeline, :validation_errors, :internal_representation,
282
+ def_delegators :validation_pipeline, :validation_errors,
251
283
  :analyzers, :ast_analyzers, :max_depth, :max_complexity
252
284
 
253
285
  attr_accessor :analysis_errors
@@ -320,8 +352,7 @@ module GraphQL
320
352
 
321
353
  def prepare_ast
322
354
  @prepared_ast = true
323
- @warden = GraphQL::Schema::Warden.new(@filter, schema: @schema, context: @context)
324
-
355
+ @warden ||= GraphQL::Schema::Warden.new(@filter, schema: @schema, context: @context)
325
356
  parse_error = nil
326
357
  @document ||= begin
327
358
  if query_string
@@ -374,7 +405,6 @@ module GraphQL
374
405
 
375
406
  @validation_pipeline = GraphQL::Query::ValidationPipeline.new(
376
407
  query: self,
377
- validate: @validate,
378
408
  parse_error: parse_error,
379
409
  operation_name_error: operation_name_error,
380
410
  max_depth: @max_depth,
@@ -1,108 +1,12 @@
1
1
  # frozen_string_literal: true
2
-
3
-
4
2
  module GraphQL
5
3
  class Railtie < Rails::Railtie
6
- rake_tasks do
7
- # Defer this so that you only need the `parser` gem when you _run_ the upgrader
8
- def load_upgraders
9
- require_relative './upgrader/member'
10
- require_relative './upgrader/schema'
11
- end
12
-
13
- namespace :graphql do
14
- task :upgrade, [:dir] do |t, args|
15
- unless (dir = args[:dir])
16
- fail 'You have to give me a directory where your GraphQL schema and types live. ' \
17
- 'For example: `bin/rake graphql:upgrade[app/graphql/**/*]`'
18
- end
19
-
20
- Dir[dir].each do |file|
21
- # Members (types, interfaces, etc.)
22
- if file =~ /.*_(type|interface|enum|union|)\.rb$/
23
- Rake::Task["graphql:upgrade:member"].execute(Struct.new(:member_file).new(file))
24
- end
25
- end
26
-
27
- puts "Upgrade complete! Note that this is a best-effort approach, and may very well contain some bugs."
28
- puts "Don't forget to create the base objects. For example, you could run:"
29
- puts "\tbin/rake graphql:upgrade:create_base_objects[app/graphql]"
30
- end
31
-
32
- namespace :upgrade do
33
- task :create_base_objects, [:base_dir] do |t, args|
34
- unless (base_dir = args[:base_dir])
35
- fail 'You have to give me a directory where your GraphQL types live. ' \
36
- 'For example: `bin/rake graphql:upgrade:create_base_objects[app/graphql]`'
37
- end
38
-
39
- destination_file = File.join(base_dir, "types", "base_scalar.rb")
40
- unless File.exists?(destination_file)
41
- FileUtils.mkdir_p(File.dirname(destination_file))
42
- File.open(destination_file, 'w') do |f|
43
- f.puts "class Types::BaseScalar < GraphQL::Schema::Scalar\nend"
44
- end
45
- end
46
-
47
- destination_file = File.join(base_dir, "types", "base_input_object.rb")
48
- unless File.exists?(destination_file)
49
- FileUtils.mkdir_p(File.dirname(destination_file))
50
- File.open(destination_file, 'w') do |f|
51
- f.puts "class Types::BaseInputObject < GraphQL::Schema::InputObject\nend"
52
- end
53
- end
54
-
55
- destination_file = File.join(base_dir, "types", "base_enum.rb")
56
- unless File.exists?(destination_file)
57
- FileUtils.mkdir_p(File.dirname(destination_file))
58
- File.open(destination_file, 'w') do |f|
59
- f.puts "class Types::BaseEnum < GraphQL::Schema::Enum\nend"
60
- end
61
- end
62
-
63
- destination_file = File.join(base_dir, "types", "base_union.rb")
64
- unless File.exists?(destination_file)
65
- FileUtils.mkdir_p(File.dirname(destination_file))
66
- File.open(destination_file, 'w') do |f|
67
- f.puts "class Types::BaseUnion < GraphQL::Schema::Union\nend"
68
- end
69
- end
70
-
71
- destination_file = File.join(base_dir, "types", "base_interface.rb")
72
- unless File.exists?(destination_file)
73
- FileUtils.mkdir_p(File.dirname(destination_file))
74
- File.open(destination_file, 'w') do |f|
75
- f.puts "module Types::BaseInterface\n include GraphQL::Schema::Interface\nend"
76
- end
77
- end
78
-
79
- destination_file = File.join(base_dir, "types", "base_object.rb")
80
- unless File.exists?(destination_file)
81
- File.open(destination_file, 'w') do |f|
82
- f.puts "class Types::BaseObject < GraphQL::Schema::Object\nend"
83
- end
84
- end
85
- end
86
-
87
- task :schema, [:schema_file] do |t, args|
88
- schema_file = args.schema_file
89
- load_upgraders
90
- upgrader = GraphQL::Upgrader::Schema.new File.read(schema_file)
91
-
92
- puts "- Transforming schema #{schema_file}"
93
- File.open(schema_file, 'w') { |f| f.write upgrader.upgrade }
94
- end
95
-
96
- task :member, [:member_file] do |t, args|
97
- member_file = args.member_file
98
- load_upgraders
99
- upgrader = GraphQL::Upgrader::Member.new File.read(member_file)
100
- next unless upgrader.upgradeable?
101
-
102
- puts "- Transforming member #{member_file}"
103
- File.open(member_file, 'w') { |f| f.write upgrader.upgrade }
104
- end
105
- end
4
+ config.before_configuration do
5
+ # Bootsnap compile cache has similar expiration properties,
6
+ # so we assume that if the user has bootsnap setup it's ok
7
+ # to piggy back on it.
8
+ if ::Object.const_defined?("Bootsnap::CompileCache::ISeq") && Bootsnap::CompileCache::ISeq.cache_dir
9
+ Language::Parser.cache ||= Language::Cache.new(Pathname.new(Bootsnap::CompileCache::ISeq.cache_dir).join('graphql'))
106
10
  end
107
11
  end
108
12
  end
@@ -7,6 +7,9 @@ module GraphQL
7
7
  desc "Get the checksum of a graphql-pro version and compare it to published versions on GitHub and graphql-ruby.org"
8
8
  task "graphql:pro:validate", [:gem_version] do |t, args|
9
9
  version = args[:gem_version]
10
+ if version.nil?
11
+ raise ArgumentError, "A specific version is required, eg `rake graphql:pro:validate[1.12.0]`"
12
+ end
10
13
  check = "\e[32m✓\e[0m"
11
14
  ex = "\e[31m✘\e[0m"
12
15
  puts "Validating graphql-pro v#{version}"
@@ -76,15 +76,7 @@ module GraphQL
76
76
  # Set the parameters of this task by passing keyword arguments
77
77
  # or assigning attributes inside the block
78
78
  def initialize(options = {})
79
- default_dependencies = if Rake::Task.task_defined?("environment")
80
- [:environment]
81
- else
82
- []
83
- end
84
-
85
- all_options = DEFAULT_OPTIONS
86
- .merge(dependencies: default_dependencies)
87
- .merge(options)
79
+ all_options = DEFAULT_OPTIONS.merge(options)
88
80
  all_options.each do |k, v|
89
81
  self.public_send("#{k}=", v)
90
82
  end
@@ -106,6 +98,9 @@ module GraphQL
106
98
  result = schema.public_send(method_name, only: @only, except: @except, context: context)
107
99
  dir = File.dirname(file)
108
100
  FileUtils.mkdir_p(dir)
101
+ if !result.end_with?("\n")
102
+ result += "\n"
103
+ end
109
104
  File.write(file, result)
110
105
  end
111
106
 
@@ -117,18 +112,26 @@ module GraphQL
117
112
  File.join(@directory, @json_outfile)
118
113
  end
119
114
 
115
+ def load_rails_environment_if_defined
116
+ if Rake::Task.task_defined?('environment')
117
+ Rake::Task['environment'].invoke
118
+ end
119
+ end
120
+
120
121
  # Use the Rake DSL to add tasks
121
122
  def define_task
122
123
  namespace(@namespace) do
123
124
  namespace("schema") do
124
125
  desc("Dump the schema to IDL in #{idl_path}")
125
126
  task :idl => @dependencies do
127
+ load_rails_environment_if_defined
126
128
  write_outfile(:to_definition, idl_path)
127
129
  puts "Schema IDL dumped into #{idl_path}"
128
130
  end
129
131
 
130
132
  desc("Dump the schema to JSON in #{json_path}")
131
133
  task :json => @dependencies do
134
+ load_rails_environment_if_defined
132
135
  write_outfile(:to_json, json_path)
133
136
  puts "Schema JSON dumped into #{json_path}"
134
137
  end
@@ -9,7 +9,7 @@ module GraphQL
9
9
  # should be ordered and paginated before providing it here.
10
10
  #
11
11
  # @example Adding a comment to list of comments
12
- # post = Post.find(args[:postId])
12
+ # post = Post.find(args[:post_id])
13
13
  # comments = post.comments
14
14
  # new_comment = comments.build(body: args[:body])
15
15
  # new_comment.save!
@@ -18,13 +18,13 @@ module GraphQL
18
18
  # parent: post,
19
19
  # collection: comments,
20
20
  # item: new_comment,
21
- # context: ctx,
21
+ # context: context,
22
22
  # )
23
23
  #
24
24
  # response = {
25
25
  # post: post,
26
- # commentsConnection: range_add.connection,
27
- # newCommentEdge: range_add.edge,
26
+ # comments_connection: range_add.connection,
27
+ # new_comment_edge: range_add.edge,
28
28
  # }
29
29
  class RangeAdd
30
30
  attr_reader :edge, :connection, :parent
@@ -33,12 +33,26 @@ module GraphQL
33
33
  # @param item [Object] The newly-added item (will be wrapped in `edge_class`)
34
34
  # @param parent [Object] The owner of `collection`, will be passed to the connection if provided
35
35
  # @param context [GraphQL::Query::Context] The surrounding `ctx`, will be passed to the connection if provided (this is required for cursor encoders)
36
- # @param edge_class [Class] The class to wrap `item` with
37
- def initialize(collection:, item:, parent: nil, context: nil, edge_class: Relay::Edge)
38
- connection_class = BaseConnection.connection_for_nodes(collection)
36
+ # @param edge_class [Class] The class to wrap `item` with (defaults to the connection's edge class)
37
+ def initialize(collection:, item:, parent: nil, context: nil, edge_class: nil)
38
+ if context && context.schema.new_connections?
39
+ conn_class = context.schema.connections.wrapper_for(collection)
40
+ # The rest will be added by ConnectionExtension
41
+ @connection = conn_class.new(collection, parent: parent, context: context, edge_class: edge_class)
42
+ # Check if this connection supports it, to support old versions of GraphQL-Pro
43
+ @edge = if @connection.respond_to?(:range_add_edge)
44
+ @connection.range_add_edge(item)
45
+ else
46
+ @connection.edge_class.new(item, @connection)
47
+ end
48
+ else
49
+ connection_class = BaseConnection.connection_for_nodes(collection)
50
+ @connection = connection_class.new(collection, {}, parent: parent, context: context)
51
+ edge_class ||= Relay::Edge
52
+ @edge = edge_class.new(item, @connection)
53
+ end
54
+
39
55
  @parent = parent
40
- @connection = connection_class.new(collection, {}, parent: parent, context: context)
41
- @edge = edge_class.new(item, @connection)
42
56
  end
43
57
  end
44
58
  end
data/lib/graphql/relay.rb CHANGED
@@ -1,18 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'graphql/relay/page_info'
4
- require 'graphql/relay/edge'
5
- require 'graphql/relay/edge_type'
6
- require 'graphql/relay/edges_instrumentation'
7
- require 'graphql/relay/base_connection'
8
- require 'graphql/relay/array_connection'
9
3
  require 'graphql/relay/range_add'
10
- require 'graphql/relay/relation_connection'
11
- require 'graphql/relay/mongo_relation_connection'
12
- require 'graphql/relay/global_id_resolve'
13
- require 'graphql/relay/mutation'
14
- require 'graphql/relay/node'
15
- require 'graphql/relay/connection_instrumentation'
16
- require 'graphql/relay/connection_resolve'
17
- require 'graphql/relay/connection_type'
18
- require 'graphql/relay/type_extensions'
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+ require "rubocop"
3
+
4
+ module GraphQL
5
+ module Rubocop
6
+ module GraphQL
7
+ class BaseCop < RuboCop::Cop::Base
8
+ extend RuboCop::Cop::AutoCorrector
9
+
10
+ # Return the source of `send_node`, but without the keyword argument represented by `pair_node`
11
+ def source_without_keyword_argument(send_node, pair_node)
12
+ # work back to the preceeding comma
13
+ first_pos = pair_node.location.expression.begin_pos
14
+ end_pos = pair_node.location.expression.end_pos
15
+ node_source = send_node.source_range.source
16
+ node_first_pos = send_node.location.expression.begin_pos
17
+
18
+ relative_first_pos = first_pos - node_first_pos
19
+ relative_last_pos = end_pos - node_first_pos
20
+
21
+ begin_removal_pos = relative_first_pos
22
+ while node_source[begin_removal_pos] != ","
23
+ begin_removal_pos -= 1
24
+ if begin_removal_pos < 1
25
+ raise "Invariant: somehow backtracked to beginning of node looking for a comma (node source: #{node_source.inspect})"
26
+ end
27
+ end
28
+
29
+ end_removal_pos = relative_last_pos
30
+ cleaned_node_source = node_source[0...begin_removal_pos] + node_source[end_removal_pos..-1]
31
+ cleaned_node_source
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+ require_relative "base_cop"
3
+
4
+ module GraphQL
5
+ module Rubocop
6
+ module GraphQL
7
+ # Identify (and auto-correct) any field configuration which duplicates
8
+ # the default `null: true` property.
9
+ #
10
+ # `null: true` is default because nullable fields can always be converted
11
+ # to non-null fields (`null: false`) without a breaking change. (The opposite change, from `null: false`
12
+ # to `null: true`, change.)
13
+ #
14
+ # @example
15
+ # # Both of these define `name: String` in GraphQL:
16
+ #
17
+ # # bad
18
+ # field :name, String, null: true
19
+ #
20
+ # # good
21
+ # field :name, String
22
+ #
23
+ class DefaultNullTrue < BaseCop
24
+ MSG = "`null: true` is the default and can be removed."
25
+
26
+ def_node_matcher :field_config_with_null_true?, <<-Pattern
27
+ (
28
+ send nil? :field ... (hash $(pair (sym :null) (true)) ...)
29
+ )
30
+ Pattern
31
+
32
+ def on_send(node)
33
+ field_config_with_null_true?(node) do |null_config|
34
+ add_offense(null_config) do |corrector|
35
+ cleaned_node_source = source_without_keyword_argument(node, null_config)
36
+ corrector.replace(node.source_range, cleaned_node_source)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+ require_relative "./base_cop"
3
+
4
+ module GraphQL
5
+ module Rubocop
6
+ module GraphQL
7
+ # Identify (and auto-correct) any argument configuration which duplicates
8
+ # the default `required: true` property.
9
+ #
10
+ # `required: true` is default because required arguments can always be converted
11
+ # to optional arguments (`required: false`) without a breaking change. (The opposite change, from `required: false`
12
+ # to `required: true`, change.)
13
+ #
14
+ # @example
15
+ # # Both of these define `id: ID!` in GraphQL:
16
+ #
17
+ # # bad
18
+ # argument :id, ID, required: true
19
+ #
20
+ # # good
21
+ # argument :id, ID
22
+ #
23
+ class DefaultRequiredTrue < BaseCop
24
+ MSG = "`required: true` is the default and can be removed."
25
+
26
+ def_node_matcher :argument_config_with_required_true?, <<-Pattern
27
+ (
28
+ send {nil? _} :argument ... (hash <$(pair (sym :required) (true)) ...>)
29
+ )
30
+ Pattern
31
+
32
+ def on_send(node)
33
+ argument_config_with_required_true?(node) do |required_config|
34
+ add_offense(required_config) do |corrector|
35
+ cleaned_node_source = source_without_keyword_argument(node, required_config)
36
+ corrector.replace(node, cleaned_node_source)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "graphql/rubocop/graphql/default_null_true"
4
+ require "graphql/rubocop/graphql/default_required_true"