graphql 1.8.7 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (368) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/install_generator.rb +2 -1
  3. data/lib/generators/graphql/scalar_generator.rb +20 -0
  4. data/lib/generators/graphql/templates/base_scalar.erb +4 -0
  5. data/lib/generators/graphql/templates/scalar.erb +13 -0
  6. data/lib/graphql/analysis/ast/analyzer.rb +62 -0
  7. data/lib/graphql/analysis/ast/field_usage.rb +28 -0
  8. data/lib/graphql/analysis/ast/max_query_complexity.rb +23 -0
  9. data/lib/graphql/analysis/ast/max_query_depth.rb +18 -0
  10. data/lib/graphql/analysis/ast/query_complexity.rb +114 -0
  11. data/lib/graphql/analysis/ast/query_depth.rb +66 -0
  12. data/lib/graphql/analysis/ast/visitor.rb +255 -0
  13. data/lib/graphql/analysis/ast.rb +82 -0
  14. data/lib/graphql/analysis.rb +1 -0
  15. data/lib/graphql/argument.rb +5 -0
  16. data/lib/graphql/authorization.rb +1 -0
  17. data/lib/graphql/backwards_compatibility.rb +1 -1
  18. data/lib/graphql/base_type.rb +1 -1
  19. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +1 -2
  20. data/lib/graphql/compatibility/schema_parser_specification.rb +2 -6
  21. data/lib/graphql/dig.rb +19 -0
  22. data/lib/graphql/directive/include_directive.rb +1 -7
  23. data/lib/graphql/directive/skip_directive.rb +1 -8
  24. data/lib/graphql/directive.rb +13 -1
  25. data/lib/graphql/enum_type.rb +8 -0
  26. data/lib/graphql/execution/execute.rb +36 -17
  27. data/lib/graphql/execution/instrumentation.rb +2 -0
  28. data/lib/graphql/execution/interpreter/execution_errors.rb +29 -0
  29. data/lib/graphql/execution/interpreter/hash_response.rb +46 -0
  30. data/lib/graphql/execution/interpreter/resolve.rb +58 -0
  31. data/lib/graphql/execution/interpreter/runtime.rb +597 -0
  32. data/lib/graphql/execution/interpreter.rb +99 -0
  33. data/lib/graphql/execution/lazy.rb +8 -1
  34. data/lib/graphql/execution/lookahead.rb +351 -0
  35. data/lib/graphql/execution/multiplex.rb +37 -29
  36. data/lib/graphql/execution.rb +2 -0
  37. data/lib/graphql/execution_error.rb +1 -1
  38. data/lib/graphql/field.rb +1 -7
  39. data/lib/graphql/integer_encoding_error.rb +12 -0
  40. data/lib/graphql/internal_representation/rewrite.rb +127 -142
  41. data/lib/graphql/introspection/dynamic_fields.rb +8 -2
  42. data/lib/graphql/introspection/entry_points.rb +11 -6
  43. data/lib/graphql/introspection/enum_value_type.rb +4 -0
  44. data/lib/graphql/introspection/schema_type.rb +7 -2
  45. data/lib/graphql/introspection/type_type.rb +9 -5
  46. data/lib/graphql/invalid_null_error.rb +1 -1
  47. data/lib/graphql/language/block_string.rb +37 -0
  48. data/lib/graphql/language/document_from_schema_definition.rb +10 -7
  49. data/lib/graphql/language/lexer.rb +55 -36
  50. data/lib/graphql/language/lexer.rl +8 -3
  51. data/lib/graphql/language/nodes.rb +440 -362
  52. data/lib/graphql/language/parser.rb +56 -56
  53. data/lib/graphql/language/parser.y +12 -12
  54. data/lib/graphql/language/printer.rb +2 -2
  55. data/lib/graphql/language/visitor.rb +158 -15
  56. data/lib/graphql/language.rb +0 -1
  57. data/lib/graphql/literal_validation_error.rb +6 -0
  58. data/lib/graphql/query/arguments.rb +3 -2
  59. data/lib/graphql/query/arguments_cache.rb +1 -1
  60. data/lib/graphql/query/context.rb +14 -5
  61. data/lib/graphql/query/executor.rb +1 -1
  62. data/lib/graphql/query/result.rb +1 -1
  63. data/lib/graphql/query/validation_pipeline.rb +35 -11
  64. data/lib/graphql/query/variable_validation_error.rb +10 -1
  65. data/lib/graphql/query.rb +16 -2
  66. data/lib/graphql/relay/base_connection.rb +2 -0
  67. data/lib/graphql/relay/connection_instrumentation.rb +3 -1
  68. data/lib/graphql/relay/connection_resolve.rb +1 -1
  69. data/lib/graphql/relay/node.rb +2 -28
  70. data/lib/graphql/relay/relation_connection.rb +1 -1
  71. data/lib/graphql/schema/argument.rb +13 -5
  72. data/lib/graphql/schema/base_64_encoder.rb +4 -4
  73. data/lib/graphql/schema/build_from_definition.rb +2 -4
  74. data/lib/graphql/schema/default_type_error.rb +1 -1
  75. data/lib/graphql/schema/directive/feature.rb +66 -0
  76. data/lib/graphql/schema/directive/include.rb +25 -0
  77. data/lib/graphql/schema/directive/skip.rb +25 -0
  78. data/lib/graphql/schema/directive/transform.rb +48 -0
  79. data/lib/graphql/schema/directive.rb +103 -0
  80. data/lib/graphql/schema/enum_value.rb +3 -2
  81. data/lib/graphql/schema/field/connection_extension.rb +50 -0
  82. data/lib/graphql/schema/field/scope_extension.rb +18 -0
  83. data/lib/graphql/schema/field.rb +273 -64
  84. data/lib/graphql/schema/field_extension.rb +69 -0
  85. data/lib/graphql/schema/input_object.rb +16 -8
  86. data/lib/graphql/schema/interface.rb +1 -0
  87. data/lib/graphql/schema/loader.rb +22 -16
  88. data/lib/graphql/schema/member/base_dsl_methods.rb +8 -2
  89. data/lib/graphql/schema/member/build_type.rb +33 -1
  90. data/lib/graphql/schema/member/has_arguments.rb +6 -2
  91. data/lib/graphql/schema/member/has_fields.rb +18 -70
  92. data/lib/graphql/schema/member/has_path.rb +25 -0
  93. data/lib/graphql/schema/member/instrumentation.rb +10 -7
  94. data/lib/graphql/schema/member.rb +2 -0
  95. data/lib/graphql/schema/mutation.rb +6 -48
  96. data/lib/graphql/schema/non_null.rb +5 -1
  97. data/lib/graphql/schema/object.rb +18 -4
  98. data/lib/graphql/schema/printer.rb +1 -1
  99. data/lib/graphql/schema/relay_classic_mutation.rb +42 -9
  100. data/lib/graphql/schema/resolver/has_payload_type.rb +65 -0
  101. data/lib/graphql/schema/resolver.rb +45 -20
  102. data/lib/graphql/schema/subscription.rb +97 -0
  103. data/lib/graphql/schema/traversal.rb +11 -7
  104. data/lib/graphql/schema.rb +186 -38
  105. data/lib/graphql/static_validation/all_rules.rb +3 -2
  106. data/lib/graphql/static_validation/base_visitor.rb +199 -0
  107. data/lib/graphql/static_validation/default_visitor.rb +15 -0
  108. data/lib/graphql/static_validation/definition_dependencies.rb +62 -68
  109. data/lib/graphql/static_validation/{message.rb → error.rb} +11 -11
  110. data/lib/graphql/static_validation/interpreter_visitor.rb +14 -0
  111. data/lib/graphql/static_validation/literal_validator.rb +54 -11
  112. data/lib/graphql/static_validation/no_validate_visitor.rb +10 -0
  113. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +87 -16
  114. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +31 -0
  115. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +11 -11
  116. data/lib/graphql/static_validation/rules/argument_names_are_unique_error.rb +30 -0
  117. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +52 -8
  118. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +35 -0
  119. data/lib/graphql/static_validation/rules/directives_are_defined.rb +12 -15
  120. data/lib/graphql/static_validation/rules/directives_are_defined_error.rb +29 -0
  121. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +19 -14
  122. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations_error.rb +31 -0
  123. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +17 -19
  124. data/lib/graphql/static_validation/rules/fields_are_defined_on_type_error.rb +32 -0
  125. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +30 -14
  126. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections_error.rb +31 -0
  127. data/lib/graphql/static_validation/rules/fields_will_merge.rb +356 -29
  128. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +32 -0
  129. data/lib/graphql/static_validation/rules/fragment_names_are_unique.rb +20 -13
  130. data/lib/graphql/static_validation/rules/fragment_names_are_unique_error.rb +29 -0
  131. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +37 -29
  132. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible_error.rb +35 -0
  133. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +25 -17
  134. data/lib/graphql/static_validation/rules/fragment_types_exist_error.rb +29 -0
  135. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +12 -10
  136. data/lib/graphql/static_validation/rules/fragments_are_finite_error.rb +29 -0
  137. data/lib/graphql/static_validation/rules/fragments_are_named.rb +7 -11
  138. data/lib/graphql/static_validation/rules/fragments_are_named_error.rb +26 -0
  139. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +16 -16
  140. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types_error.rb +30 -0
  141. data/lib/graphql/static_validation/rules/fragments_are_used.rb +21 -14
  142. data/lib/graphql/static_validation/rules/fragments_are_used_error.rb +29 -0
  143. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +10 -14
  144. data/lib/graphql/static_validation/rules/mutation_root_exists_error.rb +26 -0
  145. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +30 -30
  146. data/lib/graphql/static_validation/rules/no_definitions_are_present_error.rb +25 -0
  147. data/lib/graphql/static_validation/rules/operation_names_are_valid.rb +25 -17
  148. data/lib/graphql/static_validation/rules/operation_names_are_valid_error.rb +28 -0
  149. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +17 -18
  150. data/lib/graphql/static_validation/rules/required_arguments_are_present_error.rb +35 -0
  151. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +47 -0
  152. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present_error.rb +35 -0
  153. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +10 -14
  154. data/lib/graphql/static_validation/rules/subscription_root_exists_error.rb +26 -0
  155. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +28 -17
  156. data/lib/graphql/static_validation/rules/unique_directives_per_location_error.rb +29 -0
  157. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +35 -27
  158. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed_error.rb +39 -0
  159. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +15 -14
  160. data/lib/graphql/static_validation/rules/variable_names_are_unique_error.rb +29 -0
  161. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +41 -30
  162. data/lib/graphql/static_validation/rules/variable_usages_are_allowed_error.rb +38 -0
  163. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +18 -14
  164. data/lib/graphql/static_validation/rules/variables_are_input_types_error.rb +32 -0
  165. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +73 -65
  166. data/lib/graphql/static_validation/rules/variables_are_used_and_defined_error.rb +37 -0
  167. data/lib/graphql/static_validation/validation_context.rb +8 -51
  168. data/lib/graphql/static_validation/validator.rb +23 -15
  169. data/lib/graphql/static_validation.rb +5 -3
  170. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +21 -2
  171. data/lib/graphql/subscriptions/event.rb +28 -5
  172. data/lib/graphql/subscriptions/subscription_root.rb +66 -0
  173. data/lib/graphql/subscriptions.rb +16 -2
  174. data/lib/graphql/tracing/active_support_notifications_tracing.rb +0 -1
  175. data/lib/graphql/tracing/appsignal_tracing.rb +1 -1
  176. data/lib/graphql/tracing/data_dog_tracing.rb +1 -1
  177. data/lib/graphql/tracing/new_relic_tracing.rb +3 -3
  178. data/lib/graphql/tracing/platform_tracing.rb +17 -1
  179. data/lib/graphql/tracing/prometheus_tracing.rb +1 -1
  180. data/lib/graphql/tracing/scout_tracing.rb +1 -1
  181. data/lib/graphql/tracing/skylight_tracing.rb +3 -3
  182. data/lib/graphql/tracing.rb +8 -8
  183. data/lib/graphql/types/float.rb +1 -1
  184. data/lib/graphql/types/int.rb +11 -2
  185. data/lib/graphql/types/iso_8601_date_time.rb +15 -1
  186. data/lib/graphql/types/relay/base_connection.rb +15 -1
  187. data/lib/graphql/types/relay/node.rb +0 -1
  188. data/lib/graphql/types/relay/node_field.rb +43 -0
  189. data/lib/graphql/types/relay/nodes_field.rb +45 -0
  190. data/lib/graphql/types/relay.rb +2 -0
  191. data/lib/graphql/unauthorized_error.rb +4 -0
  192. data/lib/graphql/unauthorized_field_error.rb +23 -0
  193. data/lib/graphql/upgrader/member.rb +5 -0
  194. data/lib/graphql/version.rb +1 -1
  195. data/lib/graphql.rb +6 -1
  196. data/readme.md +7 -7
  197. data/spec/dummy/Gemfile +1 -1
  198. data/spec/dummy/Gemfile.lock +157 -0
  199. data/spec/dummy/app/channels/graphql_channel.rb +22 -11
  200. data/spec/dummy/config/locales/en.yml +1 -1
  201. data/spec/dummy/log/test.log +199 -0
  202. data/spec/dummy/test/test_helper.rb +1 -0
  203. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4w/4wzXRZrAkwKdgYaSE0pid5eB-fer8vSfSku_NPg4rMA.cache +0 -0
  204. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7I/7IHVBiJT06QSpgLpLoJIxboQ0B-D_tMTxsvoezBTV3Q.cache +1 -0
  205. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8w/8wY_SKagj8wHuwGNAAf6JnQ8joMbC6cEYpHrTAI8Urc.cache +1 -0
  206. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/AK/AKzz1u6bGb4auXcrObA_g5LL-oV0ejNGa448AgAi_WQ.cache +1 -0
  207. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ET/ETW4uxvaYpruL8y6_ZptUH82ZowMaHIqvg5WexBFdEM.cache +3 -0
  208. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F1/F1TWpjjyA56k9Z90n5B3xRn7DUdGjX73QCkYC6k07JQ.cache +0 -0
  209. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F8/F8MUNRzORGFgr329fNM0xLaoWCXdv3BIalT7dsvLfjs.cache +2 -0
  210. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/KB/KB07ZaKNC5uXJ7TjLi-WqnY6g7dq8wWp_8N3HNjBNxg.cache +2 -0
  211. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ms/MsKSimH_UCB-H1tLvDABDHuvGciuoW6kVqQWDrXU5FQ.cache +0 -0
  212. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Mt/Mtci-Kim50aPOmeClD4AIicKn1d1WJ0n454IjSd94sk.cache +0 -0
  213. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/QH/QHt3Tc1Y6M66Oo_pDuMyWrQNs4Pp3SMeZR5K1wJj2Ts.cache +1 -0
  214. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/XU/XU4k1OXnfMils5SrirorPvDSyDSqiOWLZNtmAH1HH8k.cache +0 -0
  215. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ZI/ZIof7mZxWWCnraIFOCuV6a8QRWzKJXJnx2Xd7C0ZyX0.cache +1 -0
  216. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/cG/cGc_puuPS5pZKgUcy1Y_i1L6jl5UtsiIrMH59rTzR6c.cache +3 -0
  217. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/df/dfro_B6bx3KP1Go-7jEOqqZ2j4hVRseXIc3es9PKQno.cache +1 -0
  218. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jO/jO1DfbqnG0mTULsjJJANc3fefrG2zt7DIMmcptMT628.cache +1 -0
  219. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/pE/pE7gO6pQ-z187Swb4hT554wmqsq-cNzgPWLrCz-LQQQ.cache +0 -0
  220. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/r9/r9iU1l58a6rxkZSW5RSC52_tD-_UQuHxoMVnkfJ7Mhs.cache +1 -0
  221. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xi/xitPPFfPIyDMpaznV0sBBcw8eSCV8PJcLLWin78sCgE.cache +0 -0
  222. data/spec/dummy/tmp/screenshots/failures_test_it_handles_subscriptions.png +0 -0
  223. data/spec/graphql/analysis/analyze_query_spec.rb +1 -1
  224. data/spec/graphql/analysis/ast/field_usage_spec.rb +51 -0
  225. data/spec/graphql/analysis/ast/max_query_complexity_spec.rb +120 -0
  226. data/spec/graphql/analysis/ast/max_query_depth_spec.rb +114 -0
  227. data/spec/graphql/analysis/ast/query_complexity_spec.rb +299 -0
  228. data/spec/graphql/analysis/ast/query_depth_spec.rb +108 -0
  229. data/spec/graphql/analysis/ast_spec.rb +269 -0
  230. data/spec/graphql/authorization_spec.rb +120 -23
  231. data/spec/graphql/base_type_spec.rb +6 -4
  232. data/spec/graphql/enum_type_spec.rb +6 -1
  233. data/spec/graphql/execution/execute_spec.rb +9 -9
  234. data/spec/graphql/execution/instrumentation_spec.rb +19 -0
  235. data/spec/graphql/execution/interpreter_spec.rb +485 -0
  236. data/spec/graphql/execution/lazy_spec.rb +67 -1
  237. data/spec/graphql/execution/lookahead_spec.rb +363 -0
  238. data/spec/graphql/execution/multiplex_spec.rb +31 -3
  239. data/spec/graphql/execution/typecast_spec.rb +20 -20
  240. data/spec/graphql/execution_error_spec.rb +110 -96
  241. data/spec/graphql/field_spec.rb +1 -1
  242. data/spec/graphql/input_object_type_spec.rb +13 -352
  243. data/spec/graphql/int_type_spec.rb +19 -0
  244. data/spec/graphql/interface_type_spec.rb +4 -4
  245. data/spec/graphql/internal_representation/rewrite_spec.rb +2 -0
  246. data/spec/graphql/introspection/input_value_type_spec.rb +1 -1
  247. data/spec/graphql/introspection/type_type_spec.rb +1 -2
  248. data/spec/graphql/language/document_from_schema_definition_spec.rb +2 -2
  249. data/spec/graphql/language/lexer_spec.rb +72 -3
  250. data/spec/graphql/language/nodes_spec.rb +20 -0
  251. data/spec/graphql/language/printer_spec.rb +18 -6
  252. data/spec/graphql/language/visitor_spec.rb +320 -14
  253. data/spec/graphql/non_null_type_spec.rb +1 -1
  254. data/spec/graphql/object_type_spec.rb +32 -27
  255. data/spec/graphql/query/arguments_spec.rb +21 -0
  256. data/spec/graphql/query/context_spec.rb +28 -0
  257. data/spec/graphql/query/executor_spec.rb +40 -36
  258. data/spec/graphql/query_spec.rb +12 -6
  259. data/spec/graphql/schema/argument_spec.rb +35 -1
  260. data/spec/graphql/schema/build_from_definition_spec.rb +144 -29
  261. data/spec/graphql/schema/catchall_middleware_spec.rb +16 -15
  262. data/spec/graphql/schema/directive/feature_spec.rb +81 -0
  263. data/spec/graphql/schema/directive/transform_spec.rb +39 -0
  264. data/spec/graphql/schema/enum_spec.rb +12 -3
  265. data/spec/graphql/schema/enum_value_spec.rb +11 -0
  266. data/spec/graphql/schema/field_extension_spec.rb +115 -0
  267. data/spec/graphql/schema/field_spec.rb +47 -7
  268. data/spec/graphql/schema/input_object_spec.rb +95 -0
  269. data/spec/graphql/schema/instrumentation_spec.rb +3 -0
  270. data/spec/graphql/schema/interface_spec.rb +8 -2
  271. data/spec/graphql/schema/introspection_system_spec.rb +9 -1
  272. data/spec/graphql/schema/loader_spec.rb +5 -0
  273. data/spec/graphql/schema/member/accepts_definition_spec.rb +4 -0
  274. data/spec/graphql/schema/member/build_type_spec.rb +46 -0
  275. data/spec/graphql/schema/member/scoped_spec.rb +19 -3
  276. data/spec/graphql/schema/mutation_spec.rb +5 -3
  277. data/spec/graphql/schema/object_spec.rb +9 -1
  278. data/spec/graphql/schema/printer_spec.rb +255 -93
  279. data/spec/graphql/schema/relay_classic_mutation_spec.rb +133 -0
  280. data/spec/graphql/schema/resolver_spec.rb +173 -9
  281. data/spec/graphql/schema/scalar_spec.rb +6 -0
  282. data/spec/graphql/schema/subscription_spec.rb +416 -0
  283. data/spec/graphql/schema/traversal_spec.rb +10 -10
  284. data/spec/graphql/schema/type_expression_spec.rb +2 -2
  285. data/spec/graphql/schema/union_spec.rb +7 -0
  286. data/spec/graphql/schema/validation_spec.rb +1 -1
  287. data/spec/graphql/schema/warden_spec.rb +145 -88
  288. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +213 -73
  289. data/spec/graphql/static_validation/rules/argument_names_are_unique_spec.rb +2 -2
  290. data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +72 -29
  291. data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +4 -2
  292. data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +4 -2
  293. data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +10 -5
  294. data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +10 -5
  295. data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +131 -5
  296. data/spec/graphql/static_validation/rules/fragment_names_are_unique_spec.rb +2 -1
  297. data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +6 -3
  298. data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +4 -2
  299. data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +4 -2
  300. data/spec/graphql/static_validation/rules/fragments_are_named_spec.rb +2 -1
  301. data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +6 -3
  302. data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +22 -2
  303. data/spec/graphql/static_validation/rules/mutation_root_exists_spec.rb +2 -1
  304. data/spec/graphql/static_validation/rules/operation_names_are_valid_spec.rb +6 -3
  305. data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +13 -4
  306. data/spec/graphql/static_validation/rules/required_input_object_attributes_are_present_spec.rb +58 -0
  307. data/spec/graphql/static_validation/rules/subscription_root_exists_spec.rb +2 -1
  308. data/spec/graphql/static_validation/rules/unique_directives_per_location_spec.rb +14 -7
  309. data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +14 -7
  310. data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +8 -4
  311. data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +8 -4
  312. data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +23 -3
  313. data/spec/graphql/static_validation/type_stack_spec.rb +10 -19
  314. data/spec/graphql/static_validation/validator_spec.rb +50 -2
  315. data/spec/graphql/subscriptions_spec.rb +27 -16
  316. data/spec/graphql/tracing/new_relic_tracing_spec.rb +16 -0
  317. data/spec/graphql/tracing/platform_tracing_spec.rb +59 -37
  318. data/spec/graphql/tracing/prometheus_tracing_spec.rb +3 -0
  319. data/spec/graphql/tracing/skylight_tracing_spec.rb +16 -0
  320. data/spec/graphql/types/iso_8601_date_time_spec.rb +29 -2
  321. data/spec/graphql/union_type_spec.rb +2 -2
  322. data/spec/graphql/upgrader/member_spec.rb +67 -0
  323. data/spec/{graphql → integration/mongoid/graphql}/relay/mongo_relation_connection_spec.rb +11 -22
  324. data/spec/integration/mongoid/spec_helper.rb +2 -0
  325. data/spec/{support → integration/mongoid}/star_trek/data.rb +0 -0
  326. data/spec/{support → integration/mongoid}/star_trek/schema.rb +56 -34
  327. data/spec/{support/star_wars → integration/rails}/data.rb +1 -0
  328. data/spec/{support → integration/rails/generators}/base_generator_test.rb +0 -0
  329. data/spec/{generators → integration/rails/generators}/graphql/enum_generator_spec.rb +0 -0
  330. data/spec/{generators → integration/rails/generators}/graphql/install_generator_spec.rb +1 -1
  331. data/spec/{generators → integration/rails/generators}/graphql/interface_generator_spec.rb +0 -0
  332. data/spec/{generators → integration/rails/generators}/graphql/loader_generator_spec.rb +0 -0
  333. data/spec/{generators → integration/rails/generators}/graphql/mutation_generator_spec.rb +0 -0
  334. data/spec/{generators → integration/rails/generators}/graphql/object_generator_spec.rb +0 -0
  335. data/spec/integration/rails/generators/graphql/scalar_generator_spec.rb +28 -0
  336. data/spec/{generators → integration/rails/generators}/graphql/union_generator_spec.rb +0 -0
  337. data/spec/integration/rails/graphql/input_object_type_spec.rb +364 -0
  338. data/spec/{graphql → integration/rails/graphql}/query/variables_spec.rb +7 -7
  339. data/spec/{graphql → integration/rails/graphql}/relay/array_connection_spec.rb +9 -9
  340. data/spec/{graphql → integration/rails/graphql}/relay/base_connection_spec.rb +11 -3
  341. data/spec/{graphql → integration/rails/graphql}/relay/connection_instrumentation_spec.rb +19 -22
  342. data/spec/{graphql → integration/rails/graphql}/relay/connection_resolve_spec.rb +16 -0
  343. data/spec/{graphql → integration/rails/graphql}/relay/connection_type_spec.rb +0 -0
  344. data/spec/{graphql → integration/rails/graphql}/relay/edge_spec.rb +0 -0
  345. data/spec/{graphql → integration/rails/graphql}/relay/mutation_spec.rb +48 -0
  346. data/spec/{graphql → integration/rails/graphql}/relay/node_spec.rb +0 -0
  347. data/spec/{graphql → integration/rails/graphql}/relay/page_info_spec.rb +22 -22
  348. data/spec/{graphql → integration/rails/graphql}/relay/range_add_spec.rb +4 -4
  349. data/spec/{graphql → integration/rails/graphql}/relay/relation_connection_spec.rb +56 -27
  350. data/spec/{graphql → integration/rails/graphql}/schema_spec.rb +15 -11
  351. data/spec/{graphql → integration/rails/graphql}/tracing/active_support_notifications_tracing_spec.rb +16 -9
  352. data/spec/integration/rails/spec_helper.rb +25 -0
  353. data/spec/integration/tmp/app/graphql/types/family_type.rb +9 -0
  354. data/spec/spec_helper.rb +23 -39
  355. data/spec/support/dummy/data.rb +20 -17
  356. data/spec/support/dummy/schema.rb +315 -305
  357. data/spec/support/error_bubbling_helpers.rb +23 -0
  358. data/spec/support/jazz.rb +213 -46
  359. data/spec/support/lazy_helpers.rb +69 -27
  360. data/spec/support/new_relic.rb +3 -0
  361. data/spec/support/skylight.rb +3 -0
  362. data/spec/support/star_wars/schema.rb +131 -81
  363. data/spec/support/static_validation_helpers.rb +9 -5
  364. metadata +418 -261
  365. data/lib/graphql/language/comments.rb +0 -45
  366. data/lib/graphql/static_validation/arguments_validator.rb +0 -50
  367. data/spec/graphql/schema/member/has_fields_spec.rb +0 -129
  368. data/spec/rails_dependency_sanity_spec.rb +0 -14
