graphql 1.7.6 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (289) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/function_generator.rb +1 -1
  3. data/lib/generators/graphql/install_generator.rb +14 -8
  4. data/lib/generators/graphql/loader_generator.rb +1 -1
  5. data/lib/generators/graphql/mutation_generator.rb +6 -1
  6. data/lib/generators/graphql/templates/function.erb +2 -2
  7. data/lib/generators/graphql/templates/loader.erb +2 -2
  8. data/lib/generators/graphql/templates/schema.erb +1 -1
  9. data/lib/graphql/argument.rb +25 -19
  10. data/lib/graphql/backtrace/tracer.rb +16 -22
  11. data/lib/graphql/backtrace.rb +1 -1
  12. data/lib/graphql/backwards_compatibility.rb +2 -3
  13. data/lib/graphql/base_type.rb +31 -31
  14. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +14 -0
  15. data/lib/graphql/compatibility/query_parser_specification.rb +117 -0
  16. data/lib/graphql/define/assign_object_field.rb +5 -12
  17. data/lib/graphql/deprecated_dsl.rb +42 -0
  18. data/lib/graphql/directive.rb +1 -0
  19. data/lib/graphql/enum_type.rb +3 -1
  20. data/lib/graphql/execution/execute.rb +21 -13
  21. data/lib/graphql/execution/instrumentation.rb +82 -0
  22. data/lib/graphql/execution/lazy/lazy_method_map.rb +1 -1
  23. data/lib/graphql/execution/lazy/resolve.rb +1 -3
  24. data/lib/graphql/execution/multiplex.rb +12 -29
  25. data/lib/graphql/execution.rb +1 -0
  26. data/lib/graphql/field.rb +21 -4
  27. data/lib/graphql/function.rb +14 -0
  28. data/lib/graphql/input_object_type.rb +3 -1
  29. data/lib/graphql/interface_type.rb +5 -3
  30. data/lib/graphql/internal_representation/node.rb +26 -14
  31. data/lib/graphql/internal_representation/visit.rb +3 -6
  32. data/lib/graphql/introspection/base_object.rb +16 -0
  33. data/lib/graphql/introspection/directive_location_enum.rb +11 -7
  34. data/lib/graphql/introspection/directive_type.rb +23 -16
  35. data/lib/graphql/introspection/dynamic_fields.rb +11 -0
  36. data/lib/graphql/introspection/entry_points.rb +29 -0
  37. data/lib/graphql/introspection/enum_value_type.rb +16 -11
  38. data/lib/graphql/introspection/field_type.rb +21 -12
  39. data/lib/graphql/introspection/input_value_type.rb +26 -23
  40. data/lib/graphql/introspection/schema_field.rb +7 -2
  41. data/lib/graphql/introspection/schema_type.rb +36 -22
  42. data/lib/graphql/introspection/type_by_name_field.rb +10 -2
  43. data/lib/graphql/introspection/type_kind_enum.rb +10 -6
  44. data/lib/graphql/introspection/type_type.rb +85 -23
  45. data/lib/graphql/introspection/typename_field.rb +1 -0
  46. data/lib/graphql/introspection.rb +3 -10
  47. data/lib/graphql/language/block_string.rb +47 -0
  48. data/lib/graphql/language/document_from_schema_definition.rb +280 -0
  49. data/lib/graphql/language/generation.rb +3 -182
  50. data/lib/graphql/language/lexer.rb +144 -69
  51. data/lib/graphql/language/lexer.rl +15 -4
  52. data/lib/graphql/language/nodes.rb +141 -78
  53. data/lib/graphql/language/parser.rb +677 -630
  54. data/lib/graphql/language/parser.y +18 -12
  55. data/lib/graphql/language/printer.rb +361 -0
  56. data/lib/graphql/language/token.rb +10 -3
  57. data/lib/graphql/language.rb +3 -0
  58. data/lib/graphql/non_null_type.rb +1 -1
  59. data/lib/graphql/object_type.rb +1 -6
  60. data/lib/graphql/query/arguments.rb +63 -32
  61. data/lib/graphql/query/context.rb +32 -2
  62. data/lib/graphql/query/literal_input.rb +4 -1
  63. data/lib/graphql/query/null_context.rb +1 -1
  64. data/lib/graphql/query/result.rb +1 -1
  65. data/lib/graphql/query/variables.rb +21 -3
  66. data/lib/graphql/query.rb +19 -6
  67. data/lib/graphql/railtie.rb +109 -0
  68. data/lib/graphql/relay/connection_resolve.rb +3 -0
  69. data/lib/graphql/relay/connection_type.rb +5 -3
  70. data/lib/graphql/relay/edge_type.rb +2 -1
  71. data/lib/graphql/relay/global_id_resolve.rb +5 -1
  72. data/lib/graphql/relay/mongo_relation_connection.rb +40 -0
  73. data/lib/graphql/relay/mutation/instrumentation.rb +1 -1
  74. data/lib/graphql/relay/mutation/resolve.rb +5 -1
  75. data/lib/graphql/relay/relation_connection.rb +14 -19
  76. data/lib/graphql/relay/type_extensions.rb +30 -0
  77. data/lib/graphql/relay.rb +2 -0
  78. data/lib/graphql/scalar_type.rb +14 -2
  79. data/lib/graphql/schema/argument.rb +92 -0
  80. data/lib/graphql/schema/build_from_definition.rb +64 -18
  81. data/lib/graphql/schema/enum.rb +85 -0
  82. data/lib/graphql/schema/enum_value.rb +74 -0
  83. data/lib/graphql/schema/field.rb +372 -0
  84. data/lib/graphql/schema/finder.rb +153 -0
  85. data/lib/graphql/schema/input_object.rb +87 -0
  86. data/lib/graphql/schema/interface.rb +105 -0
  87. data/lib/graphql/schema/introspection_system.rb +93 -0
  88. data/lib/graphql/schema/late_bound_type.rb +32 -0
  89. data/lib/graphql/schema/list.rb +32 -0
  90. data/lib/graphql/schema/loader.rb +2 -2
  91. data/lib/graphql/schema/member/accepts_definition.rb +152 -0
  92. data/lib/graphql/schema/member/base_dsl_methods.rb +100 -0
  93. data/lib/graphql/schema/member/build_type.rb +137 -0
  94. data/lib/graphql/schema/member/cached_graphql_definition.rb +26 -0
  95. data/lib/graphql/schema/member/graphql_type_names.rb +21 -0
  96. data/lib/graphql/schema/member/has_arguments.rb +50 -0
  97. data/lib/graphql/schema/member/has_fields.rb +130 -0
  98. data/lib/graphql/schema/member/instrumentation.rb +115 -0
  99. data/lib/graphql/schema/member/type_system_helpers.rb +34 -0
  100. data/lib/graphql/schema/member.rb +28 -0
  101. data/lib/graphql/schema/middleware_chain.rb +5 -1
  102. data/lib/graphql/schema/mutation.rb +138 -0
  103. data/lib/graphql/schema/non_null.rb +38 -0
  104. data/lib/graphql/schema/object.rb +81 -0
  105. data/lib/graphql/schema/printer.rb +33 -266
  106. data/lib/graphql/schema/relay_classic_mutation.rb +87 -0
  107. data/lib/graphql/schema/rescue_middleware.rb +8 -7
  108. data/lib/graphql/schema/resolver.rb +122 -0
  109. data/lib/graphql/schema/scalar.rb +35 -0
  110. data/lib/graphql/schema/traversal.rb +102 -22
  111. data/lib/graphql/schema/union.rb +36 -0
  112. data/lib/graphql/schema/validation.rb +3 -2
  113. data/lib/graphql/schema.rb +381 -12
  114. data/lib/graphql/static_validation/definition_dependencies.rb +1 -1
  115. data/lib/graphql/static_validation/literal_validator.rb +16 -4
  116. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +6 -6
  117. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -1
  118. data/lib/graphql/static_validation/rules/fields_will_merge.rb +15 -8
  119. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +11 -1
  120. data/lib/graphql/static_validation/validation_context.rb +1 -1
  121. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +7 -5
  122. data/lib/graphql/subscriptions/instrumentation.rb +5 -1
  123. data/lib/graphql/subscriptions/serialize.rb +2 -0
  124. data/lib/graphql/subscriptions.rb +90 -16
  125. data/lib/graphql/tracing/data_dog_tracing.rb +49 -0
  126. data/lib/graphql/tracing/new_relic_tracing.rb +26 -0
  127. data/lib/graphql/tracing/platform_tracing.rb +20 -7
  128. data/lib/graphql/tracing/scout_tracing.rb +2 -2
  129. data/lib/graphql/tracing.rb +1 -0
  130. data/lib/graphql/unresolved_type_error.rb +3 -2
  131. data/lib/graphql/upgrader/member.rb +894 -0
  132. data/lib/graphql/upgrader/schema.rb +37 -0
  133. data/lib/graphql/version.rb +1 -1
  134. data/lib/graphql.rb +5 -25
  135. data/readme.md +2 -2
  136. data/spec/dummy/app/channels/graphql_channel.rb +23 -2
  137. data/spec/dummy/log/development.log +239 -0
  138. data/spec/dummy/log/test.log +410 -0
  139. data/spec/dummy/test/system/action_cable_subscription_test.rb +4 -0
  140. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-x/-xYZjAnuuzgR79fcznLTQtSdh6AARxu8FcQ_J6p7L3U.cache +0 -0
  141. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/13/13HiV12xyoQvT-1L39ZzLwMZxjyaGMiENmfw7f-QTIc.cache +0 -0
  142. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/3W/3Wtf5pCWdqq0AB-iB0Y9uUNrTkruRxIEf1XFn_BETU0.cache +1 -0
  143. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/5i/5iguGafb4hOn8262Kn8Q37ogNN9MxxQKGKNzHAzUcvI.cache +1 -0
  144. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8m/8mj2T6yy847Mc2Z7k3Xzh8O91hhVJt3NrPe8ASNDlIA.cache +1 -0
  145. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/DT/DTQyMpr4ABZYQetsdRJ5A7S4jf1r3ie4FGOR7GZBNSs.cache +3 -0
  146. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Dq/DqJ5_yJPrP5iLlOQyTQsjAVI5FE5LCVDkED0f7GgsSo.cache +3 -0
  147. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F8/F8MUNRzORGFgr329fNM0xLaoWCXdv3BIalT7dsvLfjs.cache +0 -0
  148. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/KB/KB07ZaKNC5uXJ7TjLi-WqnY6g7dq8wWp_8N3HNjBNxg.cache +0 -0
  149. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Rw/RwDuCV-XpnCtjNkvhpJfBuxXMk0b5AD3L9eR6M-wcy0.cache +3 -0
  150. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/UL/ULdjhhb0bRuqmaG7XSZlFYzGYCXTDnqZuJBTWRlzqgw.cache +0 -0
  151. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Up/UpPNgh0yYoUsyMDh5zWqe_U6qJIyTC6-dxMMAs1vvlM.cache +1 -0
  152. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Wg/Wguh-szFGTI1gaL6npYwPekMXflugRei7F_mOyRucXg.cache +0 -0
  153. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/X-/X-khLYMA9mqFRPg3zAi86mREDxpKl4bdKYp3uF6WHos.cache +0 -0
  154. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/bi/BIkdhfxsezxM4q-HZ4oCNTq97WEJTigcq0tpX2cDvbY.cache +0 -0
  155. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ff/FfxmA4CMHQZT7exx0G7NS1Wpcnny0vzp-Jhc2H36bp8.cache +1 -0
  156. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gE/gEiiG4GZNy_djEjK2pHm_NgA-gyhLZhdQvo0Yt96GqE.cache +0 -0
  157. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gn/gnA9ZSqpjccNL2m8pe_jBvY6SinXlCzXDWyop83Od8s.cache +1 -0
  158. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/lO/lOAan3cMwCE_Hli6gsDML88xFNfn0nxPmvrSkW7eEOw.cache +1 -0
  159. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/m1/M1pv8MJEPLXGLvS8QxVh3DSO9cI4mRt5FHFWdrvUj6o.cache +2 -0
  160. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/m7/m77qH7ZqH0_0SmwJbiKGDd-aLau1Dav847DC6ge46zY.cache +1 -0
  161. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/sj/sjRjnjRB37lH2vrgtkdJ8Cz84__IJ978IuKTM7HcztI.cache +0 -0
  162. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/um/um1JrirR4hJhK-1rE-HywlyCi5ibgxHVrReiujZBWJM.cache +1 -0
  163. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/v4/v4fwVytD7ITcE0_GDbslZEYud8a5Okm85fV1o7SDl6g.cache +0 -0
  164. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/v_/v_0PAQt0iipQjFP5zjgkkk9Stnpf4VzvnMv67d1Keuw.cache +1 -0
  165. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wd/wdT9U4MKxe1PyqNjVuCKMpCl3dxGCIRJIlwUTfh2DQU.cache +1 -0
  166. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xI/xIaxut_fEIhKBDqljTNwYaADK9kj3gG0ESrfHs-5_og.cache +3 -0
  167. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/y0/y0SJOqIx2fn1SKqOkAihsQow0trRJrSIyAswufVuoA8.cache +0 -0
  168. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/zg/zgpzeaX-KZErHyGJ1aBH3ZusweNXMneVZule88XsIJI.cache +1 -0
  169. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/zy/zYFltDy-8VC-uKq2BVEiJJyYXNFvVzAKuMlR3ZIYZsk.cache +0 -0
  170. data/spec/dummy/tmp/screenshots/failures_test_it_handles_subscriptions.png +0 -0
  171. data/spec/fixtures/upgrader/account.original.rb +19 -0
  172. data/spec/fixtures/upgrader/account.transformed.rb +20 -0
  173. data/spec/fixtures/upgrader/blame_range.original.rb +43 -0
  174. data/spec/fixtures/upgrader/blame_range.transformed.rb +30 -0
  175. data/spec/fixtures/upgrader/date_time.original.rb +24 -0
  176. data/spec/fixtures/upgrader/date_time.transformed.rb +23 -0
  177. data/spec/fixtures/upgrader/delete_project.original.rb +28 -0
  178. data/spec/fixtures/upgrader/delete_project.transformed.rb +27 -0
  179. data/spec/fixtures/upgrader/gist_order_field.original.rb +14 -0
  180. data/spec/fixtures/upgrader/gist_order_field.transformed.rb +13 -0
  181. data/spec/fixtures/upgrader/increment_count.original.rb +59 -0
  182. data/spec/fixtures/upgrader/increment_count.transformed.rb +50 -0
  183. data/spec/fixtures/upgrader/photo.original.rb +10 -0
  184. data/spec/fixtures/upgrader/photo.transformed.rb +12 -0
  185. data/spec/fixtures/upgrader/release_order.original.rb +15 -0
  186. data/spec/fixtures/upgrader/release_order.transformed.rb +14 -0
  187. data/spec/fixtures/upgrader/starrable.original.rb +49 -0
  188. data/spec/fixtures/upgrader/starrable.transformed.rb +46 -0
  189. data/spec/fixtures/upgrader/subscribable.original.rb +55 -0
  190. data/spec/fixtures/upgrader/subscribable.transformed.rb +51 -0
  191. data/spec/fixtures/upgrader/type_x.original.rb +65 -0
  192. data/spec/fixtures/upgrader/type_x.transformed.rb +56 -0
  193. data/spec/generators/graphql/function_generator_spec.rb +26 -0
  194. data/spec/generators/graphql/install_generator_spec.rb +1 -1
  195. data/spec/generators/graphql/loader_generator_spec.rb +24 -0
  196. data/spec/graphql/analysis/max_query_complexity_spec.rb +3 -3
  197. data/spec/graphql/analysis/max_query_depth_spec.rb +3 -3
  198. data/spec/graphql/argument_spec.rb +21 -0
  199. data/spec/graphql/backtrace_spec.rb +10 -0
  200. data/spec/graphql/base_type_spec.rb +42 -0
  201. data/spec/graphql/boolean_type_spec.rb +3 -3
  202. data/spec/graphql/directive_spec.rb +3 -1
  203. data/spec/graphql/enum_type_spec.rb +18 -5
  204. data/spec/graphql/execution/execute_spec.rb +4 -4
  205. data/spec/graphql/execution/instrumentation_spec.rb +165 -0
  206. data/spec/graphql/execution/multiplex_spec.rb +2 -2
  207. data/spec/graphql/execution_error_spec.rb +18 -0
  208. data/spec/graphql/float_type_spec.rb +2 -2
  209. data/spec/graphql/id_type_spec.rb +1 -1
  210. data/spec/graphql/input_object_type_spec.rb +15 -2
  211. data/spec/graphql/int_type_spec.rb +2 -2
  212. data/spec/graphql/interface_type_spec.rb +12 -0
  213. data/spec/graphql/internal_representation/rewrite_spec.rb +2 -2
  214. data/spec/graphql/introspection/schema_type_spec.rb +2 -0
  215. data/spec/graphql/language/block_string_spec.rb +70 -0
  216. data/spec/graphql/language/document_from_schema_definition_spec.rb +770 -0
  217. data/spec/graphql/language/generation_spec.rb +21 -186
  218. data/spec/graphql/language/lexer_spec.rb +21 -1
  219. data/spec/graphql/language/nodes_spec.rb +21 -12
  220. data/spec/graphql/language/parser_spec.rb +1 -1
  221. data/spec/graphql/language/printer_spec.rb +203 -0
  222. data/spec/graphql/object_type_spec.rb +22 -0
  223. data/spec/graphql/query/arguments_spec.rb +25 -15
  224. data/spec/graphql/query/context_spec.rb +18 -0
  225. data/spec/graphql/query/executor_spec.rb +2 -1
  226. data/spec/graphql/query/serial_execution/value_resolution_spec.rb +2 -8
  227. data/spec/graphql/query/variables_spec.rb +42 -1
  228. data/spec/graphql/query_spec.rb +31 -5
  229. data/spec/graphql/rake_task_spec.rb +3 -1
  230. data/spec/graphql/relay/base_connection_spec.rb +1 -1
  231. data/spec/graphql/relay/connection_instrumentation_spec.rb +2 -2
  232. data/spec/graphql/relay/connection_resolve_spec.rb +1 -1
  233. data/spec/graphql/relay/connection_type_spec.rb +1 -1
  234. data/spec/graphql/relay/mongo_relation_connection_spec.rb +474 -0
  235. data/spec/graphql/relay/mutation_spec.rb +9 -7
  236. data/spec/graphql/relay/range_add_spec.rb +5 -1
  237. data/spec/graphql/relay/relation_connection_spec.rb +65 -1
  238. data/spec/graphql/schema/argument_spec.rb +87 -0
  239. data/spec/graphql/schema/build_from_definition_spec.rb +89 -5
  240. data/spec/graphql/schema/enum_spec.rb +74 -0
  241. data/spec/graphql/schema/field_spec.rb +225 -0
  242. data/spec/graphql/schema/finder_spec.rb +135 -0
  243. data/spec/graphql/schema/input_object_spec.rb +111 -0
  244. data/spec/graphql/schema/instrumentation_spec.rb +40 -0
  245. data/spec/graphql/schema/interface_spec.rb +185 -0
  246. data/spec/graphql/schema/introspection_system_spec.rb +39 -0
  247. data/spec/graphql/schema/member/accepts_definition_spec.rb +111 -0
  248. data/spec/graphql/schema/member/build_type_spec.rb +17 -0
  249. data/spec/graphql/schema/member/has_fields_spec.rb +129 -0
  250. data/spec/graphql/schema/member/type_system_helpers_spec.rb +63 -0
  251. data/spec/graphql/schema/mutation_spec.rb +148 -0
  252. data/spec/graphql/schema/object_spec.rb +175 -0
  253. data/spec/graphql/schema/printer_spec.rb +111 -15
  254. data/spec/graphql/schema/relay_classic_mutation_spec.rb +38 -0
  255. data/spec/graphql/schema/rescue_middleware_spec.rb +11 -0
  256. data/spec/graphql/schema/resolver_spec.rb +131 -0
  257. data/spec/graphql/schema/scalar_spec.rb +95 -0
  258. data/spec/graphql/schema/traversal_spec.rb +31 -0
  259. data/spec/graphql/schema/union_spec.rb +65 -0
  260. data/spec/graphql/schema/validation_spec.rb +1 -1
  261. data/spec/graphql/schema/warden_spec.rb +11 -11
  262. data/spec/graphql/schema_spec.rb +55 -12
  263. data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +10 -2
  264. data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +2 -2
  265. data/spec/graphql/string_type_spec.rb +3 -3
  266. data/spec/graphql/subscriptions_spec.rb +273 -184
  267. data/spec/graphql/tracing/active_support_notifications_tracing_spec.rb +1 -1
  268. data/spec/graphql/tracing/new_relic_tracing_spec.rb +47 -0
  269. data/spec/graphql/tracing/platform_tracing_spec.rb +60 -1
  270. data/spec/graphql/union_type_spec.rb +1 -1
  271. data/spec/graphql/upgrader/member_spec.rb +516 -0
  272. data/spec/graphql/upgrader/schema_spec.rb +82 -0
  273. data/spec/spec_helper.rb +8 -0
  274. data/spec/support/dummy/schema.rb +53 -24
  275. data/spec/support/jazz.rb +544 -0
  276. data/spec/support/lazy_helpers.rb +21 -23
  277. data/spec/support/new_relic.rb +24 -0
  278. data/spec/support/star_trek/data.rb +109 -0
  279. data/spec/support/star_trek/schema.rb +388 -0
  280. data/spec/support/star_wars/data.rb +6 -7
  281. data/spec/support/star_wars/schema.rb +127 -171
  282. metadata +233 -11
  283. data/lib/graphql/introspection/arguments_field.rb +0 -7
  284. data/lib/graphql/introspection/enum_values_field.rb +0 -18
  285. data/lib/graphql/introspection/fields_field.rb +0 -13
  286. data/lib/graphql/introspection/input_fields_field.rb +0 -12
  287. data/lib/graphql/introspection/interfaces_field.rb +0 -11
  288. data/lib/graphql/introspection/of_type_field.rb +0 -6
  289. data/lib/graphql/introspection/possible_types_field.rb +0 -11
