graphql 0.16.0 → 2.0.15

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 (490) hide show
  1. checksums.yaml +5 -5
  2. data/.yardopts +5 -0
  3. data/lib/generators/graphql/core.rb +69 -0
  4. data/lib/generators/graphql/enum_generator.rb +27 -0
  5. data/lib/generators/graphql/field_extractor.rb +31 -0
  6. data/lib/generators/graphql/input_generator.rb +50 -0
  7. data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
  8. data/lib/generators/graphql/install/templates/base_mutation.erb +10 -0
  9. data/lib/generators/graphql/install/templates/mutation_type.erb +12 -0
  10. data/lib/generators/graphql/install_generator.rb +197 -0
  11. data/lib/generators/graphql/interface_generator.rb +27 -0
  12. data/lib/generators/graphql/loader_generator.rb +21 -0
  13. data/lib/generators/graphql/mutation_create_generator.rb +22 -0
  14. data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
  15. data/lib/generators/graphql/mutation_generator.rb +30 -0
  16. data/lib/generators/graphql/mutation_update_generator.rb +22 -0
  17. data/lib/generators/graphql/object_generator.rb +50 -0
  18. data/lib/generators/graphql/orm_mutations_base.rb +40 -0
  19. data/lib/generators/graphql/relay.rb +49 -0
  20. data/lib/generators/graphql/relay_generator.rb +21 -0
  21. data/lib/generators/graphql/scalar_generator.rb +22 -0
  22. data/lib/generators/graphql/templates/base_argument.erb +6 -0
  23. data/lib/generators/graphql/templates/base_connection.erb +8 -0
  24. data/lib/generators/graphql/templates/base_edge.erb +8 -0
  25. data/lib/generators/graphql/templates/base_enum.erb +6 -0
  26. data/lib/generators/graphql/templates/base_field.erb +7 -0
  27. data/lib/generators/graphql/templates/base_input_object.erb +7 -0
  28. data/lib/generators/graphql/templates/base_interface.erb +9 -0
  29. data/lib/generators/graphql/templates/base_object.erb +7 -0
  30. data/lib/generators/graphql/templates/base_scalar.erb +6 -0
  31. data/lib/generators/graphql/templates/base_union.erb +6 -0
  32. data/lib/generators/graphql/templates/enum.erb +11 -0
  33. data/lib/generators/graphql/templates/graphql_controller.erb +52 -0
  34. data/lib/generators/graphql/templates/input.erb +9 -0
  35. data/lib/generators/graphql/templates/interface.erb +10 -0
  36. data/lib/generators/graphql/templates/loader.erb +19 -0
  37. data/lib/generators/graphql/templates/mutation.erb +16 -0
  38. data/lib/generators/graphql/templates/mutation_create.erb +20 -0
  39. data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
  40. data/lib/generators/graphql/templates/mutation_update.erb +21 -0
  41. data/lib/generators/graphql/templates/node_type.erb +9 -0
  42. data/lib/generators/graphql/templates/object.erb +10 -0
  43. data/lib/generators/graphql/templates/query_type.erb +15 -0
  44. data/lib/generators/graphql/templates/scalar.erb +17 -0
  45. data/lib/generators/graphql/templates/schema.erb +30 -0
  46. data/lib/generators/graphql/templates/union.erb +9 -0
  47. data/lib/generators/graphql/type_generator.rb +135 -0
  48. data/lib/generators/graphql/union_generator.rb +33 -0
  49. data/lib/graphql/analysis/ast/analyzer.rb +84 -0
  50. data/lib/graphql/analysis/ast/field_usage.rb +57 -0
  51. data/lib/graphql/analysis/ast/max_query_complexity.rb +22 -0
  52. data/lib/graphql/analysis/ast/max_query_depth.rb +22 -0
  53. data/lib/graphql/analysis/ast/query_complexity.rb +230 -0
  54. data/lib/graphql/analysis/ast/query_depth.rb +55 -0
  55. data/lib/graphql/analysis/ast/visitor.rb +269 -0
  56. data/lib/graphql/analysis/ast.rb +81 -0
  57. data/lib/graphql/analysis.rb +2 -5
  58. data/lib/graphql/analysis_error.rb +1 -0
  59. data/lib/graphql/backtrace/inspect_result.rb +50 -0
  60. data/lib/graphql/backtrace/table.rb +141 -0
  61. data/lib/graphql/backtrace/traced_error.rb +54 -0
  62. data/lib/graphql/backtrace/tracer.rb +80 -0
  63. data/lib/graphql/backtrace.rb +58 -0
  64. data/lib/graphql/coercion_error.rb +13 -0
  65. data/lib/graphql/dataloader/null_dataloader.rb +24 -0
  66. data/lib/graphql/dataloader/request.rb +19 -0
  67. data/lib/graphql/dataloader/request_all.rb +19 -0
  68. data/lib/graphql/dataloader/source.rb +164 -0
  69. data/lib/graphql/dataloader.rb +311 -0
  70. data/lib/graphql/date_encoding_error.rb +16 -0
  71. data/lib/graphql/deprecation.rb +9 -0
  72. data/lib/graphql/dig.rb +19 -0
  73. data/lib/graphql/execution/directive_checks.rb +37 -0
  74. data/lib/graphql/execution/errors.rb +93 -0
  75. data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
  76. data/lib/graphql/execution/interpreter/arguments.rb +88 -0
  77. data/lib/graphql/execution/interpreter/arguments_cache.rb +105 -0
  78. data/lib/graphql/execution/interpreter/execution_errors.rb +29 -0
  79. data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
  80. data/lib/graphql/execution/interpreter/resolve.rb +77 -0
  81. data/lib/graphql/execution/interpreter/runtime.rb +994 -0
  82. data/lib/graphql/execution/interpreter.rb +226 -0
  83. data/lib/graphql/execution/lazy/lazy_method_map.rb +98 -0
  84. data/lib/graphql/execution/lazy.rb +75 -0
  85. data/lib/graphql/execution/lookahead.rb +311 -0
  86. data/lib/graphql/execution/multiplex.rb +45 -0
  87. data/lib/graphql/execution.rb +18 -0
  88. data/lib/graphql/execution_error.rb +34 -1
  89. data/lib/graphql/filter.rb +53 -0
  90. data/lib/graphql/integer_decoding_error.rb +17 -0
  91. data/lib/graphql/integer_encoding_error.rb +36 -0
  92. data/lib/graphql/introspection/base_object.rb +13 -0
  93. data/lib/graphql/introspection/directive_location_enum.rb +12 -5
  94. data/lib/graphql/introspection/directive_type.rb +30 -10
  95. data/lib/graphql/introspection/dynamic_fields.rb +12 -0
  96. data/lib/graphql/introspection/entry_points.rb +22 -0
  97. data/lib/graphql/introspection/enum_value_type.rb +21 -8
  98. data/lib/graphql/introspection/field_type.rb +26 -10
  99. data/lib/graphql/introspection/input_value_type.rb +64 -14
  100. data/lib/graphql/introspection/introspection_query.rb +7 -76
  101. data/lib/graphql/introspection/schema_type.rb +42 -17
  102. data/lib/graphql/introspection/type_kind_enum.rb +11 -5
  103. data/lib/graphql/introspection/type_type.rb +104 -16
  104. data/lib/graphql/introspection.rb +104 -13
  105. data/lib/graphql/invalid_name_error.rb +11 -0
  106. data/lib/graphql/invalid_null_error.rb +36 -8
  107. data/lib/graphql/language/block_string.rb +99 -0
  108. data/lib/graphql/language/cache.rb +37 -0
  109. data/lib/graphql/language/definition_slice.rb +41 -0
  110. data/lib/graphql/language/document_from_schema_definition.rb +335 -0
  111. data/lib/graphql/language/generation.rb +16 -86
  112. data/lib/graphql/language/lexer.rb +1436 -705
  113. data/lib/graphql/language/lexer.rl +172 -64
  114. data/lib/graphql/language/nodes.rb +617 -105
  115. data/lib/graphql/language/parser.rb +1524 -430
  116. data/lib/graphql/language/parser.y +348 -73
  117. data/lib/graphql/language/printer.rb +386 -0
  118. data/lib/graphql/language/sanitized_printer.rb +222 -0
  119. data/lib/graphql/language/token.rb +16 -3
  120. data/lib/graphql/language/visitor.rb +169 -25
  121. data/lib/graphql/language.rb +30 -0
  122. data/lib/graphql/load_application_object_failed_error.rb +22 -0
  123. data/lib/graphql/name_validator.rb +11 -0
  124. data/lib/graphql/pagination/active_record_relation_connection.rb +85 -0
  125. data/lib/graphql/pagination/array_connection.rb +79 -0
  126. data/lib/graphql/pagination/connection.rb +253 -0
  127. data/lib/graphql/pagination/connections.rb +135 -0
  128. data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
  129. data/lib/graphql/pagination/relation_connection.rb +228 -0
  130. data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
  131. data/lib/graphql/pagination.rb +6 -0
  132. data/lib/graphql/parse_error.rb +24 -0
  133. data/lib/graphql/query/context.rb +266 -12
  134. data/lib/graphql/query/fingerprint.rb +26 -0
  135. data/lib/graphql/query/input_validation_result.rb +34 -7
  136. data/lib/graphql/query/null_context.rb +52 -0
  137. data/lib/graphql/query/result.rb +63 -0
  138. data/lib/graphql/query/validation_pipeline.rb +114 -0
  139. data/lib/graphql/query/variable_validation_error.rb +27 -3
  140. data/lib/graphql/query/variables.rb +75 -24
  141. data/lib/graphql/query.rb +359 -92
  142. data/lib/graphql/railtie.rb +13 -0
  143. data/lib/graphql/rake_task/validate.rb +63 -0
  144. data/lib/graphql/rake_task.rb +146 -0
  145. data/lib/graphql/relay/range_add.rb +52 -0
  146. data/lib/graphql/relay.rb +3 -0
  147. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  148. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  149. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  150. data/lib/graphql/rubocop.rb +4 -0
  151. data/lib/graphql/runtime_type_error.rb +5 -0
  152. data/lib/graphql/schema/addition.rb +245 -0
  153. data/lib/graphql/schema/argument.rb +395 -0
  154. data/lib/graphql/schema/base_64_bp.rb +26 -0
  155. data/lib/graphql/schema/base_64_encoder.rb +21 -0
  156. data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +47 -0
  157. data/lib/graphql/schema/build_from_definition/resolve_map.rb +78 -0
  158. data/lib/graphql/schema/build_from_definition.rb +492 -0
  159. data/lib/graphql/schema/built_in_types.rb +12 -0
  160. data/lib/graphql/schema/directive/deprecated.rb +18 -0
  161. data/lib/graphql/schema/directive/feature.rb +66 -0
  162. data/lib/graphql/schema/directive/flagged.rb +57 -0
  163. data/lib/graphql/schema/directive/include.rb +25 -0
  164. data/lib/graphql/schema/directive/one_of.rb +12 -0
  165. data/lib/graphql/schema/directive/skip.rb +25 -0
  166. data/lib/graphql/schema/directive/transform.rb +60 -0
  167. data/lib/graphql/schema/directive.rb +212 -0
  168. data/lib/graphql/schema/enum.rb +176 -0
  169. data/lib/graphql/schema/enum_value.rb +77 -0
  170. data/lib/graphql/schema/field/connection_extension.rb +80 -0
  171. data/lib/graphql/schema/field/scope_extension.rb +22 -0
  172. data/lib/graphql/schema/field.rb +862 -0
  173. data/lib/graphql/schema/field_extension.rb +156 -0
  174. data/lib/graphql/schema/find_inherited_value.rb +36 -0
  175. data/lib/graphql/schema/finder.rb +155 -0
  176. data/lib/graphql/schema/input_object.rb +258 -0
  177. data/lib/graphql/schema/interface.rb +113 -0
  178. data/lib/graphql/schema/introspection_system.rb +164 -0
  179. data/lib/graphql/schema/invalid_type_error.rb +1 -0
  180. data/lib/graphql/schema/late_bound_type.rb +37 -0
  181. data/lib/graphql/schema/list.rb +86 -0
  182. data/lib/graphql/schema/loader.rb +228 -0
  183. data/lib/graphql/schema/member/base_dsl_methods.rb +124 -0
  184. data/lib/graphql/schema/member/build_type.rb +178 -0
  185. data/lib/graphql/schema/member/graphql_type_names.rb +21 -0
  186. data/lib/graphql/schema/member/has_arguments.rb +376 -0
  187. data/lib/graphql/schema/member/has_ast_node.rb +20 -0
  188. data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
  189. data/lib/graphql/schema/member/has_directives.rb +113 -0
  190. data/lib/graphql/schema/member/has_fields.rb +163 -0
  191. data/lib/graphql/schema/member/has_interfaces.rb +88 -0
  192. data/lib/graphql/schema/member/has_path.rb +25 -0
  193. data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
  194. data/lib/graphql/schema/member/has_validators.rb +31 -0
  195. data/lib/graphql/schema/member/relay_shortcuts.rb +73 -0
  196. data/lib/graphql/schema/member/scoped.rb +21 -0
  197. data/lib/graphql/schema/member/type_system_helpers.rb +38 -0
  198. data/lib/graphql/schema/member/validates_input.rb +33 -0
  199. data/lib/graphql/schema/member.rb +39 -0
  200. data/lib/graphql/schema/mutation.rb +85 -0
  201. data/lib/graphql/schema/non_null.rb +67 -0
  202. data/lib/graphql/schema/null_mask.rb +11 -0
  203. data/lib/graphql/schema/object.rb +117 -0
  204. data/lib/graphql/schema/printer.rb +72 -128
  205. data/lib/graphql/schema/relay_classic_mutation.rb +179 -0
  206. data/lib/graphql/schema/resolver/has_payload_type.rb +106 -0
  207. data/lib/graphql/schema/resolver.rb +402 -0
  208. data/lib/graphql/schema/scalar.rb +68 -0
  209. data/lib/graphql/schema/subscription.rb +148 -0
  210. data/lib/graphql/schema/timeout.rb +123 -0
  211. data/lib/graphql/schema/type_expression.rb +29 -5
  212. data/lib/graphql/schema/type_membership.rb +51 -0
  213. data/lib/graphql/schema/union.rb +81 -0
  214. data/lib/graphql/schema/unique_within_type.rb +34 -0
  215. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  216. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  217. data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
  218. data/lib/graphql/schema/validator/format_validator.rb +48 -0
  219. data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
  220. data/lib/graphql/schema/validator/length_validator.rb +59 -0
  221. data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
  222. data/lib/graphql/schema/validator/required_validator.rb +82 -0
  223. data/lib/graphql/schema/validator.rb +171 -0
  224. data/lib/graphql/schema/warden.rb +413 -0
  225. data/lib/graphql/schema/wrapper.rb +24 -0
  226. data/lib/graphql/schema.rb +1179 -104
  227. data/lib/graphql/static_validation/all_rules.rb +14 -0
  228. data/lib/graphql/static_validation/base_visitor.rb +200 -0
  229. data/lib/graphql/static_validation/definition_dependencies.rb +198 -0
  230. data/lib/graphql/static_validation/error.rb +46 -0
  231. data/lib/graphql/static_validation/interpreter_visitor.rb +14 -0
  232. data/lib/graphql/static_validation/literal_validator.rb +113 -22
  233. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +59 -11
  234. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +48 -0
  235. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +31 -0
  236. data/lib/graphql/static_validation/rules/argument_names_are_unique_error.rb +30 -0
  237. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +62 -8
  238. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +37 -0
  239. data/lib/graphql/static_validation/rules/directives_are_defined.rb +20 -13
  240. data/lib/graphql/static_validation/rules/directives_are_defined_error.rb +29 -0
  241. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +32 -26
  242. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations_error.rb +31 -0
  243. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +21 -23
  244. data/lib/graphql/static_validation/rules/fields_are_defined_on_type_error.rb +32 -0
  245. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +55 -18
  246. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections_error.rb +31 -0
  247. data/lib/graphql/static_validation/rules/fields_will_merge.rb +390 -70
  248. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +53 -0
  249. data/lib/graphql/static_validation/rules/fragment_names_are_unique.rb +30 -0
  250. data/lib/graphql/static_validation/rules/fragment_names_are_unique_error.rb +29 -0
  251. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +54 -37
  252. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible_error.rb +35 -0
  253. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +26 -16
  254. data/lib/graphql/static_validation/rules/fragment_types_exist_error.rb +29 -0
  255. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +13 -19
  256. data/lib/graphql/static_validation/rules/fragments_are_finite_error.rb +29 -0
  257. data/lib/graphql/static_validation/rules/fragments_are_named.rb +16 -0
  258. data/lib/graphql/static_validation/rules/fragments_are_named_error.rb +26 -0
  259. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +25 -20
  260. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types_error.rb +30 -0
  261. data/lib/graphql/static_validation/rules/fragments_are_used.rb +22 -33
  262. data/lib/graphql/static_validation/rules/fragments_are_used_error.rb +29 -0
  263. data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
  264. data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
  265. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +17 -0
  266. data/lib/graphql/static_validation/rules/mutation_root_exists_error.rb +26 -0
  267. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +41 -0
  268. data/lib/graphql/static_validation/rules/no_definitions_are_present_error.rb +25 -0
  269. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  270. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  271. data/lib/graphql/static_validation/rules/operation_names_are_valid.rb +36 -0
  272. data/lib/graphql/static_validation/rules/operation_names_are_valid_error.rb +28 -0
  273. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  274. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  275. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +22 -21
  276. data/lib/graphql/static_validation/rules/required_arguments_are_present_error.rb +35 -0
  277. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +59 -0
  278. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present_error.rb +35 -0
  279. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +17 -0
  280. data/lib/graphql/static_validation/rules/subscription_root_exists_error.rb +26 -0
  281. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +56 -0
  282. data/lib/graphql/static_validation/rules/unique_directives_per_location_error.rb +29 -0
  283. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +36 -18
  284. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed_error.rb +39 -0
  285. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +24 -0
  286. data/lib/graphql/static_validation/rules/variable_names_are_unique_error.rb +29 -0
  287. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +103 -39
  288. data/lib/graphql/static_validation/rules/variable_usages_are_allowed_error.rb +38 -0
  289. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +22 -14
  290. data/lib/graphql/static_validation/rules/variables_are_input_types_error.rb +32 -0
  291. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +92 -70
  292. data/lib/graphql/static_validation/rules/variables_are_used_and_defined_error.rb +37 -0
  293. data/lib/graphql/static_validation/type_stack.rb +85 -24
  294. data/lib/graphql/static_validation/validation_context.rb +25 -46
  295. data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
  296. data/lib/graphql/static_validation/validator.rb +46 -15
  297. data/lib/graphql/static_validation.rb +6 -3
  298. data/lib/graphql/string_encoding_error.rb +20 -0
  299. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +247 -0
  300. data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
  301. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +58 -0
  302. data/lib/graphql/subscriptions/event.rb +144 -0
  303. data/lib/graphql/subscriptions/instrumentation.rb +28 -0
  304. data/lib/graphql/subscriptions/serialize.rb +158 -0
  305. data/lib/graphql/subscriptions.rb +306 -0
  306. data/lib/graphql/tracing/active_support_notifications_tracing.rb +21 -0
  307. data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
  308. data/lib/graphql/tracing/appsignal_tracing.rb +51 -0
  309. data/lib/graphql/tracing/data_dog_tracing.rb +100 -0
  310. data/lib/graphql/tracing/instrumentation_tracing.rb +83 -0
  311. data/lib/graphql/tracing/new_relic_tracing.rb +51 -0
  312. data/lib/graphql/tracing/notifications_tracing.rb +59 -0
  313. data/lib/graphql/tracing/platform_tracing.rb +122 -0
  314. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +32 -0
  315. data/lib/graphql/tracing/prometheus_tracing.rb +67 -0
  316. data/lib/graphql/tracing/scout_tracing.rb +54 -0
  317. data/lib/graphql/tracing/statsd_tracing.rb +42 -0
  318. data/lib/graphql/tracing.rb +94 -0
  319. data/lib/graphql/type_kinds.rb +50 -22
  320. data/lib/graphql/types/big_int.rb +23 -0
  321. data/lib/graphql/types/boolean.rb +18 -0
  322. data/lib/graphql/types/float.rb +19 -0
  323. data/lib/graphql/types/id.rb +24 -0
  324. data/lib/graphql/types/int.rb +36 -0
  325. data/lib/graphql/types/iso_8601_date.rb +45 -0
  326. data/lib/graphql/types/iso_8601_date_time.rb +76 -0
  327. data/lib/graphql/types/json.rb +25 -0
  328. data/lib/graphql/types/relay/base_connection.rb +49 -0
  329. data/lib/graphql/types/relay/base_edge.rb +29 -0
  330. data/lib/graphql/types/relay/connection_behaviors.rb +154 -0
  331. data/lib/graphql/types/relay/default_relay.rb +21 -0
  332. data/lib/graphql/types/relay/edge_behaviors.rb +64 -0
  333. data/lib/graphql/types/relay/has_node_field.rb +41 -0
  334. data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
  335. data/lib/graphql/types/relay/node.rb +15 -0
  336. data/lib/graphql/types/relay/node_behaviors.rb +19 -0
  337. data/lib/graphql/types/relay/page_info.rb +11 -0
  338. data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
  339. data/lib/graphql/types/relay.rb +39 -0
  340. data/lib/graphql/types/string.rb +29 -0
  341. data/lib/graphql/types.rb +11 -0
  342. data/lib/graphql/unauthorized_error.rb +29 -0
  343. data/lib/graphql/unauthorized_field_error.rb +23 -0
  344. data/lib/graphql/unresolved_type_error.rb +35 -0
  345. data/lib/graphql/version.rb +2 -1
  346. data/lib/graphql.rb +86 -41
  347. data/readme.md +15 -101
  348. metadata +394 -279
  349. data/lib/graphql/analysis/analyze_query.rb +0 -73
  350. data/lib/graphql/analysis/max_query_complexity.rb +0 -25
  351. data/lib/graphql/analysis/max_query_depth.rb +0 -25
  352. data/lib/graphql/analysis/query_complexity.rb +0 -122
  353. data/lib/graphql/analysis/query_depth.rb +0 -54
  354. data/lib/graphql/argument.rb +0 -25
  355. data/lib/graphql/base_type.rb +0 -115
  356. data/lib/graphql/boolean_type.rb +0 -9
  357. data/lib/graphql/define/assign_argument.rb +0 -20
  358. data/lib/graphql/define/assign_enum_value.rb +0 -16
  359. data/lib/graphql/define/assign_object_field.rb +0 -21
  360. data/lib/graphql/define/assignment_dictionary.rb +0 -26
  361. data/lib/graphql/define/defined_object_proxy.rb +0 -32
  362. data/lib/graphql/define/instance_definable.rb +0 -79
  363. data/lib/graphql/define/non_null_with_bang.rb +0 -15
  364. data/lib/graphql/define/type_definer.rb +0 -30
  365. data/lib/graphql/define.rb +0 -8
  366. data/lib/graphql/directive/include_directive.rb +0 -10
  367. data/lib/graphql/directive/skip_directive.rb +0 -11
  368. data/lib/graphql/directive.rb +0 -49
  369. data/lib/graphql/enum_type.rb +0 -95
  370. data/lib/graphql/field.rb +0 -131
  371. data/lib/graphql/float_type.rb +0 -5
  372. data/lib/graphql/id_type.rb +0 -12
  373. data/lib/graphql/input_object_type.rb +0 -71
  374. data/lib/graphql/int_type.rb +0 -5
  375. data/lib/graphql/interface_type.rb +0 -38
  376. data/lib/graphql/internal_representation/node.rb +0 -81
  377. data/lib/graphql/internal_representation/rewrite.rb +0 -177
  378. data/lib/graphql/internal_representation.rb +0 -2
  379. data/lib/graphql/introspection/arguments_field.rb +0 -5
  380. data/lib/graphql/introspection/enum_values_field.rb +0 -13
  381. data/lib/graphql/introspection/fields_field.rb +0 -13
  382. data/lib/graphql/introspection/input_fields_field.rb +0 -12
  383. data/lib/graphql/introspection/interfaces_field.rb +0 -5
  384. data/lib/graphql/introspection/of_type_field.rb +0 -6
  385. data/lib/graphql/introspection/possible_types_field.rb +0 -11
  386. data/lib/graphql/introspection/schema_field.rb +0 -15
  387. data/lib/graphql/introspection/type_by_name_field.rb +0 -16
  388. data/lib/graphql/introspection/typename_field.rb +0 -15
  389. data/lib/graphql/list_type.rb +0 -46
  390. data/lib/graphql/non_null_type.rb +0 -43
  391. data/lib/graphql/object_type.rb +0 -93
  392. data/lib/graphql/query/arguments.rb +0 -76
  393. data/lib/graphql/query/directive_resolution.rb +0 -16
  394. data/lib/graphql/query/executor.rb +0 -45
  395. data/lib/graphql/query/literal_input.rb +0 -90
  396. data/lib/graphql/query/serial_execution/execution_context.rb +0 -31
  397. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -82
  398. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -27
  399. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -42
  400. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -107
  401. data/lib/graphql/query/serial_execution.rb +0 -41
  402. data/lib/graphql/query/type_resolver.rb +0 -25
  403. data/lib/graphql/scalar_type.rb +0 -53
  404. data/lib/graphql/schema/catchall_middleware.rb +0 -34
  405. data/lib/graphql/schema/middleware_chain.rb +0 -28
  406. data/lib/graphql/schema/possible_types.rb +0 -34
  407. data/lib/graphql/schema/reduce_types.rb +0 -68
  408. data/lib/graphql/schema/rescue_middleware.rb +0 -53
  409. data/lib/graphql/schema/timeout_middleware.rb +0 -67
  410. data/lib/graphql/schema/type_map.rb +0 -30
  411. data/lib/graphql/schema/validation.rb +0 -164
  412. data/lib/graphql/static_validation/arguments_validator.rb +0 -48
  413. data/lib/graphql/static_validation/message.rb +0 -36
  414. data/lib/graphql/string_type.rb +0 -5
  415. data/lib/graphql/union_type.rb +0 -38
  416. data/spec/graphql/analysis/analyze_query_spec.rb +0 -50
  417. data/spec/graphql/analysis/max_query_complexity_spec.rb +0 -62
  418. data/spec/graphql/analysis/max_query_depth_spec.rb +0 -100
  419. data/spec/graphql/analysis/query_complexity_spec.rb +0 -235
  420. data/spec/graphql/analysis/query_depth_spec.rb +0 -80
  421. data/spec/graphql/argument_spec.rb +0 -20
  422. data/spec/graphql/base_type_spec.rb +0 -24
  423. data/spec/graphql/boolean_type_spec.rb +0 -20
  424. data/spec/graphql/define/instance_definable_spec.rb +0 -55
  425. data/spec/graphql/directive_spec.rb +0 -77
  426. data/spec/graphql/enum_type_spec.rb +0 -31
  427. data/spec/graphql/execution_error_spec.rb +0 -61
  428. data/spec/graphql/field_spec.rb +0 -92
  429. data/spec/graphql/float_type_spec.rb +0 -15
  430. data/spec/graphql/id_type_spec.rb +0 -32
  431. data/spec/graphql/input_object_type_spec.rb +0 -162
  432. data/spec/graphql/int_type_spec.rb +0 -15
  433. data/spec/graphql/interface_type_spec.rb +0 -56
  434. data/spec/graphql/internal_representation/rewrite_spec.rb +0 -120
  435. data/spec/graphql/introspection/directive_type_spec.rb +0 -50
  436. data/spec/graphql/introspection/input_value_type_spec.rb +0 -42
  437. data/spec/graphql/introspection/introspection_query_spec.rb +0 -10
  438. data/spec/graphql/introspection/schema_type_spec.rb +0 -45
  439. data/spec/graphql/introspection/type_type_spec.rb +0 -122
  440. data/spec/graphql/language/generation_spec.rb +0 -42
  441. data/spec/graphql/language/parser_spec.rb +0 -442
  442. data/spec/graphql/language/visitor_spec.rb +0 -49
  443. data/spec/graphql/list_type_spec.rb +0 -32
  444. data/spec/graphql/non_null_type_spec.rb +0 -31
  445. data/spec/graphql/object_type_spec.rb +0 -42
  446. data/spec/graphql/query/arguments_spec.rb +0 -25
  447. data/spec/graphql/query/context_spec.rb +0 -83
  448. data/spec/graphql/query/executor_spec.rb +0 -273
  449. data/spec/graphql/query/serial_execution/execution_context_spec.rb +0 -53
  450. data/spec/graphql/query/serial_execution/value_resolution_spec.rb +0 -66
  451. data/spec/graphql/query/type_resolver_spec.rb +0 -8
  452. data/spec/graphql/query/variables_spec.rb +0 -28
  453. data/spec/graphql/query_spec.rb +0 -363
  454. data/spec/graphql/scalar_type_spec.rb +0 -61
  455. data/spec/graphql/schema/catchall_middleware_spec.rb +0 -32
  456. data/spec/graphql/schema/middleware_chain_spec.rb +0 -42
  457. data/spec/graphql/schema/printer_spec.rb +0 -190
  458. data/spec/graphql/schema/reduce_types_spec.rb +0 -102
  459. data/spec/graphql/schema/rescue_middleware_spec.rb +0 -33
  460. data/spec/graphql/schema/timeout_middleware_spec.rb +0 -180
  461. data/spec/graphql/schema/type_expression_spec.rb +0 -38
  462. data/spec/graphql/schema/validation_spec.rb +0 -219
  463. data/spec/graphql/schema_spec.rb +0 -23
  464. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +0 -63
  465. data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +0 -48
  466. data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +0 -34
  467. data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +0 -39
  468. data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +0 -60
  469. data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +0 -31
  470. data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +0 -48
  471. data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +0 -47
  472. data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +0 -39
  473. data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +0 -44
  474. data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +0 -49
  475. data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +0 -25
  476. data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +0 -42
  477. data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +0 -44
  478. data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +0 -63
  479. data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +0 -37
  480. data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +0 -53
  481. data/spec/graphql/static_validation/type_stack_spec.rb +0 -37
  482. data/spec/graphql/static_validation/validator_spec.rb +0 -69
  483. data/spec/graphql/string_type_spec.rb +0 -15
  484. data/spec/graphql/union_type_spec.rb +0 -31
  485. data/spec/spec_helper.rb +0 -18
  486. data/spec/support/dairy_app.rb +0 -309
  487. data/spec/support/dairy_data.rb +0 -23
  488. data/spec/support/minimum_input_object.rb +0 -16
  489. data/spec/support/star_wars_data.rb +0 -71
  490. data/spec/support/star_wars_schema.rb +0 -76
