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
@@ -0,0 +1,280 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ module Language
4
+ # @api private
5
+ #
6
+ # {GraphQL::Language::DocumentFromSchemaDefinition} is used to convert a {GraphQL::Schema} object
7
+ # To a {GraphQL::Language::Document} AST node.
8
+ #
9
+ # @param context [Hash]
10
+ # @param only [<#call(member, ctx)>]
11
+ # @param except [<#call(member, ctx)>]
12
+ # @param include_introspection_types [Boolean] Whether or not to include introspection types in the AST
13
+ # @param include_built_in_scalars [Boolean] Whether or not to include built in scalars in the AST
14
+ # @param include_built_in_directives [Boolean] Whether or not to include built in diirectives in the AST
15
+ class DocumentFromSchemaDefinition
16
+ def initialize(
17
+ schema, context: nil, only: nil, except: nil, include_introspection_types: false,
18
+ include_built_in_directives: false, include_built_in_scalars: false, always_include_schema: false
19
+ )
20
+ @schema = schema
21
+ @always_include_schema = always_include_schema
22
+ @include_introspection_types = include_introspection_types
23
+ @include_built_in_scalars = include_built_in_scalars
24
+ @include_built_in_directives = include_built_in_directives
25
+
26
+ @warden = GraphQL::Schema::Warden.new(
27
+ GraphQL::Filter.new(only: only, except: except),
28
+ schema: @schema,
29
+ context: context,
30
+ )
31
+ end
32
+
33
+ def document
34
+ GraphQL::Language::Nodes::Document.new(
35
+ definitions: build_definition_nodes
36
+ )
37
+ end
38
+
39
+ def build_schema_node
40
+ GraphQL::Language::Nodes::SchemaDefinition.new(
41
+ query: warden.root_type_for_operation("query"),
42
+ mutation: warden.root_type_for_operation("mutation"),
43
+ subscription: warden.root_type_for_operation("subscription"),
44
+ # This only supports directives from parsing,
45
+ # use a custom printer to add to this list.
46
+ directives: @schema.ast_node ? @schema.ast_node.directives : [],
47
+ )
48
+ end
49
+
50
+ def build_object_type_node(object_type)
51
+ GraphQL::Language::Nodes::ObjectTypeDefinition.new(
52
+ name: object_type.name,
53
+ interfaces: warden.interfaces(object_type).sort_by(&:name).map { |iface| build_type_name_node(iface) },
54
+ fields: build_field_nodes(warden.fields(object_type)),
55
+ description: object_type.description,
56
+ )
57
+ end
58
+
59
+ def build_field_node(field)
60
+ field_node = GraphQL::Language::Nodes::FieldDefinition.new(
61
+ name: field.name,
62
+ arguments: build_argument_nodes(warden.arguments(field)),
63
+ type: build_type_name_node(field.type),
64
+ description: field.description,
65
+ )
66
+
67
+ if field.deprecation_reason
68
+ field_node.directives << GraphQL::Language::Nodes::Directive.new(
69
+ name: GraphQL::Directive::DeprecatedDirective.name,
70
+ arguments: [GraphQL::Language::Nodes::Argument.new(name: "reason", value: field.deprecation_reason)]
71
+ )
72
+ end
73
+
74
+ field_node
75
+ end
76
+
77
+ def build_union_type_node(union_type)
78
+ GraphQL::Language::Nodes::UnionTypeDefinition.new(
79
+ name: union_type.name,
80
+ description: union_type.description,
81
+ types: warden.possible_types(union_type).sort_by(&:name).map { |type| build_type_name_node(type) }
82
+ )
83
+ end
84
+
85
+ def build_interface_type_node(interface_type)
86
+ GraphQL::Language::Nodes::InterfaceTypeDefinition.new(
87
+ name: interface_type.name,
88
+ description: interface_type.description,
89
+ fields: build_field_nodes(warden.fields(interface_type))
90
+ )
91
+ end
92
+
93
+ def build_enum_type_node(enum_type)
94
+ GraphQL::Language::Nodes::EnumTypeDefinition.new(
95
+ name: enum_type.name,
96
+ values: warden.enum_values(enum_type).sort_by(&:name).map do |enum_value|
97
+ build_enum_value_node(enum_value)
98
+ end,
99
+ description: enum_type.description,
100
+ )
101
+ end
102
+
103
+ def build_enum_value_node(enum_value)
104
+ enum_value_node = GraphQL::Language::Nodes::EnumValueDefinition.new(
105
+ name: enum_value.name,
106
+ description: enum_value.description,
107
+ )
108
+
109
+ if enum_value.deprecation_reason
110
+ enum_value_node.directives << GraphQL::Language::Nodes::Directive.new(
111
+ name: GraphQL::Directive::DeprecatedDirective.name,
112
+ arguments: [GraphQL::Language::Nodes::Argument.new(name: "reason", value: enum_value.deprecation_reason)]
113
+ )
114
+ end
115
+
116
+ enum_value_node
117
+ end
118
+
119
+ def build_scalar_type_node(scalar_type)
120
+ GraphQL::Language::Nodes::ScalarTypeDefinition.new(
121
+ name: scalar_type.name,
122
+ description: scalar_type.description,
123
+ )
124
+ end
125
+
126
+ def build_argument_node(argument)
127
+ argument_node = GraphQL::Language::Nodes::InputValueDefinition.new(
128
+ name: argument.name,
129
+ description: argument.description,
130
+ type: build_type_name_node(argument.type),
131
+ )
132
+
133
+ if argument.default_value?
134
+ argument_node.default_value = build_default_value(argument.default_value, argument.type)
135
+ end
136
+
137
+ argument_node
138
+ end
139
+
140
+ def build_input_object_node(input_object)
141
+ GraphQL::Language::Nodes::InputObjectTypeDefinition.new(
142
+ name: input_object.name,
143
+ fields: build_argument_nodes(warden.arguments(input_object)),
144
+ description: input_object.description,
145
+ )
146
+ end
147
+
148
+ def build_directive_node(directive)
149
+ GraphQL::Language::Nodes::DirectiveDefinition.new(
150
+ name: directive.name,
151
+ arguments: build_argument_nodes(warden.arguments(directive)),
152
+ locations: directive.locations.map(&:to_s),
153
+ description: directive.description,
154
+ )
155
+ end
156
+
157
+ def build_type_name_node(type)
158
+ case type
159
+ when GraphQL::ListType
160
+ GraphQL::Language::Nodes::ListType.new(
161
+ of_type: build_type_name_node(type.of_type)
162
+ )
163
+ when GraphQL::NonNullType
164
+ GraphQL::Language::Nodes::NonNullType.new(
165
+ of_type: build_type_name_node(type.of_type)
166
+ )
167
+ else
168
+ GraphQL::Language::Nodes::TypeName.new(name: type.name)
169
+ end
170
+ end
171
+
172
+ def build_default_value(default_value, type)
173
+ if default_value.nil?
174
+ return GraphQL::Language::Nodes::NullValue.new(name: "null")
175
+ end
176
+
177
+ case type
178
+ when GraphQL::ScalarType
179
+ type.coerce_isolated_result(default_value)
180
+ when EnumType
181
+ GraphQL::Language::Nodes::Enum.new(name: type.coerce_isolated_result(default_value))
182
+ when InputObjectType
183
+ GraphQL::Language::Nodes::InputObject.new(
184
+ arguments: default_value.to_h.map do |arg_name, arg_value|
185
+ arg_type = type.input_fields.fetch(arg_name.to_s).type
186
+ GraphQL::Language::Nodes::Argument.new(
187
+ name: arg_name,
188
+ value: build_default_value(arg_value, arg_type)
189
+ )
190
+ end
191
+ )
192
+ when NonNullType
193
+ build_default_value(default_value, type.of_type)
194
+ when ListType
195
+ default_value.to_a.map { |v| build_default_value(v, type.of_type) }
196
+ else
197
+ raise NotImplementedError, "Unexpected default value type #{type.inspect}"
198
+ end
199
+ end
200
+
201
+ def build_type_definition_node(type)
202
+ case type
203
+ when GraphQL::ObjectType
204
+ build_object_type_node(type)
205
+ when GraphQL::UnionType
206
+ build_union_type_node(type)
207
+ when GraphQL::InterfaceType
208
+ build_interface_type_node(type)
209
+ when GraphQL::ScalarType
210
+ build_scalar_type_node(type)
211
+ when GraphQL::EnumType
212
+ build_enum_type_node(type)
213
+ when GraphQL::InputObjectType
214
+ build_input_object_node(type)
215
+ else
216
+ raise TypeError
217
+ end
218
+ end
219
+
220
+ def build_argument_nodes(arguments)
221
+ arguments
222
+ .map { |arg| build_argument_node(arg) }
223
+ .sort_by(&:name)
224
+ end
225
+
226
+ def build_directive_nodes(directives)
227
+ if !include_built_in_directives
228
+ directives = directives.reject { |directive| directive.default_directive? }
229
+ end
230
+
231
+ directives
232
+ .map { |directive| build_directive_node(directive) }
233
+ .sort_by(&:name)
234
+ end
235
+
236
+ def build_definition_nodes
237
+ definitions = []
238
+ definitions << build_schema_node if include_schema_node?
239
+ definitions += build_directive_nodes(warden.directives)
240
+ definitions += build_type_definition_nodes(warden.types)
241
+ definitions
242
+ end
243
+
244
+ def build_type_definition_nodes(types)
245
+ if !include_introspection_types
246
+ types = types.reject { |type| type.introspection? }
247
+ end
248
+
249
+ if !include_built_in_scalars
250
+ types = types.reject { |type| type.default_scalar? }
251
+ end
252
+
253
+ types
254
+ .map { |type| build_type_definition_node(type) }
255
+ .sort_by(&:name)
256
+ end
257
+
258
+ def build_field_nodes(fields)
259
+ fields
260
+ .map { |field| build_field_node(field) }
261
+ .sort_by(&:name)
262
+ end
263
+
264
+ private
265
+
266
+ def include_schema_node?
267
+ always_include_schema || !schema_respects_root_name_conventions?(schema)
268
+ end
269
+
270
+ def schema_respects_root_name_conventions?(schema)
271
+ (schema.query.nil? || schema.query.name == 'Query') &&
272
+ (schema.mutation.nil? || schema.mutation.name == 'Mutation') &&
273
+ (schema.subscription.nil? || schema.subscription.name == 'Subscription')
274
+ end
275
+
276
+ attr_reader :schema, :warden, :always_include_schema,
277
+ :include_introspection_types, :include_built_in_directives, :include_built_in_scalars
278
+ end
279
+ end
280
+ end
@@ -14,189 +14,10 @@ module GraphQL
14
14
  #