@@ -8,17 +8,19 @@ module GraphQL
8
8
  # - `children` returns all AST nodes attached to this one. Used for tree traversal.
9
9
  # - `scalars` returns all scalar (Ruby) values attached to this one. Used for comparing nodes.
10
10
  # - `to_query_string` turns an AST node into a GraphQL string
11
-
12
11
  class AbstractNode
13
- module Scalars # :nodoc:
14
- module Name
15
- def scalars
16
- super + [name]
17
- end
12
+ module DefinitionNode
13
+ # This AST node's {#line} returns the first line, which may be the description.
14
+ # @return [Integer] The first line of the definition (not the description)
15
+ attr_reader :definition_line
16
+
17
+ def initialize(options = {})
18
+ @definition_line = options.delete(:definition_line)
19
+ super(options)
18
20
  end
19
21
  end
20
22
 
21
- attr_accessor :line, :col, :filename
23
+ attr_reader :line, :col, :filename
22
24
 
23
25
  # Initialize a node by extracting its position,
24
26
  # then calling the class's `initialize_node` method.
@@ -34,11 +36,6 @@ module GraphQL
34
36
  initialize_node(options)
35
37
  end
36
38
 
37
- # This is called with node-specific options
38
- def initialize_node(options={})
39
- raise NotImplementedError
40
- end
41
-
42
39
  # Value equality