@@ -1,16 +1,64 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  module StaticValidation
3
- class ArgumentLiteralsAreCompatible < GraphQL::StaticValidation::ArgumentsValidator
4
- def validate_node(parent, node, defn, context)
5
- return if node.value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
6
- validator = GraphQL::StaticValidation::LiteralValidator.new
7
- arg_defn = defn.arguments[node.name]
8
- return unless arg_defn
9
- valid = validator.validate(node.value, arg_defn.type)
10
- if !valid
11
- kind_of_node = node_type(parent)
12
- error_arg_name = parent_name(parent, defn)
13
- context.errors << message("Argument '#{node.name}' on #{kind_of_node} '#{error_arg_name}' has an invalid value", parent)
4
+ module ArgumentLiteralsAreCompatible
5
+ def on_argument(node, parent)
6
+ # Check the child arguments first;
7
+ # don't add a new error if one of them reports an error
8
+ super
9
+
10
+ # Don't validate variables here
11
+ if node.value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
12
+ return
13
+ end
14
+
15
+ if @context.schema.error_bubbling || context.errors.none? { |err| err.path.take(@path.size) == @path }
16
+ parent_defn = parent_definition(parent)
17
+
18
+ if parent_defn && (arg_defn = context.warden.get_argument(parent_defn, node.name))
19
+ validation_result = context.validate_literal(node.value, arg_defn.type)
20
+ if !validation_result.valid?
21
+ kind_of_node = node_type(parent)
22
+ error_arg_name = parent_name(parent, parent_defn)
23
+ string_value = if node.value == Float::INFINITY
24
+ ""
25
+ else
26
+ " (#{GraphQL::Language::Printer.new.print(node.value)})"
27
+ end
28
+
29
+ problems = validation_result.problems
30
+ first_problem = problems && problems.first
31
+ if first_problem
32
+ message = first_problem["message"]
33
+ # This is some legacy stuff from when `CoercionError` was raised thru the stack
34
+ if message
35
+ coerce_extensions = first_problem["extensions"] || {
36
+ "code" => "argumentLiteralsIncompatible"
37
+ }
38
+ end
39
+ end
40
+
41
+ error_options = {
42
+ nodes: parent,
43
+ type: kind_of_node,
44
+ argument_name: node.name,
45
+ argument: arg_defn,
46
+ value: node.value
47
+ }
48
+ if coerce_extensions
49
+ error_options[:coerce_extensions] = coerce_extensions
50
+ end
51
+
52
+ message ||= "Argument '#{node.name}' on #{kind_of_node} '#{error_arg_name}' has an invalid value#{string_value}. Expected type '#{arg_defn.type.to_type_signature}'."
53
+
54
+ error = GraphQL::StaticValidation::ArgumentLiteralsAreCompatibleError.new(
55
+ message,
56
+ **error_options
57
+ )
58
+
59
+ add_error(error)
60
+ end
61
+ end
14
62
  end