15
15
  # @param node [GraphQL::Language::Nodes::AbstractNode] an AST node to recursively stringify
16
16
  # @param indent [String] Whitespace to add to each printed node
17
+ # @param printer [GraphQL::Language::Printer] An optional custom printer for printing AST nodes. Defaults to GraphQL::Language::Printer
17
18
  # @return [String] Valid GraphQL for `node`
18
- def generate(node, indent: "")
19
- case node
20
- when Nodes::Document
21
- node.definitions.map { |d| generate(d) }.join("\n\n")
22
- when Nodes::Argument
23
- "#{node.name}: #{generate(node.value)}".dup
24
- when Nodes::Directive
25
- out = "@#{node.name}".dup
26
- out << "(#{node.arguments.map { |a| generate(a) }.join(", ")})" if node.arguments.any?
27
- out
28
- when Nodes::Enum
29
- "#{node.name}".dup
30
- when Nodes::NullValue
31
- "null".dup
32
- when Nodes::Field
33
- out = "#{indent}".dup
34
- out << "#{node.alias}: " if node.alias
35
- out << "#{node.name}"
36
- out << "(#{node.arguments.map { |a| generate(a) }.join(", ")})" if node.arguments.any?
37
- out << generate_directives(node.directives)
38
- out << generate_selections(node.selections, indent: indent)
39
- out
40
- when Nodes::FragmentDefinition
41
- out = "#{indent}fragment #{node.name}".dup
42
- if node.type
43
- out << " on #{generate(node.type)}"
44
- end
45
- out << generate_directives(node.directives)
46
- out << generate_selections(node.selections, indent: indent)
47
- out
48
- when Nodes::FragmentSpread
49
- out = "#{indent}...#{node.name}".dup
50
- out << generate_directives(node.directives)
51
- out
52
- when Nodes::InlineFragment
53
- out = "#{indent}...".dup
54
- if node.type
55
- out << " on #{generate(node.type)}"
56
- end
57
- out << generate_directives(node.directives)
58
- out << generate_selections(node.selections, indent: indent)
59
- out
60
- when Nodes::InputObject
61
- generate(node.to_h)
62
- when Nodes::ListType
63
- "[#{generate(node.of_type)}]".dup
64
- when Nodes::NonNullType
65
- "#{generate(node.of_type)}!".dup
66
- when Nodes::OperationDefinition
67
- out = "#{indent}#{node.operation_type}".dup
68
- out << " #{node.name}" if node.name
69
- out << "(#{node.variables.map { |v| generate(v) }.join(", ")})" if node.variables.any?
70
- out << generate_directives(node.directives)
71
- out << generate_selections(node.selections, indent: indent)
72
- out
73
- when Nodes::TypeName
74
- "#{node.name}".dup
75
- when Nodes::VariableDefinition
76
- out = "$#{node.name}: #{generate(node.type)}".dup
77
- out << " = #{generate(node.default_value)}" unless node.default_value.nil?
78
- out
79
- when Nodes::VariableIdentifier
80
- "$#{node.name}".dup
81
- when Nodes::SchemaDefinition
82
- if (node.query.nil? || node.query == 'Query') &&
83
- (node.mutation.nil? || node.mutation == 'Mutation') &&
84
- (node.subscription.nil? || node.subscription == 'Subscription')
85
- return
86
- end
87
-
88
- out = "schema {\n".dup
89
- out << " query: #{node.query}\n" if node.query
90
- out << " mutation: #{node.mutation}\n" if node.mutation
91
- out << " subscription: #{node.subscription}\n" if node.subscription
92
- out << "}"
93
- when Nodes::ScalarTypeDefinition
94
- out = generate_description(node)
95
- out << "scalar #{node.name}"
96
- out << generate_directives(node.directives)
97
- when Nodes::ObjectTypeDefinition
98
- out = generate_description(node)
99
- out << "type #{node.name}"
100
- out << generate_directives(node.directives)
101
- out << " implements " << node.interfaces.map(&:name).join(", ") unless node.interfaces.empty?
102
- out << generate_field_definitions(node.fields)
103
- when Nodes::InputValueDefinition
104
- out = "#{node.name}: #{generate(node.type)}".dup
105
- out << " = #{generate(node.default_value)}" unless node.default_value.nil?
106
- out << generate_directives(node.directives)
107
- when Nodes::FieldDefinition
108
- out = node.name.dup
109
- unless node.arguments.empty?
110
- out << "(" << node.arguments.map{ |arg| generate(arg) }.join(", ") << ")"
111
- end
112
- out << ": #{generate(node.type)}"
113
- out << generate_directives(node.directives)
114
- when Nodes::InterfaceTypeDefinition
115
- out = generate_description(node)
116
- out << "interface #{node.name}"
117
- out << generate_directives(node.directives)
118
- out << generate_field_definitions(node.fields)
119
- when Nodes::UnionTypeDefinition
120
- out = generate_description(node)
121
- out << "union #{node.name}"
122
- out << generate_directives(node.directives)
123
- out << " = " + node.types.map(&:name).join(" | ")
124
- when Nodes::EnumTypeDefinition
125
- out = generate_description(node)
126
- out << "enum #{node.name}#{generate_directives(node.directives)} {\n"
127
- node.values.each.with_index do |value, i|
128
- out << generate_description(value, indent: ' ', first_in_block: i == 0)
129
- out << generate(value)
130
- end
131
- out << "}"
132
- when Nodes::EnumValueDefinition
133
- out = " #{node.name}".dup
134
- out << generate_directives(node.directives)
135
- out << "\n"
136
- when Nodes::InputObjectTypeDefinition
137
- out = generate_description(node)
138
- out << "input #{node.name}"
139
- out << generate_directives(node.directives)
140
- out << " {\n"
141
- node.fields.each.with_index do |field, i|
142
- out << generate_description(field, indent: ' ', first_in_block: i == 0)
143
- out << " #{generate(field)}\n"
144
- end
145
- out << "}"
146
- when Nodes::DirectiveDefinition
147
- out = generate_description(node)
148
- out << "directive @#{node.name}"
149
- out << "(#{node.arguments.map { |a| generate(a) }.join(", ")})" if node.arguments.any?
150
- out << " on #{node.locations.join(' | ')}"
151
- when Nodes::AbstractNode
152
- node.to_query_string(indent: indent)
153
- when FalseClass, Float, Integer, NilClass, String, TrueClass
154
- GraphQL::Language.serialize(node)
155
- when Array
156
- "[#{node.map { |v| generate(v) }.join(", ")}]".dup
157
- when Hash
158
- "{#{node.map { |k, v| "#{k}: #{generate(v)}" }.join(", ")}}".dup
159
- else
160
- raise TypeError
161
- end
162
- end
163
-
164
- private
165
-
166
- def generate_directives(directives)
167
- if directives.any?
168
- directives.map { |d| " #{generate(d)}" }.join
169
- else
170
- ""
171
- end
172
- end
173
-
174
- def generate_selections(selections, indent: "")
175
- if selections.any?
176
- out = " {\n".dup
177
- selections.each do |selection|
178
- out << generate(selection, indent: indent + " ") << "\n"
179
- end
180
- out << "#{indent}}"
181
- else
182
- ""
183
- end
184
- end
185
-
186
- def generate_description(node, indent: '', first_in_block: true)
187
- return ''.dup unless node.description
188
-
189
- description = indent != '' && !first_in_block ? "\n".dup : "".dup
190
- description << GraphQL::Language::Comments.commentize(node.description, indent: indent)
191
- end
192
-
193
- def generate_field_definitions(fields)
194
- out = " {\n".dup
195
- fields.each.with_index do |field, i|
196
- out << generate_description(field, indent: ' ', first_in_block: i == 0)
197
- out << " #{generate(field)}\n"
198
- end
199
- out << "}"
19
+ def generate(node, indent: "", printer: GraphQL::Language::Printer.new)
20
+ printer.print(node, indent: indent)
200
21
  end
201
22
  end
202
23
  end