43
40
  # @return [Boolean] True if `self` is equivalent to `other`
44
41
  def eql?(other)
@@ -48,14 +45,27 @@ module GraphQL
48
45
  other.children.eql?(self.children)
49
46
  end
50
47
 
48
+ NO_CHILDREN = [].freeze
49
+
51
50
  # @return [Array<GraphQL::Language::Nodes::AbstractNode>] all nodes in the tree below this one
52
51
  def children
53
- []
52
+ NO_CHILDREN
54
53
  end
55
54
 
56
55
  # @return [Array<Integer, Float, String, Boolean, Array>] Scalar values attached to this node
57
56
  def scalars
58
- []
57
+ NO_CHILDREN
58
+ end
59
+
60
+ # This might be unnecessary, but its easiest to add it here.
61
+ def initialize_copy(other)
62
+ @children = nil
63
+ @scalars = nil
64
+ end
65
+
66
+ # @return [Symbol] the method to call on {Language::Visitor} for this node
67
+ def visit_method
68
+ raise NotImplementedError, "#{self.class.name}#visit_method shold return a symbol"
59
69
  end
60
70
 
61
71
  def position
@@ -65,35 +75,202 @@ module GraphQL
65
75
  def to_query_string(printer: GraphQL::Language::Printer.new)
66
76
  printer.print(self)