15
63
  end
16
64
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ module StaticValidation
4
+ class ArgumentLiteralsAreCompatibleError < StaticValidation::Error
5
+ attr_reader :type_name
6
+ attr_reader :argument_name
7
+ attr_reader :argument
8
+ attr_reader :value
9
+
10
+ def initialize(message, path: nil, nodes: [], type:, argument_name: nil, extensions: nil, coerce_extensions: nil, argument: nil, value: nil)
11
+ super(message, path: path, nodes: nodes)
12
+ @type_name = type
13
+ @argument_name = argument_name
14
+ @extensions = extensions
15
+ @coerce_extensions = coerce_extensions
16
+ @argument = argument
17
+ @value = value
18
+ end
19
+
20
+ # A hash representation of this Message
21
+ def to_h
22
+ if @coerce_extensions
23
+ extensions = @coerce_extensions
24
+ # This is for legacy compat -- but this key is supposed to be a GraphQL type name :confounded:
25
+ extensions["typeName"] = "CoercionError"
26
+ else
27
+ extensions = {
28
+ "code" => code,
29
+ "typeName" => type_name
30
+ }
31
+
32
+ if argument_name
33
+ extensions["argumentName"] = argument_name
34
+ end
35
+ end
36
+
37
+ extensions.merge!(@extensions) unless @extensions.nil?
38
+ super.merge({
39
+ "extensions" => extensions
40
+ })
41
+ end
42
+
43
+ def code
44
+ "argumentLiteralsIncompatible"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ module StaticValidation
4
+ module ArgumentNamesAreUnique
5
+ include GraphQL::StaticValidation::Error::ErrorHelper
6
+
7
+ def on_field(node, parent)
8
+ validate_arguments(node)
9
+ super
10
+ end
11
+
12
+ def on_directive(node, parent)
13
+ validate_arguments(node)
14
+ super
15
+ end
16
+
17
+ def validate_arguments(node)
18
+ argument_defns = node.arguments
19
+ if argument_defns.any?
20
+ args_by_name = Hash.new { |h, k| h[k] = [] }
21
+ argument_defns.each { |a| args_by_name[a.name] << a }
22
+ args_by_name.each do |name, defns|
23
+ if defns.size > 1
24
+ add_error(GraphQL::StaticValidation::ArgumentNamesAreUniqueError.new("There can be only one argument named \"#{name}\"", nodes: defns, name: name))
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ module StaticValidation
4
+ class ArgumentNamesAreUniqueError < StaticValidation::Error
5
+ attr_reader :name
6
+
7
+ def initialize(message, path: nil, nodes: [], name:)
8
+ super(message, path: path, nodes: nodes)
9
+ @name = name
10
+ end
11
+
12
+ # A hash representation of this Message
13
+ def to_h
14
+ extensions = {
15
+ "code" => code,
16
+ "name" => name
17
+ }
18
+
19
+ super.merge({
20
+ "extensions" => extensions
21
+ })
22
+ end
23
+
24
+ def code
25
+ "argumentNotUnique"
26
+ end
27
+ end
28
+ end
29
+ end
30
+
@@ -1,15 +1,69 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  module StaticValidation
3
- class ArgumentsAreDefined < GraphQL::StaticValidation::ArgumentsValidator
4
- def validate_node(parent, node, defn, context)
5
- argument_defn = defn.arguments[node.name]
6
- if argument_defn.nil?
4
+ module ArgumentsAreDefined
5
+ def on_argument(node, parent)
6
+ parent_defn = parent_definition(parent)
7
+
8
+ if parent_defn && context.warden.get_argument(parent_defn, node.name)
9
+ super
10
+ elsif parent_defn
7
11
  kind_of_node = node_type(parent)