@@ -34,6 +34,9 @@
34
34
  RBRACKET = ']';
35
35
  COLON = ':';
36
36
  QUOTE = '"';
37
+ BLOCK_QUOTE = '"""';
38
+ ESCAPED_BLOCK_QUOTE = '\\"""';
39
+ BLOCK_STRING_CHAR = (ESCAPED_BLOCK_QUOTE | ^'"""');
37
40
  ESCAPED_QUOTE = '\\"';
38
41
  STRING_CHAR = (ESCAPED_QUOTE | ^'"');
39
42
  VAR_SIGN = '$';
@@ -42,9 +45,10 @@
42
45
  EQUALS = '=';
43
46
  BANG = '!';
44
47
  PIPE = '|';
48
+ AMP = '&';
45
49
 
46
50
  QUOTED_STRING = QUOTE STRING_CHAR* QUOTE;
47
-
51
+ BLOCK_STRING = BLOCK_QUOTE BLOCK_STRING_CHAR* BLOCK_QUOTE;
48
52
  # catch-all for anything else. must be at the bottom for precedence.
49
53
  UNKNOWN_CHAR = /./;
50
54
 
@@ -75,13 +79,15 @@
75
79
  RBRACKET => { emit(:RBRACKET, ts, te, meta) };
76
80
  LBRACKET => { emit(:LBRACKET, ts, te, meta) };