67
77
  end
68
- end
69
78
 
70
- # Base class for non-null type names and list type names
71
- class WrapperType < AbstractNode
72
- attr_accessor :of_type
79
+ # This creates a copy of `self`, with `new_options` applied.
80
+ # @param new_options [Hash]
81
+ # @return [AbstractNode] a shallow copy of `self`
82
+ def merge(new_options)
83
+ copied_self = dup
84
+ new_options.each do |key, value|
85
+ copied_self.instance_variable_set(:"@#{key}", value)
86
+ end
87
+ copied_self
88
+ end
89
+
90
+ # Copy `self`, but modify the copy so that `previous_child` is replaced by `new_child`
91
+ def replace_child(previous_child, new_child)
92
+ # Figure out which list `previous_child` may be found in
93
+ method_name = previous_child.children_method_name
94
+ # Get the value from this (original) node
95
+ prev_children = public_send(method_name)
96
+ if prev_children.is_a?(Array)
97
+ # Copy that list, and replace `previous_child` with `new_child`
98
+ # in the list.
99
+ new_children = prev_children.dup
100
+ prev_idx = new_children.index(previous_child)
101
+ new_children[prev_idx] = new_child
102
+ else
103
+ # Use the new value for the given attribute
104
+ new_children = new_child
105
+ end
106
+ # Copy this node, but with the new child value
107
+ copy_of_self = merge(method_name => new_children)
108
+ # Return the copy:
109
+ copy_of_self
110
+ end
111
+
112
+ # TODO DRY with `replace_child`
113
+ def delete_child(previous_child)
114
+ # Figure out which list `previous_child` may be found in
115
+ method_name = previous_child.children_method_name
116
+ # Copy that list, and delete previous_child
117
+ new_children = public_send(method_name).dup
118
+ new_children.delete(previous_child)
119
+ # Copy this node, but with the new list of children:
120
+ copy_of_self = merge(method_name => new_children)
121
+ # Return the copy:
122
+ copy_of_self
123
+ end
124
+
125
+ class << self
126
+ # Add a default `#visit_method` and `#children_method_name` using the class name
127
+ def inherited(child_class)
128
+ super
129
+ name_underscored = child_class.name
130
+ .split("::").last
131
+ .gsub(/([a-z])([A-Z])/,'\1_\2') # insert underscores
132
+ .downcase # remove caps
133
+
134
+ child_class.module_eval <<-RUBY
135
+ def visit_method
136
+ :on_#{name_underscored}
137
+ end
138
+
139
+ def children_method_name
140
+ :#{name_underscored}s
141
+ end
142
+ RUBY
143
+ end
73
144
 