8
- error_arg_name = parent_name(parent, defn)
9
- context.errors << message("#{kind_of_node} '#{error_arg_name}' doesn't accept argument '#{node.name}'", parent)
10
- GraphQL::Language::Visitor::SKIP
12
+ error_arg_name = parent_name(parent, parent_defn)
13
+ add_error(GraphQL::StaticValidation::ArgumentsAreDefinedError.new(
14
+ "#{kind_of_node} '#{error_arg_name}' doesn't accept argument '#{node.name}'",
15
+ nodes: node,
16
+ name: error_arg_name,
17
+ type: kind_of_node,
18
+ argument_name: node.name,
19
+ parent: parent_defn
20
+ ))
11
21
  else
12
- nil
22
+ # Some other weird error
23
+ super
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ # TODO smell: these methods are added to all visitors, since they're included in a module.
30
+ def parent_name(parent, type_defn)
31
+ case parent
32
+ when GraphQL::Language::Nodes::Field
33
+ parent.alias || parent.name
34
+ when GraphQL::Language::Nodes::InputObject
35
+ type_defn.graphql_name
36
+ when GraphQL::Language::Nodes::Argument, GraphQL::Language::Nodes::Directive
37
+ parent.name
38
+ else
39
+ raise "Invariant: Unexpected parent #{parent.inspect} (#{parent.class})"
40
+ end
41
+ end
42
+
43
+ def node_type(parent)
44
+ parent.class.name.split("::").last
45
+ end
46
+
47
+ def parent_definition(parent)
48
+ case parent
49
+ when GraphQL::Language::Nodes::InputObject
50
+ arg_defn = context.argument_definition
51
+ if arg_defn.nil?
52
+ nil
53
+ else
54
+ arg_ret_type = arg_defn.type.unwrap
55
+ if arg_ret_type.kind.input_object?
56
+ arg_ret_type
57
+ else
58
+ nil
59
+ end
60
+ end
61
+ when GraphQL::Language::Nodes::Directive
62
+ context.schema_directives[parent.name]
63
+ when GraphQL::Language::Nodes::Field
64
+ context.field_definition
65
+ else
66
+ raise "Unexpected argument parent: #{parent.class} (##{parent})"
13
67
  end