77
81
  COLON => { emit(:COLON, ts, te, meta) };
78
- QUOTED_STRING => { emit_string(ts + 1, te - 1, meta) };
82
+ QUOTED_STRING => { emit_string(ts, te, meta, block: false) };
83
+ BLOCK_STRING => { emit_string(ts, te, meta, block: true) };
79
84
  VAR_SIGN => { emit(:VAR_SIGN, ts, te, meta) };
80
85
  DIR_SIGN => { emit(:DIR_SIGN, ts, te, meta) };
81
86
  ELLIPSIS => { emit(:ELLIPSIS, ts, te, meta) };
82
87
  EQUALS => { emit(:EQUALS, ts, te, meta) };
83
88
  BANG => { emit(:BANG, ts, te, meta) };
84
89
  PIPE => { emit(:PIPE, ts, te, meta) };
90
+ AMP => { emit(:AMP, ts, te, meta) };
85
91
  IDENTIFIER => { emit(:IDENTIFIER, ts, te, meta) };
86
92
  COMMENT => { record_comment(ts, te, meta) };
87
93
 
@@ -188,8 +194,13 @@ module GraphQL
188
194
  PACK_DIRECTIVE = "c*"
189
195
  UTF_8_ENCODING = "UTF-8"
190
196
 
191
- def self.emit_string(ts, te, meta)
192
- value = meta[:data][ts...te].pack(PACK_DIRECTIVE).force_encoding(UTF_8_ENCODING)
197
+ def self.emit_string(ts, te, meta, block:)
198
+ quotes_length = block ? 3 : 1
199
+ ts += quotes_length
200
+ value = meta[:data][ts...te - quotes_length].pack(PACK_DIRECTIVE).force_encoding(UTF_8_ENCODING)
201
+ if block
202
+ value = GraphQL::Language::BlockString.trim_whitespace(value)
203
+ end
193
204
  if value !~ VALID_STRING