74
- def initialize_node(of_type: nil)
75
- @of_type = of_type
76
- end
145
+ private
146
+
147
+ # Name accessors which return lists of nodes,
148
+ # along with the kind of node they return, if possible.
149
+ # - Add a reader for these children
150
+ # - Add a persistent update method to add a child
151
+ # - Generate a `#children` method
152
+ def children_methods(children_of_type)
153
+ if @children_methods
154
+ raise "Can't re-call .children_methods for #{self} (already have: #{@children_methods})"
155
+ else
156
+ @children_methods = children_of_type
157
+ end
77
158
 
78
- def scalars
79
- [of_type]
159
+ if children_of_type == false
160
+ @children_methods = {}
161
+ # skip
162
+ else
163
+
164
+ children_of_type.each do |method_name, node_type|
165
+ module_eval <<-RUBY, __FILE__, __LINE__
166
+ # A reader for these children
167
+ attr_reader :#{method_name}
168
+ RUBY
169
+
170
+ if node_type
171
+ # Only generate a method if we know what kind of node to make
172
+ module_eval <<-RUBY, __FILE__, __LINE__
173
+ # Singular method: create a node with these options
174
+ # and return a new `self` which includes that node in this list.
175
+ def merge_#{method_name.to_s.sub(/s$/, "")}(node_opts)
176
+ merge(#{method_name}: #{method_name} + [#{node_type.name}.new(node_opts)])
177
+ end
178
+ RUBY
179
+ end
180
+ end
181
+
182
+ if children_of_type.size == 1
183
+ module_eval <<-RUBY, __FILE__, __LINE__
184
+ alias :children #{children_of_type.keys.first}
185
+ RUBY
186
+ else
187
+ module_eval <<-RUBY, __FILE__, __LINE__
188
+ def children
189
+ @children ||= (#{children_of_type.keys.map { |k| "@#{k}" }.join(" + ")}).freeze
190
+ end
191
+ RUBY
192
+ end
193
+ end
194
+
195
+ if defined?(@scalar_methods)
196
+ generate_initialize_node
197
+ else
198
+ raise "Can't generate_initialize_node because scalar_methods wasn't called; call it before children_methods"
199
+ end
200
+ end
201
+
202
+ # These methods return a plain Ruby value, not another node
203
+ # - Add reader methods
204
+ # - Add a `#scalars` method
205
+ def scalar_methods(*method_names)
206
+ if @scalar_methods
207
+ raise "Can't re-call .scalar_methods for #{self} (already have: #{@scalar_methods})"
208
+ else
209
+ @scalar_methods = method_names
210
+ end
211
+
212
+ if method_names == [false]
213
+ @scalar_methods = []
214
+ # skip it
215
+ else
216
+ module_eval <<-RUBY, __FILE__, __LINE__
217
+ # add readers for each scalar
218
+ attr_reader #{method_names.map { |m| ":#{m}"}.join(", ")}
219
+
220
+ def scalars
221
+ @scalars ||= [#{method_names.map { |k| "@#{k}" }.join(", ")}].freeze
222
+ end
223
+ RUBY
224
+ end
225
+ end
226
+
227
+ def generate_initialize_node
228
+ scalar_method_names = @scalar_methods
229
+ # TODO: These probably should be scalar methods, but `types` returns an array
230
+ [:types, :description].each do |extra_method|
231
+ if method_defined?(extra_method)
232
+ scalar_method_names += [extra_method]
233
+ end
234
+ end
235
+
236
+ all_method_names = scalar_method_names + @children_methods.keys
237
+ if all_method_names.include?(:alias)
238
+ # Rather than complicating this special case,
239
+ # let it be overridden (in field)
240
+ return
241
+ else
242
+ arguments = scalar_method_names.map { |m| "#{m}: nil"} +
243
+ @children_methods.keys.map { |m| "#{m}: []" }
244
+
245
+ assignments = scalar_method_names.map { |m| "@#{m} = #{m}"} +
246
+ @children_methods.keys.map { |m| "@#{m} = #{m}.freeze" }
247
+
248
+ module_eval <<-RUBY, __FILE__, __LINE__
249
+ def initialize_node #{arguments.join(", ")}
250
+ #{assignments.join("\n")}
251
+ end
252
+ RUBY
253
+ end
254
+ end
80
255
  end
81
256
  end
82
257
 
258
+ # Base class for non-null type names and list type names
259
+ class WrapperType < AbstractNode
260
+ scalar_methods :of_type
261
+ children_methods(false)
262
+ end
263
+
83
264
  # Base class for nodes whose only value is a name (no child nodes or other scalars)
84
265
  class NameOnlyNode < AbstractNode
85
- include Scalars::Name
86
-
87
- attr_accessor :name
88
-
89
- def initialize_node(name: nil)
90
- @name = name
91
- end
266
+ scalar_methods :name
267
+ children_methods(false)
92
268
  end
93
269
 
94
270
  # A key-value pair for a field's inputs
95
271
  class Argument < AbstractNode
96
- attr_accessor :name, :value
272
+ scalar_methods :name, :value
273
+ children_methods(false)
97
274
 
98
275
  # @!attribute name
99
276
  # @return [String] the key for this argument
@@ -101,51 +278,29 @@ module GraphQL
101
278
  # @!attribute value
102
279
  # @return [String, Float, Integer, Boolean, Array, InputObject] The value passed for this key
103
280
 
104
- def initialize_node(name: nil, value: nil)
105
- @name = name
106
- @value = value
107
- end
108
-
109
- def scalars
110
- [name, value]
111
- end
112
-
113
281
  def children
114
- [value].flatten.select { |v| v.is_a?(AbstractNode) }
282
+ @children ||= Array(value).flatten.select { |v| v.is_a?(AbstractNode) }
115
283
  end
116
284
  end
117
285
 
118
286
  class Directive < AbstractNode
119
- include Scalars::Name
120
-
121
- attr_accessor :name, :arguments
122
- alias :children :arguments
287
+ scalar_methods :name
288
+ children_methods(arguments: GraphQL::Language::Nodes::Argument)
289
+ end
123
290
 
124
- def initialize_node(name: nil, arguments: [])
125
- @name = name
126
- @arguments = arguments
127
- end
291
+ class DirectiveLocation < NameOnlyNode
128
292
  end
129
293
 
130
294
  class DirectiveDefinition < AbstractNode
131
- include Scalars::Name
132
-
133
- attr_accessor :name, :arguments, :locations, :description
134
-
135
- def initialize_node(name: nil, arguments: [], locations: [], description: nil)
136
- @name = name
137
- @arguments = arguments
138
- @locations = locations
139
- @description = description
140
- end
141
-
142
- def children
143
- arguments + locations
144
- end
295
+ include DefinitionNode
296
+ attr_reader :description
297
+ scalar_methods :name
298
+ children_methods(
299
+ locations: Nodes::DirectiveLocation,
300
+ arguments: Nodes::Argument,
301
+ )
145
302
  end
146
303
 
147
- class DirectiveLocation < NameOnlyNode; end
148
-
149
304
  # This is the AST root for normal queries
150
305
  #
151
306
  # @example Deriving a document by parsing a string
@@ -165,14 +320,10 @@ module GraphQL
165
320
  # document.to_query_string(printer: VariableSrubber.new)
166
321
  #
167
322
  class Document < AbstractNode
168
- attr_accessor :definitions
169
- alias :children :definitions
170
-
323
+ scalar_methods false
324
+ children_methods(definitions: nil)
171
325
  # @!attribute definitions
172
326
  # @return [Array<OperationDefinition, FragmentDefinition>] top-level GraphQL units: operations or fragments
173
- def initialize_node(definitions: [])
174
- @definitions = definitions
175
- end
176
327
 
177
328
  def slice_definition(name)
178
329
  GraphQL::Language::DefinitionSlice.slice(self, name)
@@ -180,39 +331,47 @@ module GraphQL
180
331
  end
181
332
 
182
333
  # An enum value. The string is available as {#name}.
183
- class Enum < NameOnlyNode; end
334
+ class Enum < NameOnlyNode
335
+ end
184
336
 
185
337
  # A null value literal.
186
- class NullValue < NameOnlyNode; end
338
+ class NullValue < NameOnlyNode
339
+ end
187
340
 
188
341
  # A single selection in a GraphQL query.
189
342
  class Field < AbstractNode
190
- attr_accessor :name, :alias, :arguments, :directives, :selections
343
+ scalar_methods :name, :alias
344
+ children_methods({
345
+ arguments: GraphQL::Language::Nodes::Argument,
346
+ selections: GraphQL::Language::Nodes::Field,
347
+ directives: GraphQL::Language::Nodes::Directive,
348
+ })
191
349
 
192
350
  # @!attribute selections
193
351
  # @return [Array<Nodes::Field>] Selections on this object (or empty array if this is a scalar field)
194
352
 
195
353
  def initialize_node(name: nil, arguments: [], directives: [], selections: [], **kwargs)
196
354
  @name = name
197
- # oops, alias is a keyword:
198
- @alias = kwargs.fetch(:alias, nil)
199
355
  @arguments = arguments
200
356
  @directives = directives
201
357
  @selections = selections
358
+ # oops, alias is a keyword:
359
+ @alias = kwargs.fetch(:alias, nil)
202
360
  end
203
361
 
204
- def scalars
205
- [name, self.alias]
206
- end
207
-
208
- def children
209
- arguments + directives + selections
362
+ # Override this because default is `:fields`
363
+ def children_method_name
364
+ :selections
210
365
  end
211
366
  end
212
367
 
213
368
  # A reusable fragment, defined at document-level.
214
369
  class FragmentDefinition < AbstractNode
215
- attr_accessor :name, :type, :directives, :selections
370
+ scalar_methods :name, :type
371
+ children_methods({
372
+ selections: GraphQL::Language::Nodes::Field,
373
+ directives: GraphQL::Language::Nodes::Directive,
374
+ })
216
375
 
217
376
  # @!attribute name
218
377
  # @return [String] the identifier for this fragment, which may be applied with `...#{name}`
@@ -226,65 +385,48 @@ module GraphQL
226
385
  @selections = selections
227
386
  end
228
387
 
229
- def children
230
- directives + selections
231
- end
232
-
233
- def scalars
234
- [name, type]
388
+ def children_method_name
389
+ :definitions
235
390
  end
236
391
  end
237
392
 
238
393
  # Application of a named fragment in a selection
239
394
  class FragmentSpread < AbstractNode
240
- include Scalars::Name
395
+ scalar_methods :name
396
+ children_methods(directives: GraphQL::Language::Nodes::Directive)
241
397
 
242
- attr_accessor :name, :directives
243
- alias :children :directives
398
+ def children_method_name
399
+ :selections
400
+ end
244
401
 
245
402
  # @!attribute name
246
403
  # @return [String] The identifier of the fragment to apply, corresponds with {FragmentDefinition#name}
247
-
248
- def initialize_node(name: nil, directives: [])
249
- @name = name
250
- @directives = directives
251
- end
252
404
  end
253
405
 
254
406
  # An unnamed fragment, defined directly in the query with `... { }`
255
407
  class InlineFragment < AbstractNode
256
- attr_accessor :type, :directives, :selections
408
+ scalar_methods :type
409
+ children_methods({
410
+ selections: GraphQL::Language::Nodes::Field,
411
+ directives: GraphQL::Language::Nodes::Directive,
412
+ })
257
413
 
258
- # @!attribute type
259
- # @return [String, nil] Name of the type this fragment applies to, or `nil` if this fragment applies to any type
260
-
261
- def initialize_node(type: nil, directives: [], selections: [])
262
- @type = type
263
- @directives = directives
264
- @selections = selections
265
- end
266
-
267
- def children
268
- directives + selections
414
+ def children_method_name
415
+ :selections
269
416
  end
270
417
 
271
- def scalars
272
- [type]
273
- end
418
+ # @!attribute type
419
+ # @return [String, nil] Name of the type this fragment applies to, or `nil` if this fragment applies to any type
274
420
  end
275
421
 
276
422
  # A collection of key-value inputs which may be a field argument
277
423
  class InputObject < AbstractNode
278
- attr_accessor :arguments
279
- alias :children :arguments
424
+ scalar_methods(false)
425
+ children_methods(arguments: GraphQL::Language::Nodes::Argument)
280
426
 
281
427
  # @!attribute arguments
282
428
  # @return [Array<Nodes::Argument>] A list of key-value pairs inside this input object
283
429
 
284
- def initialize_node(arguments: [])
285
- @arguments = arguments
286
- end
287
-
288
430
  # @return [Hash<String, Any>] Recursively turn this input object into a Ruby Hash
289
431
  def to_h(options={})
290
432
  arguments.inject({}) do |memo, pair|
@@ -294,6 +436,10 @@ module GraphQL
294
436
  end
295
437
  end
296
438
 
439
+ def children_method_name
440
+ :value
441
+ end
442
+
297
443
  private
298
444
 
299
445
  def serialize_value_for_hash(value)
@@ -316,16 +462,37 @@ module GraphQL
316
462
 
317
463
 
318
464
  # A list type definition, denoted with `[...]` (used for variable type definitions)
319
- class ListType < WrapperType; end
465
+ class ListType < WrapperType
466
+ end
320
467
 
321
468
  # A non-null type definition, denoted with `...!` (used for variable type definitions)
322
- class NonNullType < WrapperType; end
469
+ class NonNullType < WrapperType
470
+ end
471
+
472
+ # An operation-level query variable
473
+ class VariableDefinition < AbstractNode
474
+ scalar_methods :name, :type, :default_value
475
+ children_methods false
476
+ # @!attribute default_value
477
+ # @return [String, Integer, Float, Boolean, Array, NullValue] A Ruby value to use if no other value is provided
478
+
479
+ # @!attribute type
480
+ # @return [TypeName, NonNullType, ListType] The expected type of this value
481
+
482
+ # @!attribute name
483
+ # @return [String] The identifier for this variable, _without_ `$`
484
+ end
323
485
 
324
486
  # A query, mutation or subscription.
325
487
  # May be anonymous or named.
326
488
  # May be explicitly typed (eg `mutation { ... }`) or implicitly a query (eg `{ ... }`).
327
489
  class OperationDefinition < AbstractNode
328
- attr_accessor :operation_type, :name, :variables, :directives, :selections
490
+ scalar_methods :operation_type, :name
491
+ children_methods({
492
+ variables: GraphQL::Language::Nodes::VariableDefinition,
493
+ selections: GraphQL::Language::Nodes::Field,
494
+ directives: GraphQL::Language::Nodes::Directive,
495
+ })
329
496
 
330
497
  # @!attribute variables
331
498
  # @return [Array<VariableDefinition>] Variable definitions for this operation
@@ -339,314 +506,225 @@ module GraphQL
339
506
  # @!attribute name
340
507
  # @return [String, nil] The name for this operation, or `nil` if unnamed
341
508
 
342
- def initialize_node(operation_type: nil, name: nil, variables: [], directives: [], selections: [])
343
- @operation_type = operation_type
344
- @name = name
345
- @variables = variables
346
- @directives = directives
347
- @selections = selections
348
- end
349
-
350
- def children
351
- variables + directives + selections
352
- end
353
-
354
- def scalars
355
- [operation_type, name]
509
+ def children_method_name
510
+ :definitions
356
511
  end
357
512
  end
358
513
 
359
514
  # A type name, used for variable definitions
360
- class TypeName < NameOnlyNode; end
361
-
362
- # An operation-level query variable
363
- class VariableDefinition < AbstractNode
364
- attr_accessor :name, :type, :default_value
365
-
366
- # @!attribute default_value
367
- # @return [String, Integer, Float, Boolean, Array, NullValue] A Ruby value to use if no other value is provided
368
-
369
- # @!attribute type
370
- # @return [TypeName, NonNullType, ListType] The expected type of this value
371
-
372
- # @!attribute name
373
- # @return [String] The identifier for this variable, _without_ `$`
374
-
375
- def initialize_node(name: nil, type: nil, default_value: nil)
376
- @name = name
377
- @type = type
378
- @default_value = default_value
379
- end
380
-
381
- def scalars
382
- [name, type, default_value]
383
- end
515
+ class TypeName < NameOnlyNode
384
516
  end
385
517
 
386
518
  # Usage of a variable in a query. Name does _not_ include `$`.
387
- class VariableIdentifier < NameOnlyNode; end
519
+ class VariableIdentifier < NameOnlyNode
520
+ end
388
521
 
389
522
  class SchemaDefinition < AbstractNode
390
- attr_accessor :query, :mutation, :subscription, :directives
391
-
392
- def initialize_node(query: nil, mutation: nil, subscription: nil, directives: [])
393
- @query = query
394
- @mutation = mutation
395
- @subscription = subscription
396
- @directives = directives
397
- end
398
-
399
- def scalars
400
- [query, mutation, subscription]
523
+ include DefinitionNode
524
+ scalar_methods :query, :mutation, :subscription
525
+ children_methods({
526
+ directives: GraphQL::Language::Nodes::Directive,
527
+ })
528
+ def children_method_name
529
+ :definitions
401
530
  end
402
-
403
- alias :children :directives
404
531
  end
405
532
 
406
533
  class SchemaExtension < AbstractNode
407
- attr_accessor :query, :mutation, :subscription, :directives
408
-
409
- def initialize_node(query: nil, mutation: nil, subscription: nil, directives: [])
410
- @query = query
411
- @mutation = mutation
412
- @subscription = subscription
413
- @directives = directives
414
- end
415
-
416
- def scalars
417
- [query, mutation, subscription]
534
+ scalar_methods :query, :mutation, :subscription
535
+ children_methods({
536
+ directives: GraphQL::Language::Nodes::Directive,
537
+ })
538
+ def children_method_name
539
+ :definitions
418
540
  end
419
-
420
- alias :children :directives
421
541
  end
422
542
 
423
543
  class ScalarTypeDefinition < AbstractNode
424
- include Scalars::Name
425
-
426
- attr_accessor :name, :directives, :description
427
- alias :children :directives
428
-
429
- def initialize_node(name:, directives: [], description: nil)
430
- @name = name
431
- @directives = directives
432
- @description = description
544
+ include DefinitionNode
545
+ attr_reader :description
546
+ scalar_methods :name
547
+ children_methods({
548
+ directives: GraphQL::Language::Nodes::Directive,
549
+ })
550
+ def children_method_name
551
+ :definitions
433
552
  end
434
553
  end
435
554
 
436
555
  class ScalarTypeExtension < AbstractNode
437
- attr_accessor :name, :directives
438
- alias :children :directives
439
-
440
- def initialize_node(name:, directives: [])
441
- @name = name
442
- @directives = directives
443
- end
444
- end
445
-
446
- class ObjectTypeDefinition < AbstractNode
447
- include Scalars::Name
448
-
449
- attr_accessor :name, :interfaces, :fields, :directives, :description
450
-
451
- def initialize_node(name:, interfaces:, fields:, directives: [], description: nil)
452
- @name = name
453
- @interfaces = interfaces || []
454
- @directives = directives
455
- @fields = fields
456
- @description = description
457
- end
458
-
459
- def children
460
- interfaces + fields + directives
461
- end
462
- end
463
-
464
- class ObjectTypeExtension < AbstractNode
465
- attr_accessor :name, :interfaces, :fields, :directives
466
-
467
- def initialize_node(name:, interfaces:, fields:, directives: [])
468
- @name = name
469
- @interfaces = interfaces || []
470
- @directives = directives
471
- @fields = fields
472
- end
473
-
474
- def children
475
- interfaces + fields + directives
556
+ scalar_methods :name
557
+ children_methods({
558
+ directives: GraphQL::Language::Nodes::Directive,
559
+ })
560
+ def children_method_name
561
+ :definitions
476
562
  end
477
563
  end
478
564
 
479
565
  class InputValueDefinition < AbstractNode
480
- attr_accessor :name, :type, :default_value, :directives,:description
481
- alias :children :directives
482
-
483
- def initialize_node(name:, type:, default_value: nil, directives: [], description: nil)
484
- @name = name
485
- @type = type
486
- @default_value = default_value
487
- @directives = directives
488
- @description = description
489
- end
490
-
491
- def scalars
492
- [name, type, default_value]
566
+ include DefinitionNode
567
+ attr_reader :description
568
+ scalar_methods :name, :type, :default_value
569
+ children_methods({
570
+ directives: GraphQL::Language::Nodes::Directive,
571
+ })
572
+ def children_method_name
573
+ :fields
493
574
  end
494
575
  end
495
576
 
496
577
  class FieldDefinition < AbstractNode
497
- attr_accessor :name, :arguments, :type, :directives, :description
498
-
499
- def initialize_node(name:, arguments:, type:, directives: [], description: nil)
500
- @name = name
501
- @arguments = arguments
502
- @type = type
503
- @directives = directives
504
- @description = description
578
+ include DefinitionNode
579
+ attr_reader :description
580
+ scalar_methods :name, :type
581
+ children_methods({
582
+ directives: GraphQL::Language::Nodes::Directive,
583
+ arguments: GraphQL::Language::Nodes::InputValueDefinition,
584
+ })
585
+ def children_method_name
586
+ :fields
587
+ end
588
+
589
+ # this is so that `children_method_name` of `InputValueDefinition` works properly
590
+ # with `#replace_child`
591
+ alias :fields :arguments
592
+ def merge(new_options)
593
+ if (f = new_options.delete(:fields))
594
+ new_options[:arguments] = f
595
+ end
596
+ super
505
597
  end
598
+ end
506
599
 
507
- def children
508
- arguments + directives
600
+ class ObjectTypeDefinition < AbstractNode
601
+ include DefinitionNode
602
+ attr_reader :description
603
+ scalar_methods :name, :interfaces
604
+ children_methods({
605
+ directives: GraphQL::Language::Nodes::Directive,
606
+ fields: GraphQL::Language::Nodes::FieldDefinition,
607
+ })
608
+ def children_method_name
609
+ :definitions
509
610
  end
611
+ end
510
612
 
511
- def scalars
512
- [name, type]
613
+ class ObjectTypeExtension < AbstractNode
614
+ scalar_methods :name, :interfaces
615
+ children_methods({
616
+ directives: GraphQL::Language::Nodes::Directive,
617
+ fields: GraphQL::Language::Nodes::FieldDefinition,
618
+ })
619
+ def children_method_name
620
+ :definitions
513
621
  end
514
622
  end
515
623
 
516
624
  class InterfaceTypeDefinition < AbstractNode
517
- include Scalars::Name
518
-
519
- attr_accessor :name, :fields, :directives, :description
520
-
521
- def initialize_node(name:, fields:, directives: [], description: nil)
522
- @name = name
523
- @fields = fields
524
- @directives = directives
525
- @description = description
526
- end
527
-
528
- def children
529
- fields + directives
625
+ include DefinitionNode
626
+ attr_reader :description
627
+ scalar_methods :name
628
+ children_methods({
629
+ directives: GraphQL::Language::Nodes::Directive,
630
+ fields: GraphQL::Language::Nodes::FieldDefinition,
631
+ })
632
+ def children_method_name
633
+ :definitions
530
634
  end
531
635
  end
532
636
 
533
637
  class InterfaceTypeExtension < AbstractNode
534
- attr_accessor :name, :fields, :directives
535
-
536
- def initialize_node(name:, fields:, directives: [])
537
- @name = name
538
- @fields = fields
539
- @directives = directives
540
- end
541
-
542
- def children
543
- fields + directives
638
+ scalar_methods :name
639
+ children_methods({
640
+ directives: GraphQL::Language::Nodes::Directive,
641
+ fields: GraphQL::Language::Nodes::FieldDefinition,
642
+ })
643
+ def children_method_name
644
+ :definitions
544
645
  end
545
646
  end
546
647
 
547
648
  class UnionTypeDefinition < AbstractNode
548
- include Scalars::Name
549
-
550
- attr_accessor :name, :types, :directives, :description
551
-
552
- def initialize_node(name:, types:, directives: [], description: nil)
553
- @name = name
554
- @types = types
555
- @directives = directives
556
- @description = description
557
- end
558
-
559
- def children
560
- types + directives
649
+ include DefinitionNode
650
+ attr_reader :description, :types
651
+ scalar_methods :name
652
+ children_methods({
653
+ directives: GraphQL::Language::Nodes::Directive,
654
+ })
655
+ def children_method_name
656
+ :definitions
561
657
  end
562
658
  end
563
659
 
564
660
  class UnionTypeExtension < AbstractNode
565
- attr_accessor :name, :types, :directives
566
-
567
- def initialize_node(name:, types:, directives: [])
568
- @name = name
569
- @types = types
570
- @directives = directives
661
+ attr_reader :types
662
+ scalar_methods :name
663
+ children_methods({
664
+ directives: GraphQL::Language::Nodes::Directive,
665
+ })
666
+ def children_method_name
667
+ :definitions
571
668
  end
669
+ end
572
670
 
573
- def children
574
- types + directives
671
+ class EnumValueDefinition < AbstractNode
672
+ include DefinitionNode
673
+ attr_reader :description
674
+ scalar_methods :name
675
+ children_methods({
676
+ directives: GraphQL::Language::Nodes::Directive,
677
+ })
678
+ def children_method_name
679
+ :values
575
680
  end
576
681
  end
577
682
 
578
683
  class EnumTypeDefinition < AbstractNode
579
- include Scalars::Name
580
-
581
- attr_accessor :name, :values, :directives, :description
582
-
583
- def initialize_node(name:, values:, directives: [], description: nil)
584
- @name = name
585
- @values = values
586
- @directives = directives
587
- @description = description
588
- end
589
-
590
- def children
591
- values + directives
684
+ include DefinitionNode
685
+ attr_reader :description
686
+ scalar_methods :name
687
+ children_methods({
688
+ directives: GraphQL::Language::Nodes::Directive,
689
+ values: GraphQL::Language::Nodes::EnumValueDefinition,
690
+ })
691
+ def children_method_name
692
+ :definitions
592
693
  end
593
694
  end
594
695
 
595
696
  class EnumTypeExtension < AbstractNode
596
- attr_accessor :name, :values, :directives
597
-
598
- def initialize_node(name:, values:, directives: [])
599
- @name = name
600
- @values = values
601
- @directives = directives
602
- end
603
-
604
- def children
605
- values + directives
606
- end
607
- end
608
-
609
- class EnumValueDefinition < AbstractNode
610
- include Scalars::Name
611
-
612
- attr_accessor :name, :directives, :description
613
- alias :children :directives
614
-
615
- def initialize_node(name:, directives: [], description: nil)
616
- @name = name
617
- @directives = directives
618
- @description = description
697
+ scalar_methods :name
698
+ children_methods({
699
+ directives: GraphQL::Language::Nodes::Directive,
700
+ values: GraphQL::Language::Nodes::EnumValueDefinition,
701
+ })
702
+ def children_method_name
703
+ :definitions
619
704
  end
620
705
  end
621
706
 
622
707
  class InputObjectTypeDefinition < AbstractNode
623
- include Scalars::Name
624
-
625
- attr_accessor :name, :fields, :directives, :description
626
-
627
- def initialize_node(name:, fields:, directives: [], description: nil)
628
- @name = name
629
- @fields = fields
630
- @directives = directives
631
- @description = description
632
- end
633
-
634
- def children
635
- fields + directives
708
+ include DefinitionNode
709
+ attr_reader :description
710
+ scalar_methods :name
711
+ children_methods({
712
+ directives: GraphQL::Language::Nodes::Directive,
713
+ fields: GraphQL::Language::Nodes::InputValueDefinition,
714
+ })
715
+ def children_method_name
716
+ :definitions
636
717
  end
637
718
  end
638
719
 
639
720
  class InputObjectTypeExtension < AbstractNode
640
- attr_accessor :name, :fields, :directives
641
-
642
- def initialize_node(name:, fields:, directives: [])
643
- @name = name
644
- @fields = fields
645
- @directives = directives
646
- end
647
-
648
- def children
649
- fields + directives
721
+ scalar_methods :name
722
+ children_methods({
723
+ directives: GraphQL::Language::Nodes::Directive,
724
+ fields: GraphQL::Language::Nodes::InputValueDefinition,
725
+ })
726
+ def children_method_name
727
+ :definitions
650
728
  end
651
729
  end
652
730
  end