14
68
  end
15
69
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ module StaticValidation
4
+ class ArgumentsAreDefinedError < StaticValidation::Error
5
+ attr_reader :name
6
+ attr_reader :type_name
7
+ attr_reader :argument_name
8
+ attr_reader :parent
9
+
10
+ def initialize(message, path: nil, nodes: [], name:, type:, argument_name:, parent:)
11
+ super(message, path: path, nodes: nodes)
12
+ @name = name
13
+ @type_name = type
14
+ @argument_name = argument_name
15
+ @parent = parent
16
+ end
17
+
18
+ # A hash representation of this Message
19
+ def to_h
20
+ extensions = {
21
+ "code" => code,
22
+ "name" => name,
23
+ "typeName" => type_name,
24
+ "argumentName" => argument_name
25
+ }
26
+
27
+ super.merge({
28
+ "extensions" => extensions
29
+ })
30
+ end
31
+
32
+ def code
33
+ "argumentNotAccepted"
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,20 +1,27 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  module StaticValidation
3
- class DirectivesAreDefined
4
- include GraphQL::StaticValidation::Message::MessageHelper
5
-
6
- def validate(context)
7
- directive_names = context.schema.directives.keys
8
- context.visitor[GraphQL::Language::Nodes::Directive] << -> (node, parent) {
9
- validate_directive(node, directive_names, context.errors)
10
- }
4
+ module DirectivesAreDefined
5
+ def initialize(*)
6
+ super
7
+ @directive_names = context.warden.directives.map(&:graphql_name)
11
8
  end