194
205
  meta[:tokens] << token = GraphQL::Language::Token.new(
195
206
  name: :BAD_UNICODE_ESCAPE,
@@ -8,7 +8,16 @@ 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
+
11
12
  class AbstractNode
13
+ module Scalars # :nodoc:
14
+ module Name
15
+ def scalars
16
+ super + [name]
17
+ end
18
+ end
19
+ end
20
+
12
21
  attr_accessor :line, :col, :filename
13
22
 
14
23
  # Initialize a node by extracting its position,
@@ -41,79 +50,50 @@ module GraphQL
41
50
 
42
51
  # @return [Array<GraphQL::Language::Nodes::AbstractNode>] all nodes in the tree below this one
43
52
  def children
44
- self.class.child_attributes
45
- .map { |attr_name| public_send(attr_name) }
46
- .flatten
53
+ []
47
54
  end
48
55
 
49
56
  # @return [Array<Integer, Float, String, Boolean, Array>] Scalar values attached to this node
50
57
  def scalars
51
- self.class.scalar_attributes
52
- .map { |attr_name| public_send(attr_name) }
53
- end
54
-
55
- class << self
56
- # A node subclass inherits `scalar_attributes`
57
- # and `child_attributes` from its parent
58
- def inherited(subclass)
59
- subclass.scalar_attributes(*@scalar_attributes)
60
- subclass.child_attributes(*@child_attributes)
61
- end
62
-
63
- # define `attr_names` as places where scalars may be attached to this node
64
- def scalar_attributes(*attr_names)
65
- @scalar_attributes ||= []
66
- @scalar_attributes += attr_names
67
- end
68
-
69
- # define `attr_names` as places where child nodes may be attached to this node
70
- def child_attributes(*attr_names)
71
- @child_attributes ||= []
72
- @child_attributes += attr_names
73
- end
58
+ []
74
59
  end
75
60
 
76
61
  def position
77
62
  [line, col]
78
63
  end
79
64
 
80
- def to_query_string
81
- Generation.generate(self)
65
+ def to_query_string(printer: GraphQL::Language::Printer.new)
66
+ printer.print(self)
82
67
  end
83
68
  end
84
69
 
85
70
  # Base class for non-null type names and list type names
86
71
  class WrapperType < AbstractNode
87
72
  attr_accessor :of_type
88
- scalar_attributes :of_type
89
73
 
90
74
  def initialize_node(of_type: nil)
91
75
  @of_type = of_type
92
76
  end
93
77
 
94
- def children
95
- [].freeze
78
+ def scalars
79
+ [of_type]
96
80
  end
97
81
  end
98
82
 
99
83
  # Base class for nodes whose only value is a name (no child nodes or other scalars)
100
84
  class NameOnlyNode < AbstractNode
85
+ include Scalars::Name
86
+
101
87
  attr_accessor :name
102
- scalar_attributes :name
103
88
 
104
89
  def initialize_node(name: nil)
105
90
  @name = name
106
91
  end
107
-
108
- def children
109
- [].freeze
110
- end
111
92
  end
112
93
 
113
94
  # A key-value pair for a field's inputs
114
95
  class Argument < AbstractNode
115
96
  attr_accessor :name, :value
116
- scalar_attributes :name, :value
117
97
 
118
98
  # @!attribute name
119
99
  # @return [String] the key for this argument
@@ -126,15 +106,20 @@ module GraphQL
126
106
  @value = value
127
107
  end
128
108
 
109
+ def scalars
110
+ [name, value]
111
+ end
112
+
129
113
  def children
130
114
  [value].flatten.select { |v| v.is_a?(AbstractNode) }
131
115
  end
132
116
  end
133
117
 
134
118
  class Directive < AbstractNode
119
+ include Scalars::Name
120
+
135
121
  attr_accessor :name, :arguments
136
- scalar_attributes :name
137
- child_attributes :arguments
122
+ alias :children :arguments
138
123
 
139
124
  def initialize_node(name: nil, arguments: [])
140
125
  @name = name
@@ -143,9 +128,9 @@ module GraphQL
143
128
  end
144
129
 
145
130
  class DirectiveDefinition < AbstractNode
131
+ include Scalars::Name
132
+
146
133
  attr_accessor :name, :arguments, :locations, :description
147
- scalar_attributes :name
148
- child_attributes :arguments, :locations
149
134
 
150
135
  def initialize_node(name: nil, arguments: [], locations: [], description: nil)
151
136
  @name = name
@@ -153,6 +138,10 @@ module GraphQL
153
138
  @locations = locations
154
139
  @description = description
155
140
  end
141
+
142
+ def children
143
+ arguments + locations
144
+ end
156
145
  end
157
146
 
158
147
  # This is the AST root for normal queries
@@ -164,9 +153,18 @@ module GraphQL
164
153
  # document.to_query_string
165
154
  # # { ... }
166
155
  #
156
+ # @example Creating a custom string from a document
157
+ # class VariableScrubber < GraphQL::Language::Printer
158
+ # def print_argument(arg)
159
+ # "#{arg.name}: <HIDDEN>"
160
+ # end
161
+ # end
162
+ #
163
+ # document.to_query_string(printer: VariableSrubber.new)
164
+ #
167
165
  class Document < AbstractNode
168
166
  attr_accessor :definitions
169
- child_attributes :definitions
167
+ alias :children :definitions
170
168
 
171
169
  # @!attribute definitions
172
170
  # @return [Array<OperationDefinition, FragmentDefinition>] top-level GraphQL units: operations or fragments
@@ -188,8 +186,6 @@ module GraphQL
188
186
  # A single selection in a GraphQL query.
189
187
  class Field < AbstractNode
190
188
  attr_accessor :name, :alias, :arguments, :directives, :selections
191
- scalar_attributes :name, :alias
192
- child_attributes :arguments, :directives, :selections
193
189
 
194
190
  # @!attribute selections
195
191
  # @return [Array<Nodes::Field>] Selections on this object (or empty array if this is a scalar field)
@@ -202,13 +198,19 @@ module GraphQL
202
198
  @directives = directives
203
199
  @selections = selections
204
200
  end
201
+
202
+ def scalars
203
+ [name, self.alias]
204
+ end
205
+
206
+ def children
207
+ arguments + directives + selections
208
+ end
205
209
  end
206
210
 
207
211
  # A reusable fragment, defined at document-level.
208
212
  class FragmentDefinition < AbstractNode
209
213
  attr_accessor :name, :type, :directives, :selections
210
- scalar_attributes :name, :type
211
- child_attributes :directives, :selections
212
214
 
213
215
  # @!attribute name
214
216
  # @return [String] the identifier for this fragment, which may be applied with `...#{name}`
@@ -221,13 +223,22 @@ module GraphQL
221
223
  @directives = directives
222
224
  @selections = selections
223
225
  end
226
+
227
+ def children
228
+ directives + selections
229
+ end
230
+
231
+ def scalars
232
+ [name, type]
233
+ end
224
234
  end
225
235
 
226
236
  # Application of a named fragment in a selection
227
237
  class FragmentSpread < AbstractNode
238
+ include Scalars::Name
239
+
228
240
  attr_accessor :name, :directives
229
- scalar_attributes :name
230
- child_attributes :directives
241
+ alias :children :directives
231
242
 
232
243
  # @!attribute name
233
244
  # @return [String] The identifier of the fragment to apply, corresponds with {FragmentDefinition#name}
@@ -241,8 +252,6 @@ module GraphQL
241
252
  # An unnamed fragment, defined directly in the query with `... { }`
242
253
  class InlineFragment < AbstractNode
243
254
  attr_accessor :type, :directives, :selections
244
- scalar_attributes :type
245
- child_attributes :directives, :selections
246
255
 
247
256
  # @!attribute type
248
257
  # @return [String, nil] Name of the type this fragment applies to, or `nil` if this fragment applies to any type
@@ -252,12 +261,20 @@ module GraphQL
252
261
  @directives = directives
253
262
  @selections = selections
254
263
  end
264
+
265
+ def children
266
+ directives + selections
267
+ end
268
+
269
+ def scalars
270
+ [type]
271
+ end
255
272
  end
256
273
 
257
274
  # A collection of key-value inputs which may be a field argument
258
275
  class InputObject < AbstractNode
259
276
  attr_accessor :arguments
260
- child_attributes :arguments
277
+ alias :children :arguments
261
278
 
262
279
  # @!attribute arguments
263
280
  # @return [Array<Nodes::Argument>] A list of key-value pairs inside this input object
@@ -278,13 +295,16 @@ module GraphQL
278
295
  private
279
296
 
280
297
  def serialize_value_for_hash(value)
281
- if value.is_a? InputObject
298
+ case value
299
+ when InputObject
282
300
  value.to_h
283
- elsif value.is_a? Array
301
+ when Array
284
302
  value.map do |v|
285
303
  serialize_value_for_hash v
286
304
  end
287
- elsif value.is_a? NullValue
305
+ when Enum
306
+ value.name
307
+ when NullValue
288
308
  nil
289
309
  else
290
310
  value
@@ -304,8 +324,6 @@ module GraphQL
304
324
  # May be explicitly typed (eg `mutation { ... }`) or implicitly a query (eg `{ ... }`).
305
325
  class OperationDefinition < AbstractNode
306
326
  attr_accessor :operation_type, :name, :variables, :directives, :selections
307
- scalar_attributes :operation_type, :name
308
- child_attributes :variables, :directives, :selections
309
327
 
310
328
  # @!attribute variables
311
329
  # @return [Array<VariableDefinition>] Variable definitions for this operation
@@ -326,6 +344,14 @@ module GraphQL
326
344
  @directives = directives
327
345
  @selections = selections
328
346
  end
347
+
348
+ def children
349
+ variables + directives + selections
350
+ end
351
+
352
+ def scalars
353
+ [operation_type, name]
354
+ end
329
355
  end
330
356
 
331
357
  # A type name, used for variable definitions
@@ -334,7 +360,6 @@ module GraphQL
334
360
  # An operation-level query variable
335
361
  class VariableDefinition < AbstractNode
336
362
  attr_accessor :name, :type, :default_value
337
- scalar_attributes :name, :type, :default_value
338
363
 
339
364
  # @!attribute default_value
340
365
  # @return [String, Integer, Float, Boolean, Array, NullValue] A Ruby value to use if no other value is provided
@@ -350,26 +375,37 @@ module GraphQL
350
375
  @type = type
351
376
  @default_value = default_value
352
377
  end
378
+
379
+ def scalars
380
+ [name, type, default_value]
381
+ end
353
382
  end
354
383
 
355
384
  # Usage of a variable in a query. Name does _not_ include `$`.
356
385
  class VariableIdentifier < NameOnlyNode; end
357
386
 
358
387
  class SchemaDefinition < AbstractNode
359
- attr_accessor :query, :mutation, :subscription
360
- scalar_attributes :query, :mutation, :subscription
388
+ attr_accessor :query, :mutation, :subscription, :directives
361
389
 
362
- def initialize_node(query: nil, mutation: nil, subscription: nil)
390
+ def initialize_node(query: nil, mutation: nil, subscription: nil, directives: [])
363
391
  @query = query
364
392
  @mutation = mutation
365
393
  @subscription = subscription
394
+ @directives = directives
395
+ end
396
+
397
+ def scalars
398
+ [query, mutation, subscription]
366
399
  end
400
+
401
+ alias :children :directives
367
402
  end
368
403
 
369
404
  class ScalarTypeDefinition < AbstractNode
405
+ include Scalars::Name
406
+
370
407
  attr_accessor :name, :directives, :description
371
- scalar_attributes :name
372
- child_attributes :directives
408
+ alias :children :directives
373
409
 
374
410
  def initialize_node(name:, directives: [], description: nil)
375
411
  @name = name
@@ -379,9 +415,9 @@ module GraphQL
379
415
  end
380
416
 
381
417
  class ObjectTypeDefinition < AbstractNode
418
+ include Scalars::Name
419
+
382
420
  attr_accessor :name, :interfaces, :fields, :directives, :description
383
- scalar_attributes :name
384
- child_attributes :interfaces, :fields, :directives
385
421
 
386
422
  def initialize_node(name:, interfaces:, fields:, directives: [], description: nil)
387
423
  @name = name
@@ -390,12 +426,15 @@ module GraphQL
390
426
  @fields = fields
391
427
  @description = description
392
428
  end
429
+
430
+ def children
431
+ interfaces + fields + directives
432
+ end
393
433
  end
394
434
 
395
435
  class InputValueDefinition < AbstractNode
396
436
  attr_accessor :name, :type, :default_value, :directives,:description
397
- scalar_attributes :name, :type, :default_value
398
- child_attributes :directives
437
+ alias :children :directives
399
438
 
400
439
  def initialize_node(name:, type:, default_value: nil, directives: [], description: nil)
401
440
  @name = name
@@ -404,12 +443,14 @@ module GraphQL
404
443
  @directives = directives
405
444
  @description = description
406
445
  end
446
+
447
+ def scalars
448
+ [name, type, default_value]
449
+ end
407
450
  end
408
451
 
409
452
  class FieldDefinition < AbstractNode
410
453
  attr_accessor :name, :arguments, :type, :directives, :description
411
- scalar_attributes :name, :type
412
- child_attributes :arguments, :directives
413
454
 
414
455
  def initialize_node(name:, arguments:, type:, directives: [], description: nil)
415
456
  @name = name
@@ -418,12 +459,20 @@ module GraphQL
418
459
  @directives = directives
419
460
  @description = description
420
461
  end
462
+
463
+ def children
464
+ arguments + directives
465
+ end
466
+
467
+ def scalars
468
+ [name, type]
469
+ end
421
470
  end
422
471
 
423
472
  class InterfaceTypeDefinition < AbstractNode
473
+ include Scalars::Name
474
+
424
475
  attr_accessor :name, :fields, :directives, :description
425
- scalar_attributes :name
426
- child_attributes :fields, :directives
427
476
 
428
477
  def initialize_node(name:, fields:, directives: [], description: nil)
429
478
  @name = name
@@ -431,12 +480,16 @@ module GraphQL
431
480
  @directives = directives
432
481
  @description = description
433
482
  end
483
+
484
+ def children
485
+ fields + directives
486
+ end
434
487
  end
435
488
 
436
489
  class UnionTypeDefinition < AbstractNode
490
+ include Scalars::Name
491
+
437
492
  attr_accessor :name, :types, :directives, :description
438
- scalar_attributes :name
439
- child_attributes :types, :directives
440
493
 
441
494
  def initialize_node(name:, types:, directives: [], description: nil)
442
495
  @name = name
@@ -444,12 +497,16 @@ module GraphQL
444
497
  @directives = directives
445
498
  @description = description
446
499
  end
500
+
501
+ def children
502
+ types + directives
503
+ end
447
504
  end
448
505
 
449
506
  class EnumTypeDefinition < AbstractNode
507
+ include Scalars::Name
508
+
450
509
  attr_accessor :name, :values, :directives, :description
451
- scalar_attributes :name
452
- child_attributes :values, :directives
453
510
 
454
511
  def initialize_node(name:, values:, directives: [], description: nil)
455
512
  @name = name
@@ -457,12 +514,17 @@ module GraphQL
457
514
  @directives = directives
458
515
  @description = description
459
516
  end
517
+
518
+ def children
519
+ values + directives
520
+ end
460
521
  end
461
522
 
462
523
  class EnumValueDefinition < AbstractNode
524
+ include Scalars::Name
525
+
463
526
  attr_accessor :name, :directives, :description
464
- scalar_attributes :name
465
- child_attributes :directives
527
+ alias :children :directives
466
528
 
467
529
  def initialize_node(name:, directives: [], description: nil)
468
530
  @name = name
@@ -472,9 +534,10 @@ module GraphQL
472
534
  end
473
535
 
474
536
  class InputObjectTypeDefinition < AbstractNode
537
+ include Scalars::Name
538
+
475
539
  attr_accessor :name, :fields, :directives, :description
476
- scalar_attributes :name
477
- child_attributes :fields
540
+ alias :children :fields
478
541
 
479
542
  def initialize_node(name:, fields:, directives: [], description: nil)
480
543
  @name = name