12
9
 
13
- private
14
-
15
- def validate_directive(ast_directive, directive_names, errors)
16
- if !directive_names.include?(ast_directive.name)
17
- errors << message("Directive @#{ast_directive.name} is not defined", ast_directive)
10
+ def on_directive(node, parent)
11
+ if !@directive_names.include?(node.name)
12
+ @directives_are_defined_errors_by_name ||= {}
13
+ error = @directives_are_defined_errors_by_name[node.name] ||= begin
14
+ err = GraphQL::StaticValidation::DirectivesAreDefinedError.new(
15
+ "Directive @#{node.name} is not defined",
16
+ nodes: [],
17
+ directive: node.name
18
+ )
19
+ add_error(err)
20
+ err
21
+ end
22
+ error.nodes << node
23
+ else
24
+ super
18
25
  end
19
26
  end
20
27
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ module StaticValidation
4
+ class DirectivesAreDefinedError < StaticValidation::Error
5
+ attr_reader :directive_name
6
+
7
+ def initialize(message, path: nil, nodes: [], directive:)
8
+ super(message, path: path, nodes: nodes)
9
+ @directive_name = directive
10
+ end
11
+
12
+ # A hash representation of this Message
13
+ def to_h
14
+ extensions = {
15
+ "code" => code,
16
+ "directiveName" => directive_name
17
+ }
18
+
19
+ super.merge({
20
+ "extensions" => extensions
21
+ })
22
+ end
23
+
24
+ def code
25
+ "undefinedDirective"
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,57 +1,63 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  module StaticValidation
3
- class DirectivesAreInValidLocations
4
- include GraphQL::StaticValidation::Message::MessageHelper
4
+ module DirectivesAreInValidLocations
5
5
  include GraphQL::Language
6
6
 
7
- def validate(context)
8
- directives = context.schema.directives
9
-
10
- context.visitor[Nodes::Directive] << -> (node, parent) {
11
- validate_location(node, parent, directives, context.errors)
12
- }
7
+ def on_directive(node, parent)
8
+ validate_location(node, parent, context.schema_directives)
9
+ super
13
10
  end
14
11
 
15
12
  private
16
13
 
17
14
  LOCATION_MESSAGE_NAMES = {
18
- GraphQL::Directive::QUERY => "queries",
19
- GraphQL::Directive::MUTATION => "mutations",
20
- GraphQL::Directive::SUBSCRIPTION => "subscriptions",
21
- GraphQL::Directive::FIELD => "fields",
22
- GraphQL::Directive::FRAGMENT_DEFINITION => "fragment definitions",
23
- GraphQL::Directive::FRAGMENT_SPREAD => "fragment spreads",
24
- GraphQL::Directive::INLINE_FRAGMENT => "inline fragments",
15
+ GraphQL::Schema::Directive::QUERY => "queries",
16
+ GraphQL::Schema::Directive::MUTATION => "mutations",
17
+ GraphQL::Schema::Directive::SUBSCRIPTION => "subscriptions",
18
+ GraphQL::Schema::Directive::FIELD => "fields",
19
+ GraphQL::Schema::Directive::FRAGMENT_DEFINITION => "fragment definitions",
20
+ GraphQL::Schema::Directive::FRAGMENT_SPREAD => "fragment spreads",
21
+ GraphQL::Schema::Directive::INLINE_FRAGMENT => "inline fragments",
25
22
  }
26
23
 
27
24
  SIMPLE_LOCATIONS = {
28
- Nodes::Field => GraphQL::Directive::FIELD,
29
- Nodes::InlineFragment => GraphQL::Directive::INLINE_FRAGMENT,
30
- Nodes::FragmentSpread => GraphQL::Directive::FRAGMENT_SPREAD,
31
- Nodes::FragmentDefinition => GraphQL::Directive::FRAGMENT_DEFINITION,
25
+ Nodes::Field => GraphQL::Schema::Directive::FIELD,
26
+ Nodes::InlineFragment => GraphQL::Schema::Directive::INLINE_FRAGMENT,
27
+ Nodes::FragmentSpread => GraphQL::Schema::Directive::FRAGMENT_SPREAD,
28
+ Nodes::FragmentDefinition => GraphQL::Schema::Directive::FRAGMENT_DEFINITION,
32
29
  }
33
30
 
34
31
  SIMPLE_LOCATION_NODES = SIMPLE_LOCATIONS.keys
35
32
 
36
- def validate_location(ast_directive, ast_parent, directives, errors)
33
+ def validate_location(ast_directive, ast_parent, directives)
37
34
  directive_defn = directives[ast_directive.name]
38
35
  case ast_parent
39
36
  when Nodes::OperationDefinition
40
- required_location = GraphQL::Directive.const_get(ast_parent.operation_type.upcase)
41
- assert_includes_location(directive_defn, ast_directive, required_location, errors)
37
+ required_location = GraphQL::Schema::Directive.const_get(ast_parent.operation_type.upcase)
38
+ assert_includes_location(directive_defn, ast_directive, required_location)
42
39
  when *SIMPLE_LOCATION_NODES
43
40
  required_location = SIMPLE_LOCATIONS[ast_parent.class]
44
- assert_includes_location(directive_defn, ast_directive, required_location, errors)
41
+ assert_includes_location(directive_defn, ast_directive, required_location)
45
42
  else
46
- errors << message("Directives can't be applied to #{ast_parent.class.name}s", ast_directive)
43
+ add_error(GraphQL::StaticValidation::DirectivesAreInValidLocationsError.new(
44
+ "Directives can't be applied to #{ast_parent.class.name}s",
45
+ nodes: ast_directive,
46
+ target: ast_parent.class.name
47
+ ))
47
48
  end
48
49
  end
49
50
 
50
- def assert_includes_location(directive_defn, directive_ast, required_location, errors)
51
+ def assert_includes_location(directive_defn, directive_ast, required_location)
51
52
  if !directive_defn.locations.include?(required_location)
52
53
  location_name = LOCATION_MESSAGE_NAMES[required_location]
53
54
  allowed_location_names = directive_defn.locations.map { |loc| LOCATION_MESSAGE_NAMES[loc] }
54
- errors << message("'@#{directive_defn.name}' can't be applied to #{location_name} (allowed: #{allowed_location_names.join(", ")})", directive_ast)
55
+ add_error(GraphQL::StaticValidation::DirectivesAreInValidLocationsError.new(
56
+ "'@#{directive_defn.graphql_name}' can't be applied to #{location_name} (allowed: #{allowed_location_names.join(", ")})",
57
+ nodes: directive_ast,
58
+ target: location_name,
59
+ name: directive_defn.graphql_name
60
+ ))
55
61
  end
56
62
  end
57
63
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ module StaticValidation
4
+ class DirectivesAreInValidLocationsError < StaticValidation::Error
5
+ attr_reader :target_name
6
+ attr_reader :name
7
+
8
+ def initialize(message, path: nil, nodes: [], target:, name: nil)
9
+ super(message, path: path, nodes: nodes)
10
+ @target_name = target
11
+ @name = name
12
+ end
13
+
14
+ # A hash representation of this Message
15
+ def to_h
16
+ extensions = {
17
+ "code" => code,
18
+ "targetName" => target_name
19
+ }.tap { |h| h["name"] = name unless name.nil? }
20
+
21
+ super.merge({
22
+ "extensions" => extensions
23
+ })
24
+ end
25
+
26
+ def code
27
+ "directiveCannotBeApplied"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,30 +1,28 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  module StaticValidation
3
- class FieldsAreDefinedOnType
4
- include GraphQL::StaticValidation::Message::MessageHelper
4
+ module FieldsAreDefinedOnType
5
+ def on_field(node, parent)
6
+ parent_type = @object_types[-2]
7
+ field = context.warden.get_field(parent_type, node.name)
5
8
 
6
- def validate(context)
7
- visitor = context.visitor
8
- visitor[GraphQL::Language::Nodes::Field] << -> (node, parent) {
9
- return if context.skip_field?(node.name)
10
- parent_type = context.object_types[-2]
11
- parent_type = parent_type.unwrap
12
- validate_field(context.errors, node, parent_type, parent)
13
- }
14
- end
15
-
16
- private
17
-
18
- def validate_field(errors, ast_field, parent_type, parent)
19
- if parent_type.kind.union?
20
- errors << message("Selections can't be made directly on unions (see selections on #{parent_type.name})", parent)
21
- return GraphQL::Language::Visitor::SKIP
22
- end
23
-
24
- field = parent_type.get_field(ast_field.name)
25
9
  if field.nil?
26
- errors << message("Field '#{ast_field.name}' doesn't exist on type '#{parent_type.name}'", parent)
27
- return GraphQL::Language::Visitor::SKIP
10
+ if parent_type.kind.union?
11
+ add_error(GraphQL::StaticValidation::FieldsHaveAppropriateSelectionsError.new(
12
+ "Selections can't be made directly on unions (see selections on #{parent_type.graphql_name})",
13
+ nodes: parent,
14
+ node_name: parent_type.graphql_name
15
+ ))
16
+ else
17
+ add_error(GraphQL::StaticValidation::FieldsAreDefinedOnTypeError.new(
18
+ "Field '#{node.name}' doesn't exist on type '#{parent_type.graphql_name}'",
19
+ nodes: node,
20
+ field: node.name,
21
+ type: parent_type.graphql_name
22
+ ))
23
+ end
24
+ else
25
+ super
28
26
  end
29
27
  end
30
28
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ module StaticValidation
4
+ class FieldsAreDefinedOnTypeError < StaticValidation::Error
5
+ attr_reader :type_name
6
+ attr_reader :field_name
7
+
8
+ def initialize(message, path: nil, nodes: [], type:, field:)
9
+ super(message, path: path, nodes: nodes)
10
+ @type_name = type
11
+ @field_name = field
12
+ end
13
+
14
+ # A hash representation of this Message
15
+ def to_h
16
+ extensions = {
17
+ "code" => code,
18
+ "typeName" => type_name,
19
+ "fieldName" => field_name
20
+ }
21
+
22
+ super.merge({
23
+ "extensions" => extensions
24
+ })
25
+ end
26
+
27
+ def code
28
+ "undefinedField"
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,34 +1,71 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  module StaticValidation
3
4
  # Scalars _can't_ have selections
4
5
  # Objects _must_ have selections
5
- class FieldsHaveAppropriateSelections
6
- include GraphQL::StaticValidation::Message::MessageHelper
6
+ module FieldsHaveAppropriateSelections
7
+ include GraphQL::StaticValidation::Error::ErrorHelper
7
8
 
8
- def validate(context)
9
- context.visitor[GraphQL::Language::Nodes::Field] << -> (node, parent) {
10
- return if context.skip_field?(node.name)
11
- field_defn = context.field_definition
12
- validate_field_selections(node, field_defn, context.errors)
13
- }
9
+ def on_field(node, parent)
10
+ field_defn = field_definition
11
+ if validate_field_selections(node, field_defn.type.unwrap)
12
+ super
13
+ end
14
+ end
15
+
16
+ def on_operation_definition(node, _parent)
17
+ if validate_field_selections(node, type_definition)
18
+ super
19
+ end
14
20
  end
15
21
 
16
22
  private
17
23
 
18
- def validate_field_selections(ast_field, field_defn, errors)
19
- resolved_type = field_defn.type.unwrap
20
24
 
21
- if resolved_type.kind.scalar? && ast_field.selections.any?
22
- error = message("Selections can't be made on scalars (field '#{ast_field.name}' returns #{resolved_type.name} but has selections [#{ast_field.selections.map(&:name).join(", ")}])", ast_field)
23
- elsif resolved_type.kind.object? && ast_field.selections.none?
24
- error = message("Objects must have selections (field '#{ast_field.name}' returns #{resolved_type.name} but has no selections)", ast_field)
25
+ def validate_field_selections(ast_node, resolved_type)
26
+ msg = if resolved_type.nil?
27
+ nil
28
+ elsif resolved_type.kind.scalar? && ast_node.selections.any?
29
+ if ast_node.selections.first.is_a?(GraphQL::Language::Nodes::InlineFragment)
30
+ "Selections can't be made on scalars (%{node_name} returns #{resolved_type.graphql_name} but has inline fragments [#{ast_node.selections.map(&:type).map(&:name).join(", ")}])"
31
+ else
32
+ "Selections can't be made on scalars (%{node_name} returns #{resolved_type.graphql_name} but has selections [#{ast_node.selections.map(&:name).join(", ")}])"
33
+ end
34
+ elsif resolved_type.kind.fields? && ast_node.selections.empty?
35
+ "Field must have selections (%{node_name} returns #{resolved_type.graphql_name} but has no selections. Did you mean '#{ast_node.name} { ... }'?)"
25
36
  else
26
- error = nil
37
+ nil
27
38
  end
28
39
 
29
- if !error.nil?
30
- errors << error
31
- GraphQL::Language::Visitor::SKIP
40
+ if msg
41
+ node_name = case ast_node
42
+ when GraphQL::Language::Nodes::Field
43
+ "field '#{ast_node.name}'"
44
+ when GraphQL::Language::Nodes::OperationDefinition
45
+ if ast_node.name.nil?
46
+ "anonymous query"
47
+ else
48
+ "#{ast_node.operation_type} '#{ast_node.name}'"
49
+ end
50
+ else
51
+ raise("Unexpected node #{ast_node}")
52
+ end
53
+ extensions = {
54
+ "rule": "StaticValidation::FieldsHaveAppropriateSelections",
55
+ "name": node_name.to_s
56
+ }
57
+ unless resolved_type.nil?
58
+ extensions["type"] = resolved_type.to_type_signature
59
+ end
60
+ add_error(GraphQL::StaticValidation::FieldsHaveAppropriateSelectionsError.new(
61
+ msg % { node_name: node_name },
62
+ nodes: ast_node,
63
+ node_name: node_name.to_s,
64
+ type: resolved_type.nil? ? nil : resolved_type.graphql_name,
65
+ ))
66
+ false
67
+ else
68
+ true
32
69
  end
33
70
  end
34
71
  end