graphql 0.16.0 → 2.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of graphql might be problematic. Click here for more details.

Files changed (490) hide show
  1. checksums.yaml +5 -5
  2. data/.yardopts +5 -0
  3. data/lib/generators/graphql/core.rb +69 -0
  4. data/lib/generators/graphql/enum_generator.rb +27 -0
  5. data/lib/generators/graphql/field_extractor.rb +31 -0
  6. data/lib/generators/graphql/input_generator.rb +50 -0
  7. data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
  8. data/lib/generators/graphql/install/templates/base_mutation.erb +10 -0
  9. data/lib/generators/graphql/install/templates/mutation_type.erb +12 -0
  10. data/lib/generators/graphql/install_generator.rb +197 -0
  11. data/lib/generators/graphql/interface_generator.rb +27 -0
  12. data/lib/generators/graphql/loader_generator.rb +21 -0
  13. data/lib/generators/graphql/mutation_create_generator.rb +22 -0
  14. data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
  15. data/lib/generators/graphql/mutation_generator.rb +30 -0
  16. data/lib/generators/graphql/mutation_update_generator.rb +22 -0
  17. data/lib/generators/graphql/object_generator.rb +50 -0
  18. data/lib/generators/graphql/orm_mutations_base.rb +40 -0
  19. data/lib/generators/graphql/relay.rb +49 -0
  20. data/lib/generators/graphql/relay_generator.rb +21 -0
  21. data/lib/generators/graphql/scalar_generator.rb +22 -0
  22. data/lib/generators/graphql/templates/base_argument.erb +6 -0
  23. data/lib/generators/graphql/templates/base_connection.erb +8 -0
  24. data/lib/generators/graphql/templates/base_edge.erb +8 -0
  25. data/lib/generators/graphql/templates/base_enum.erb +6 -0
  26. data/lib/generators/graphql/templates/base_field.erb +7 -0
  27. data/lib/generators/graphql/templates/base_input_object.erb +7 -0
  28. data/lib/generators/graphql/templates/base_interface.erb +9 -0
  29. data/lib/generators/graphql/templates/base_object.erb +7 -0
  30. data/lib/generators/graphql/templates/base_scalar.erb +6 -0
  31. data/lib/generators/graphql/templates/base_union.erb +6 -0
  32. data/lib/generators/graphql/templates/enum.erb +11 -0
  33. data/lib/generators/graphql/templates/graphql_controller.erb +52 -0
  34. data/lib/generators/graphql/templates/input.erb +9 -0
  35. data/lib/generators/graphql/templates/interface.erb +10 -0
  36. data/lib/generators/graphql/templates/loader.erb +19 -0
  37. data/lib/generators/graphql/templates/mutation.erb +16 -0
  38. data/lib/generators/graphql/templates/mutation_create.erb +20 -0
  39. data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
  40. data/lib/generators/graphql/templates/mutation_update.erb +21 -0
  41. data/lib/generators/graphql/templates/node_type.erb +9 -0
  42. data/lib/generators/graphql/templates/object.erb +10 -0
  43. data/lib/generators/graphql/templates/query_type.erb +15 -0
  44. data/lib/generators/graphql/templates/scalar.erb +17 -0
  45. data/lib/generators/graphql/templates/schema.erb +30 -0
  46. data/lib/generators/graphql/templates/union.erb +9 -0
  47. data/lib/generators/graphql/type_generator.rb +135 -0
  48. data/lib/generators/graphql/union_generator.rb +33 -0
  49. data/lib/graphql/analysis/ast/analyzer.rb +84 -0
  50. data/lib/graphql/analysis/ast/field_usage.rb +57 -0
  51. data/lib/graphql/analysis/ast/max_query_complexity.rb +22 -0
  52. data/lib/graphql/analysis/ast/max_query_depth.rb +22 -0
  53. data/lib/graphql/analysis/ast/query_complexity.rb +230 -0
  54. data/lib/graphql/analysis/ast/query_depth.rb +55 -0
  55. data/lib/graphql/analysis/ast/visitor.rb +269 -0
  56. data/lib/graphql/analysis/ast.rb +81 -0
  57. data/lib/graphql/analysis.rb +2 -5
  58. data/lib/graphql/analysis_error.rb +1 -0
  59. data/lib/graphql/backtrace/inspect_result.rb +50 -0
  60. data/lib/graphql/backtrace/table.rb +141 -0
  61. data/lib/graphql/backtrace/traced_error.rb +54 -0
  62. data/lib/graphql/backtrace/tracer.rb +80 -0
  63. data/lib/graphql/backtrace.rb +58 -0
  64. data/lib/graphql/coercion_error.rb +13 -0
  65. data/lib/graphql/dataloader/null_dataloader.rb +24 -0
  66. data/lib/graphql/dataloader/request.rb +19 -0
  67. data/lib/graphql/dataloader/request_all.rb +19 -0
  68. data/lib/graphql/dataloader/source.rb +164 -0
  69. data/lib/graphql/dataloader.rb +311 -0
  70. data/lib/graphql/date_encoding_error.rb +16 -0
  71. data/lib/graphql/deprecation.rb +9 -0
  72. data/lib/graphql/dig.rb +19 -0
  73. data/lib/graphql/execution/directive_checks.rb +37 -0
  74. data/lib/graphql/execution/errors.rb +93 -0
  75. data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
  76. data/lib/graphql/execution/interpreter/arguments.rb +88 -0
  77. data/lib/graphql/execution/interpreter/arguments_cache.rb +105 -0
  78. data/lib/graphql/execution/interpreter/execution_errors.rb +29 -0
  79. data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
  80. data/lib/graphql/execution/interpreter/resolve.rb +77 -0
  81. data/lib/graphql/execution/interpreter/runtime.rb +994 -0
  82. data/lib/graphql/execution/interpreter.rb +226 -0
  83. data/lib/graphql/execution/lazy/lazy_method_map.rb +98 -0
  84. data/lib/graphql/execution/lazy.rb +75 -0
  85. data/lib/graphql/execution/lookahead.rb +311 -0
  86. data/lib/graphql/execution/multiplex.rb +45 -0
  87. data/lib/graphql/execution.rb +18 -0
  88. data/lib/graphql/execution_error.rb +34 -1
  89. data/lib/graphql/filter.rb +53 -0
  90. data/lib/graphql/integer_decoding_error.rb +17 -0
  91. data/lib/graphql/integer_encoding_error.rb +36 -0
  92. data/lib/graphql/introspection/base_object.rb +13 -0
  93. data/lib/graphql/introspection/directive_location_enum.rb +12 -5
  94. data/lib/graphql/introspection/directive_type.rb +30 -10
  95. data/lib/graphql/introspection/dynamic_fields.rb +12 -0
  96. data/lib/graphql/introspection/entry_points.rb +22 -0
  97. data/lib/graphql/introspection/enum_value_type.rb +21 -8
  98. data/lib/graphql/introspection/field_type.rb +26 -10
  99. data/lib/graphql/introspection/input_value_type.rb +64 -14
  100. data/lib/graphql/introspection/introspection_query.rb +7 -76
  101. data/lib/graphql/introspection/schema_type.rb +42 -17
  102. data/lib/graphql/introspection/type_kind_enum.rb +11 -5
  103. data/lib/graphql/introspection/type_type.rb +104 -16
  104. data/lib/graphql/introspection.rb +104 -13
  105. data/lib/graphql/invalid_name_error.rb +11 -0
  106. data/lib/graphql/invalid_null_error.rb +36 -8
  107. data/lib/graphql/language/block_string.rb +99 -0
  108. data/lib/graphql/language/cache.rb +37 -0
  109. data/lib/graphql/language/definition_slice.rb +41 -0
  110. data/lib/graphql/language/document_from_schema_definition.rb +335 -0
  111. data/lib/graphql/language/generation.rb +16 -86
  112. data/lib/graphql/language/lexer.rb +1436 -705
  113. data/lib/graphql/language/lexer.rl +172 -64
  114. data/lib/graphql/language/nodes.rb +617 -105
  115. data/lib/graphql/language/parser.rb +1524 -430
  116. data/lib/graphql/language/parser.y +348 -73
  117. data/lib/graphql/language/printer.rb +386 -0
  118. data/lib/graphql/language/sanitized_printer.rb +222 -0
  119. data/lib/graphql/language/token.rb +16 -3
  120. data/lib/graphql/language/visitor.rb +169 -25
  121. data/lib/graphql/language.rb +30 -0
  122. data/lib/graphql/load_application_object_failed_error.rb +22 -0
  123. data/lib/graphql/name_validator.rb +11 -0
  124. data/lib/graphql/pagination/active_record_relation_connection.rb +85 -0
  125. data/lib/graphql/pagination/array_connection.rb +79 -0
  126. data/lib/graphql/pagination/connection.rb +253 -0
  127. data/lib/graphql/pagination/connections.rb +135 -0
  128. data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
  129. data/lib/graphql/pagination/relation_connection.rb +228 -0
  130. data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
  131. data/lib/graphql/pagination.rb +6 -0
  132. data/lib/graphql/parse_error.rb +24 -0
  133. data/lib/graphql/query/context.rb +266 -12
  134. data/lib/graphql/query/fingerprint.rb +26 -0
  135. data/lib/graphql/query/input_validation_result.rb +34 -7
  136. data/lib/graphql/query/null_context.rb +52 -0
  137. data/lib/graphql/query/result.rb +63 -0
  138. data/lib/graphql/query/validation_pipeline.rb +114 -0
  139. data/lib/graphql/query/variable_validation_error.rb +27 -3
  140. data/lib/graphql/query/variables.rb +75 -24
  141. data/lib/graphql/query.rb +359 -92
  142. data/lib/graphql/railtie.rb +13 -0
  143. data/lib/graphql/rake_task/validate.rb +63 -0
  144. data/lib/graphql/rake_task.rb +146 -0
  145. data/lib/graphql/relay/range_add.rb +52 -0
  146. data/lib/graphql/relay.rb +3 -0
  147. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  148. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  149. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  150. data/lib/graphql/rubocop.rb +4 -0
  151. data/lib/graphql/runtime_type_error.rb +5 -0
  152. data/lib/graphql/schema/addition.rb +245 -0
  153. data/lib/graphql/schema/argument.rb +395 -0
  154. data/lib/graphql/schema/base_64_bp.rb +26 -0
  155. data/lib/graphql/schema/base_64_encoder.rb +21 -0
  156. data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +47 -0
  157. data/lib/graphql/schema/build_from_definition/resolve_map.rb +78 -0
  158. data/lib/graphql/schema/build_from_definition.rb +492 -0
  159. data/lib/graphql/schema/built_in_types.rb +12 -0
  160. data/lib/graphql/schema/directive/deprecated.rb +18 -0
  161. data/lib/graphql/schema/directive/feature.rb +66 -0
  162. data/lib/graphql/schema/directive/flagged.rb +57 -0
  163. data/lib/graphql/schema/directive/include.rb +25 -0
  164. data/lib/graphql/schema/directive/one_of.rb +12 -0
  165. data/lib/graphql/schema/directive/skip.rb +25 -0
  166. data/lib/graphql/schema/directive/transform.rb +60 -0
  167. data/lib/graphql/schema/directive.rb +212 -0
  168. data/lib/graphql/schema/enum.rb +176 -0
  169. data/lib/graphql/schema/enum_value.rb +77 -0
  170. data/lib/graphql/schema/field/connection_extension.rb +80 -0
  171. data/lib/graphql/schema/field/scope_extension.rb +22 -0
  172. data/lib/graphql/schema/field.rb +862 -0
  173. data/lib/graphql/schema/field_extension.rb +156 -0
  174. data/lib/graphql/schema/find_inherited_value.rb +36 -0
  175. data/lib/graphql/schema/finder.rb +155 -0
  176. data/lib/graphql/schema/input_object.rb +258 -0
  177. data/lib/graphql/schema/interface.rb +113 -0
  178. data/lib/graphql/schema/introspection_system.rb +164 -0
  179. data/lib/graphql/schema/invalid_type_error.rb +1 -0
  180. data/lib/graphql/schema/late_bound_type.rb +37 -0
  181. data/lib/graphql/schema/list.rb +86 -0
  182. data/lib/graphql/schema/loader.rb +228 -0
  183. data/lib/graphql/schema/member/base_dsl_methods.rb +124 -0
  184. data/lib/graphql/schema/member/build_type.rb +178 -0
  185. data/lib/graphql/schema/member/graphql_type_names.rb +21 -0
  186. data/lib/graphql/schema/member/has_arguments.rb +376 -0
  187. data/lib/graphql/schema/member/has_ast_node.rb +20 -0
  188. data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
  189. data/lib/graphql/schema/member/has_directives.rb +113 -0
  190. data/lib/graphql/schema/member/has_fields.rb +163 -0
  191. data/lib/graphql/schema/member/has_interfaces.rb +88 -0
  192. data/lib/graphql/schema/member/has_path.rb +25 -0
  193. data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
  194. data/lib/graphql/schema/member/has_validators.rb +31 -0
  195. data/lib/graphql/schema/member/relay_shortcuts.rb +73 -0
  196. data/lib/graphql/schema/member/scoped.rb +21 -0
  197. data/lib/graphql/schema/member/type_system_helpers.rb +38 -0
  198. data/lib/graphql/schema/member/validates_input.rb +33 -0
  199. data/lib/graphql/schema/member.rb +39 -0
  200. data/lib/graphql/schema/mutation.rb +85 -0
  201. data/lib/graphql/schema/non_null.rb +67 -0
  202. data/lib/graphql/schema/null_mask.rb +11 -0
  203. data/lib/graphql/schema/object.rb +117 -0
  204. data/lib/graphql/schema/printer.rb +72 -128
  205. data/lib/graphql/schema/relay_classic_mutation.rb +179 -0
  206. data/lib/graphql/schema/resolver/has_payload_type.rb +106 -0
  207. data/lib/graphql/schema/resolver.rb +402 -0
  208. data/lib/graphql/schema/scalar.rb +68 -0
  209. data/lib/graphql/schema/subscription.rb +148 -0
  210. data/lib/graphql/schema/timeout.rb +123 -0
  211. data/lib/graphql/schema/type_expression.rb +29 -5
  212. data/lib/graphql/schema/type_membership.rb +51 -0
  213. data/lib/graphql/schema/union.rb +81 -0
  214. data/lib/graphql/schema/unique_within_type.rb +34 -0
  215. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  216. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  217. data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
  218. data/lib/graphql/schema/validator/format_validator.rb +48 -0
  219. data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
  220. data/lib/graphql/schema/validator/length_validator.rb +59 -0
  221. data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
  222. data/lib/graphql/schema/validator/required_validator.rb +82 -0
  223. data/lib/graphql/schema/validator.rb +171 -0
  224. data/lib/graphql/schema/warden.rb +413 -0
  225. data/lib/graphql/schema/wrapper.rb +24 -0
  226. data/lib/graphql/schema.rb +1179 -104
  227. data/lib/graphql/static_validation/all_rules.rb +14 -0
  228. data/lib/graphql/static_validation/base_visitor.rb +200 -0
  229. data/lib/graphql/static_validation/definition_dependencies.rb +198 -0
  230. data/lib/graphql/static_validation/error.rb +46 -0
  231. data/lib/graphql/static_validation/interpreter_visitor.rb +14 -0
  232. data/lib/graphql/static_validation/literal_validator.rb +113 -22
  233. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +59 -11
  234. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +48 -0
  235. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +31 -0
  236. data/lib/graphql/static_validation/rules/argument_names_are_unique_error.rb +30 -0
  237. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +62 -8
  238. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +37 -0
  239. data/lib/graphql/static_validation/rules/directives_are_defined.rb +20 -13
  240. data/lib/graphql/static_validation/rules/directives_are_defined_error.rb +29 -0
  241. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +32 -26
  242. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations_error.rb +31 -0
  243. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +21 -23
  244. data/lib/graphql/static_validation/rules/fields_are_defined_on_type_error.rb +32 -0
  245. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +55 -18
  246. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections_error.rb +31 -0
  247. data/lib/graphql/static_validation/rules/fields_will_merge.rb +390 -70
  248. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +53 -0
  249. data/lib/graphql/static_validation/rules/fragment_names_are_unique.rb +30 -0
  250. data/lib/graphql/static_validation/rules/fragment_names_are_unique_error.rb +29 -0
  251. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +54 -37
  252. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible_error.rb +35 -0
  253. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +26 -16
  254. data/lib/graphql/static_validation/rules/fragment_types_exist_error.rb +29 -0
  255. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +13 -19
  256. data/lib/graphql/static_validation/rules/fragments_are_finite_error.rb +29 -0
  257. data/lib/graphql/static_validation/rules/fragments_are_named.rb +16 -0
  258. data/lib/graphql/static_validation/rules/fragments_are_named_error.rb +26 -0
  259. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +25 -20
  260. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types_error.rb +30 -0
  261. data/lib/graphql/static_validation/rules/fragments_are_used.rb +22 -33
  262. data/lib/graphql/static_validation/rules/fragments_are_used_error.rb +29 -0
  263. data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
  264. data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
  265. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +17 -0
  266. data/lib/graphql/static_validation/rules/mutation_root_exists_error.rb +26 -0
  267. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +41 -0
  268. data/lib/graphql/static_validation/rules/no_definitions_are_present_error.rb +25 -0
  269. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  270. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  271. data/lib/graphql/static_validation/rules/operation_names_are_valid.rb +36 -0
  272. data/lib/graphql/static_validation/rules/operation_names_are_valid_error.rb +28 -0
  273. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  274. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  275. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +22 -21
  276. data/lib/graphql/static_validation/rules/required_arguments_are_present_error.rb +35 -0
  277. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +59 -0
  278. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present_error.rb +35 -0
  279. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +17 -0
  280. data/lib/graphql/static_validation/rules/subscription_root_exists_error.rb +26 -0
  281. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +56 -0
  282. data/lib/graphql/static_validation/rules/unique_directives_per_location_error.rb +29 -0
  283. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +36 -18
  284. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed_error.rb +39 -0
  285. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +24 -0
  286. data/lib/graphql/static_validation/rules/variable_names_are_unique_error.rb +29 -0
  287. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +103 -39
  288. data/lib/graphql/static_validation/rules/variable_usages_are_allowed_error.rb +38 -0
  289. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +22 -14
  290. data/lib/graphql/static_validation/rules/variables_are_input_types_error.rb +32 -0
  291. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +92 -70
  292. data/lib/graphql/static_validation/rules/variables_are_used_and_defined_error.rb +37 -0
  293. data/lib/graphql/static_validation/type_stack.rb +85 -24
  294. data/lib/graphql/static_validation/validation_context.rb +25 -46
  295. data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
  296. data/lib/graphql/static_validation/validator.rb +46 -15
  297. data/lib/graphql/static_validation.rb +6 -3
  298. data/lib/graphql/string_encoding_error.rb +20 -0
  299. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +247 -0
  300. data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
  301. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +58 -0
  302. data/lib/graphql/subscriptions/event.rb +144 -0
  303. data/lib/graphql/subscriptions/instrumentation.rb +28 -0
  304. data/lib/graphql/subscriptions/serialize.rb +158 -0
  305. data/lib/graphql/subscriptions.rb +306 -0
  306. data/lib/graphql/tracing/active_support_notifications_tracing.rb +21 -0
  307. data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
  308. data/lib/graphql/tracing/appsignal_tracing.rb +51 -0
  309. data/lib/graphql/tracing/data_dog_tracing.rb +100 -0
  310. data/lib/graphql/tracing/instrumentation_tracing.rb +83 -0
  311. data/lib/graphql/tracing/new_relic_tracing.rb +51 -0
  312. data/lib/graphql/tracing/notifications_tracing.rb +59 -0
  313. data/lib/graphql/tracing/platform_tracing.rb +122 -0
  314. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +32 -0
  315. data/lib/graphql/tracing/prometheus_tracing.rb +67 -0
  316. data/lib/graphql/tracing/scout_tracing.rb +54 -0
  317. data/lib/graphql/tracing/statsd_tracing.rb +42 -0
  318. data/lib/graphql/tracing.rb +94 -0
  319. data/lib/graphql/type_kinds.rb +50 -22
  320. data/lib/graphql/types/big_int.rb +23 -0
  321. data/lib/graphql/types/boolean.rb +18 -0
  322. data/lib/graphql/types/float.rb +19 -0
  323. data/lib/graphql/types/id.rb +24 -0
  324. data/lib/graphql/types/int.rb +36 -0
  325. data/lib/graphql/types/iso_8601_date.rb +45 -0
  326. data/lib/graphql/types/iso_8601_date_time.rb +76 -0
  327. data/lib/graphql/types/json.rb +25 -0
  328. data/lib/graphql/types/relay/base_connection.rb +49 -0
  329. data/lib/graphql/types/relay/base_edge.rb +29 -0
  330. data/lib/graphql/types/relay/connection_behaviors.rb +154 -0
  331. data/lib/graphql/types/relay/default_relay.rb +21 -0
  332. data/lib/graphql/types/relay/edge_behaviors.rb +64 -0
  333. data/lib/graphql/types/relay/has_node_field.rb +41 -0
  334. data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
  335. data/lib/graphql/types/relay/node.rb +15 -0
  336. data/lib/graphql/types/relay/node_behaviors.rb +19 -0
  337. data/lib/graphql/types/relay/page_info.rb +11 -0
  338. data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
  339. data/lib/graphql/types/relay.rb +39 -0
  340. data/lib/graphql/types/string.rb +29 -0
  341. data/lib/graphql/types.rb +11 -0
  342. data/lib/graphql/unauthorized_error.rb +29 -0
  343. data/lib/graphql/unauthorized_field_error.rb +23 -0
  344. data/lib/graphql/unresolved_type_error.rb +35 -0
  345. data/lib/graphql/version.rb +2 -1
  346. data/lib/graphql.rb +86 -41
  347. data/readme.md +15 -101
  348. metadata +394 -279
  349. data/lib/graphql/analysis/analyze_query.rb +0 -73
  350. data/lib/graphql/analysis/max_query_complexity.rb +0 -25
  351. data/lib/graphql/analysis/max_query_depth.rb +0 -25
  352. data/lib/graphql/analysis/query_complexity.rb +0 -122
  353. data/lib/graphql/analysis/query_depth.rb +0 -54
  354. data/lib/graphql/argument.rb +0 -25
  355. data/lib/graphql/base_type.rb +0 -115
  356. data/lib/graphql/boolean_type.rb +0 -9
  357. data/lib/graphql/define/assign_argument.rb +0 -20
  358. data/lib/graphql/define/assign_enum_value.rb +0 -16
  359. data/lib/graphql/define/assign_object_field.rb +0 -21
  360. data/lib/graphql/define/assignment_dictionary.rb +0 -26
  361. data/lib/graphql/define/defined_object_proxy.rb +0 -32
  362. data/lib/graphql/define/instance_definable.rb +0 -79
  363. data/lib/graphql/define/non_null_with_bang.rb +0 -15
  364. data/lib/graphql/define/type_definer.rb +0 -30
  365. data/lib/graphql/define.rb +0 -8
  366. data/lib/graphql/directive/include_directive.rb +0 -10
  367. data/lib/graphql/directive/skip_directive.rb +0 -11
  368. data/lib/graphql/directive.rb +0 -49
  369. data/lib/graphql/enum_type.rb +0 -95
  370. data/lib/graphql/field.rb +0 -131
  371. data/lib/graphql/float_type.rb +0 -5
  372. data/lib/graphql/id_type.rb +0 -12
  373. data/lib/graphql/input_object_type.rb +0 -71
  374. data/lib/graphql/int_type.rb +0 -5
  375. data/lib/graphql/interface_type.rb +0 -38
  376. data/lib/graphql/internal_representation/node.rb +0 -81
  377. data/lib/graphql/internal_representation/rewrite.rb +0 -177
  378. data/lib/graphql/internal_representation.rb +0 -2
  379. data/lib/graphql/introspection/arguments_field.rb +0 -5
  380. data/lib/graphql/introspection/enum_values_field.rb +0 -13
  381. data/lib/graphql/introspection/fields_field.rb +0 -13
  382. data/lib/graphql/introspection/input_fields_field.rb +0 -12
  383. data/lib/graphql/introspection/interfaces_field.rb +0 -5
  384. data/lib/graphql/introspection/of_type_field.rb +0 -6
  385. data/lib/graphql/introspection/possible_types_field.rb +0 -11
  386. data/lib/graphql/introspection/schema_field.rb +0 -15
  387. data/lib/graphql/introspection/type_by_name_field.rb +0 -16
  388. data/lib/graphql/introspection/typename_field.rb +0 -15
  389. data/lib/graphql/list_type.rb +0 -46
  390. data/lib/graphql/non_null_type.rb +0 -43
  391. data/lib/graphql/object_type.rb +0 -93
  392. data/lib/graphql/query/arguments.rb +0 -76
  393. data/lib/graphql/query/directive_resolution.rb +0 -16
  394. data/lib/graphql/query/executor.rb +0 -45
  395. data/lib/graphql/query/literal_input.rb +0 -90
  396. data/lib/graphql/query/serial_execution/execution_context.rb +0 -31
  397. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -82
  398. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -27
  399. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -42
  400. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -107
  401. data/lib/graphql/query/serial_execution.rb +0 -41
  402. data/lib/graphql/query/type_resolver.rb +0 -25
  403. data/lib/graphql/scalar_type.rb +0 -53
  404. data/lib/graphql/schema/catchall_middleware.rb +0 -34
  405. data/lib/graphql/schema/middleware_chain.rb +0 -28
  406. data/lib/graphql/schema/possible_types.rb +0 -34
  407. data/lib/graphql/schema/reduce_types.rb +0 -68
  408. data/lib/graphql/schema/rescue_middleware.rb +0 -53
  409. data/lib/graphql/schema/timeout_middleware.rb +0 -67
  410. data/lib/graphql/schema/type_map.rb +0 -30
  411. data/lib/graphql/schema/validation.rb +0 -164
  412. data/lib/graphql/static_validation/arguments_validator.rb +0 -48
  413. data/lib/graphql/static_validation/message.rb +0 -36
  414. data/lib/graphql/string_type.rb +0 -5
  415. data/lib/graphql/union_type.rb +0 -38
  416. data/spec/graphql/analysis/analyze_query_spec.rb +0 -50
  417. data/spec/graphql/analysis/max_query_complexity_spec.rb +0 -62
  418. data/spec/graphql/analysis/max_query_depth_spec.rb +0 -100
  419. data/spec/graphql/analysis/query_complexity_spec.rb +0 -235
  420. data/spec/graphql/analysis/query_depth_spec.rb +0 -80
  421. data/spec/graphql/argument_spec.rb +0 -20
  422. data/spec/graphql/base_type_spec.rb +0 -24
  423. data/spec/graphql/boolean_type_spec.rb +0 -20
  424. data/spec/graphql/define/instance_definable_spec.rb +0 -55
  425. data/spec/graphql/directive_spec.rb +0 -77
  426. data/spec/graphql/enum_type_spec.rb +0 -31
  427. data/spec/graphql/execution_error_spec.rb +0 -61
  428. data/spec/graphql/field_spec.rb +0 -92
  429. data/spec/graphql/float_type_spec.rb +0 -15
  430. data/spec/graphql/id_type_spec.rb +0 -32
  431. data/spec/graphql/input_object_type_spec.rb +0 -162
  432. data/spec/graphql/int_type_spec.rb +0 -15
  433. data/spec/graphql/interface_type_spec.rb +0 -56
  434. data/spec/graphql/internal_representation/rewrite_spec.rb +0 -120
  435. data/spec/graphql/introspection/directive_type_spec.rb +0 -50
  436. data/spec/graphql/introspection/input_value_type_spec.rb +0 -42
  437. data/spec/graphql/introspection/introspection_query_spec.rb +0 -10
  438. data/spec/graphql/introspection/schema_type_spec.rb +0 -45
  439. data/spec/graphql/introspection/type_type_spec.rb +0 -122
  440. data/spec/graphql/language/generation_spec.rb +0 -42
  441. data/spec/graphql/language/parser_spec.rb +0 -442
  442. data/spec/graphql/language/visitor_spec.rb +0 -49
  443. data/spec/graphql/list_type_spec.rb +0 -32
  444. data/spec/graphql/non_null_type_spec.rb +0 -31
  445. data/spec/graphql/object_type_spec.rb +0 -42
  446. data/spec/graphql/query/arguments_spec.rb +0 -25
  447. data/spec/graphql/query/context_spec.rb +0 -83
  448. data/spec/graphql/query/executor_spec.rb +0 -273
  449. data/spec/graphql/query/serial_execution/execution_context_spec.rb +0 -53
  450. data/spec/graphql/query/serial_execution/value_resolution_spec.rb +0 -66
  451. data/spec/graphql/query/type_resolver_spec.rb +0 -8
  452. data/spec/graphql/query/variables_spec.rb +0 -28
  453. data/spec/graphql/query_spec.rb +0 -363
  454. data/spec/graphql/scalar_type_spec.rb +0 -61
  455. data/spec/graphql/schema/catchall_middleware_spec.rb +0 -32
  456. data/spec/graphql/schema/middleware_chain_spec.rb +0 -42
  457. data/spec/graphql/schema/printer_spec.rb +0 -190
  458. data/spec/graphql/schema/reduce_types_spec.rb +0 -102
  459. data/spec/graphql/schema/rescue_middleware_spec.rb +0 -33
  460. data/spec/graphql/schema/timeout_middleware_spec.rb +0 -180
  461. data/spec/graphql/schema/type_expression_spec.rb +0 -38
  462. data/spec/graphql/schema/validation_spec.rb +0 -219
  463. data/spec/graphql/schema_spec.rb +0 -23
  464. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +0 -63
  465. data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +0 -48
  466. data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +0 -34
  467. data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +0 -39
  468. data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +0 -60
  469. data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +0 -31
  470. data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +0 -48
  471. data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +0 -47
  472. data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +0 -39
  473. data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +0 -44
  474. data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +0 -49
  475. data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +0 -25
  476. data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +0 -42
  477. data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +0 -44
  478. data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +0 -63
  479. data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +0 -37
  480. data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +0 -53
  481. data/spec/graphql/static_validation/type_stack_spec.rb +0 -37
  482. data/spec/graphql/static_validation/validator_spec.rb +0 -69
  483. data/spec/graphql/string_type_spec.rb +0 -15
  484. data/spec/graphql/union_type_spec.rb +0 -31
  485. data/spec/spec_helper.rb +0 -18
  486. data/spec/support/dairy_app.rb +0 -309
  487. data/spec/support/dairy_data.rb +0 -23
  488. data/spec/support/minimum_input_object.rb +0 -16
  489. data/spec/support/star_wars_data.rb +0 -71
  490. data/spec/support/star_wars_schema.rb +0 -76
@@ -0,0 +1,492 @@
1
+ # frozen_string_literal: true
2
+ require "graphql/schema/build_from_definition/resolve_map"
3
+
4
+ module GraphQL
5
+ class Schema
6
+ module BuildFromDefinition
7
+ class << self
8
+ # @see {Schema.from_definition}
9
+ def from_definition(schema_superclass, definition_string, parser: GraphQL.default_parser, **kwargs)
10
+ from_document(schema_superclass, parser.parse(definition_string), **kwargs)
11
+ end
12
+
13
+ def from_definition_path(schema_superclass, definition_path, parser: GraphQL.default_parser, **kwargs)
14
+ from_document(schema_superclass, parser.parse_file(definition_path), **kwargs)
15
+ end
16
+
17
+ def from_document(schema_superclass, document, default_resolve:, using: {}, relay: false)
18
+ Builder.build(schema_superclass, document, default_resolve: default_resolve || {}, relay: relay, using: using)
19
+ end
20
+ end
21
+
22
+ # @api private
23
+ module Builder
24
+ extend self
25
+
26
+ def build(schema_superclass, document, default_resolve:, using: {}, relay:)
27
+ raise InvalidDocumentError.new('Must provide a document ast.') if !document || !document.is_a?(GraphQL::Language::Nodes::Document)
28
+
29
+ if default_resolve.is_a?(Hash)
30
+ default_resolve = ResolveMap.new(default_resolve)
31
+ end
32
+
33
+ schema_defns = document.definitions.select { |d| d.is_a?(GraphQL::Language::Nodes::SchemaDefinition) }
34
+ if schema_defns.size > 1
35
+ raise InvalidDocumentError.new('Must provide only one schema definition.')
36
+ end
37
+ schema_definition = schema_defns.first
38
+ types = {}
39
+ directives = schema_superclass.directives.dup
40
+ type_resolver = build_resolve_type(types, directives, ->(type_name) { types[type_name] ||= Schema::LateBoundType.new(type_name)})
41
+ # Make a different type resolver because we need to coerce directive arguments
42
+ # _while_ building the schema.
43
+ # It will dig for a type if it encounters a custom type. This could be a problem if there are cycles.
44
+ directive_type_resolver = nil
45
+ directive_type_resolver = build_resolve_type(types, directives, ->(type_name) {
46
+ types[type_name] ||= begin
47
+ defn = document.definitions.find { |d| d.respond_to?(:name) && d.name == type_name }
48
+ if defn
49
+ build_definition_from_node(defn, directive_type_resolver, default_resolve)
50
+ elsif (built_in_defn = GraphQL::Schema::BUILT_IN_TYPES[type_name])
51
+ built_in_defn
52
+ else
53
+ raise "No definition for #{type_name.inspect} found in schema document or built-in types. Add a definition for it or remove it."
54
+ end
55
+ end
56
+ })
57
+
58
+ directives.merge!(GraphQL::Schema.default_directives)
59
+ document.definitions.each do |definition|
60
+ if definition.is_a?(GraphQL::Language::Nodes::DirectiveDefinition)
61
+ directives[definition.name] = build_directive(definition, directive_type_resolver)
62
+ end
63
+ end
64
+
65
+ # In case any directives referenced built-in types for their arguments:
66
+ replace_late_bound_types_with_built_in(types)
67
+
68
+ schema_extensions = nil
69
+ document.definitions.each do |definition|
70
+ case definition
71
+ when GraphQL::Language::Nodes::SchemaDefinition, GraphQL::Language::Nodes::DirectiveDefinition
72
+ nil # already handled
73
+ when GraphQL::Language::Nodes::SchemaExtension
74
+ schema_extensions ||= []
75
+ schema_extensions << definition
76
+ else
77
+ # It's possible that this was already loaded by the directives
78
+ prev_type = types[definition.name]
79
+ if prev_type.nil? || prev_type.is_a?(Schema::LateBoundType)
80
+ types[definition.name] = build_definition_from_node(definition, type_resolver, default_resolve)
81
+ end
82
+ end
83
+ end
84
+
85
+ replace_late_bound_types_with_built_in(types)
86
+
87
+ if schema_definition
88
+ if schema_definition.query
89
+ raise InvalidDocumentError.new("Specified query type \"#{schema_definition.query}\" not found in document.") unless types[schema_definition.query]
90
+ query_root_type = types[schema_definition.query]
91
+ end
92
+
93
+ if schema_definition.mutation
94
+ raise InvalidDocumentError.new("Specified mutation type \"#{schema_definition.mutation}\" not found in document.") unless types[schema_definition.mutation]
95
+ mutation_root_type = types[schema_definition.mutation]
96
+ end
97
+
98
+ if schema_definition.subscription
99
+ raise InvalidDocumentError.new("Specified subscription type \"#{schema_definition.subscription}\" not found in document.") unless types[schema_definition.subscription]
100
+ subscription_root_type = types[schema_definition.subscription]
101
+ end
102
+ else
103
+ query_root_type = types['Query']
104
+ mutation_root_type = types['Mutation']
105
+ subscription_root_type = types['Subscription']
106
+ end
107
+
108
+ raise InvalidDocumentError.new('Must provide schema definition with query type or a type named Query.') unless query_root_type
109
+
110
+ schema_class = Class.new(schema_superclass) do
111
+ begin
112
+ # Add these first so that there's some chance of resolving late-bound types
113
+ orphan_types types.values
114
+ query query_root_type
115
+ mutation mutation_root_type
116
+ subscription subscription_root_type
117
+ rescue Schema::UnresolvedLateBoundTypeError => err
118
+ type_name = err.type.name
119
+ err_backtrace = err.backtrace
120
+ raise InvalidDocumentError, "Type \"#{type_name}\" not found in document.", err_backtrace
121
+ end
122
+
123
+ if default_resolve.respond_to?(:resolve_type)
124
+ def self.resolve_type(*args)
125
+ self.definition_default_resolve.resolve_type(*args)
126
+ end
127
+ else
128
+ def self.resolve_type(*args)
129
+ NullResolveType.call(*args)
130
+ end
131
+ end
132
+
133
+ directives directives.values
134
+
135
+ if schema_definition
136
+ ast_node(schema_definition)
137
+ end
138
+
139
+ using.each do |plugin, options|
140
+ if options
141
+ use(plugin, **options)
142
+ else
143
+ use(plugin)
144
+ end
145
+ end
146
+
147
+ # Empty `orphan_types` -- this will make unreachable types ... unreachable.
148
+ own_orphan_types.clear
149
+
150
+ class << self
151
+ attr_accessor :definition_default_resolve
152
+ end
153
+
154
+ self.definition_default_resolve = default_resolve
155
+
156
+ def definition_default_resolve
157
+ self.class.definition_default_resolve
158
+ end
159
+
160
+ def self.inherited(child_class)
161
+ child_class.definition_default_resolve = self.definition_default_resolve
162
+ end
163
+ end
164
+
165
+ if schema_extensions
166
+ schema_extensions.each do |ext|
167
+ build_directives(schema_class, ext, type_resolver)
168
+ end
169
+ end
170
+
171
+ schema_class
172
+ end
173
+
174
+ NullResolveType = ->(type, obj, ctx) {
175
+ raise(GraphQL::RequiredImplementationMissingError, "Generated Schema cannot use Interface or Union types for execution. Implement resolve_type on your resolver.")
176
+ }
177
+
178
+ def build_definition_from_node(definition, type_resolver, default_resolve)
179
+ case definition
180
+ when GraphQL::Language::Nodes::EnumTypeDefinition
181
+ build_enum_type(definition, type_resolver)
182
+ when GraphQL::Language::Nodes::ObjectTypeDefinition
183
+ build_object_type(definition, type_resolver)
184
+ when GraphQL::Language::Nodes::InterfaceTypeDefinition
185
+ build_interface_type(definition, type_resolver)
186
+ when GraphQL::Language::Nodes::UnionTypeDefinition
187
+ build_union_type(definition, type_resolver)
188
+ when GraphQL::Language::Nodes::ScalarTypeDefinition
189
+ build_scalar_type(definition, type_resolver, default_resolve: default_resolve)
190
+ when GraphQL::Language::Nodes::InputObjectTypeDefinition
191
+ build_input_object_type(definition, type_resolver)
192
+ end
193
+ end
194
+
195
+ # Modify `types`, replacing any late-bound references to built-in types
196
+ # with their actual definitions.
197
+ #
198
+ # (Schema definitions are allowed to reference those built-ins without redefining them.)
199
+ # @return void
200
+ def replace_late_bound_types_with_built_in(types)
201
+ GraphQL::Schema::BUILT_IN_TYPES.each do |scalar_name, built_in_scalar|
202
+ existing_type = types[scalar_name]
203
+ if existing_type.is_a?(GraphQL::Schema::LateBoundType)
204
+ types[scalar_name] = built_in_scalar
205
+ end
206
+ end
207
+ end
208
+
209
+ def build_directives(definition, ast_node, type_resolver)
210
+ dirs = prepare_directives(ast_node, type_resolver)
211
+ dirs.each do |(dir_class, options)|
212
+ if definition.respond_to?(:schema_directive)
213
+ # it's a schema
214
+ definition.schema_directive(dir_class, **options)
215
+ else
216
+ definition.directive(dir_class, **options)
217
+ end
218
+ end
219
+ end
220
+
221
+ def prepare_directives(ast_node, type_resolver)
222
+ dirs = []
223
+ ast_node.directives.each do |dir_node|
224
+ if dir_node.name == "deprecated"
225
+ # This is handled using `deprecation_reason`
226
+ next
227
+ else
228
+ dir_class = type_resolver.call(dir_node.name)
229
+ if dir_class.nil?
230
+ raise ArgumentError, "No definition for @#{dir_node.name} #{ast_node.respond_to?(:name) ? "on #{ast_node.name} " : ""}at #{ast_node.line}:#{ast_node.col}"
231
+ end
232
+ options = args_to_kwargs(dir_class, dir_node)
233
+ dirs << [dir_class, options]
234
+ end
235
+ end
236
+ dirs
237
+ end
238
+
239
+ def args_to_kwargs(arg_owner, node)
240
+ if node.respond_to?(:arguments)
241
+ kwargs = {}
242
+ node.arguments.each do |arg_node|
243
+ arg_defn = arg_owner.get_argument(arg_node.name)
244
+ kwargs[arg_defn.keyword] = args_to_kwargs(arg_defn.type.unwrap, arg_node.value)
245
+ end
246
+ kwargs
247
+ elsif node.is_a?(Array)
248
+ node.map { |n| args_to_kwargs(arg_owner, n) }
249
+ elsif node.is_a?(Language::Nodes::Enum)
250
+ node.name
251
+ else
252
+ # scalar
253
+ node
254
+ end
255
+ end
256
+
257
+ def build_enum_type(enum_type_definition, type_resolver)
258
+ builder = self
259
+ Class.new(GraphQL::Schema::Enum) do
260
+ graphql_name(enum_type_definition.name)
261
+ builder.build_directives(self, enum_type_definition, type_resolver)
262
+ description(enum_type_definition.description)
263
+ ast_node(enum_type_definition)
264
+ enum_type_definition.values.each do |enum_value_definition|
265
+ value(enum_value_definition.name,
266
+ value: enum_value_definition.name,
267
+ deprecation_reason: builder.build_deprecation_reason(enum_value_definition.directives),
268
+ description: enum_value_definition.description,
269
+ directives: builder.prepare_directives(enum_value_definition, type_resolver),
270
+ ast_node: enum_value_definition,
271
+ )
272
+ end
273
+ end
274
+ end
275
+
276
+ def build_deprecation_reason(directives)
277
+ deprecated_directive = directives.find{ |d| d.name == 'deprecated' }
278
+ return unless deprecated_directive
279
+
280
+ reason = deprecated_directive.arguments.find{ |a| a.name == 'reason' }
281
+ return GraphQL::Schema::Directive::DEFAULT_DEPRECATION_REASON unless reason
282
+
283
+ reason.value
284
+ end
285
+
286
+ def build_scalar_type(scalar_type_definition, type_resolver, default_resolve:)
287
+ builder = self
288
+ Class.new(GraphQL::Schema::Scalar) do
289
+ graphql_name(scalar_type_definition.name)
290
+ description(scalar_type_definition.description)
291
+ ast_node(scalar_type_definition)
292
+ builder.build_directives(self, scalar_type_definition, type_resolver)
293
+
294
+ if default_resolve.respond_to?(:coerce_input)
295
+ # Put these method definitions in another method to avoid retaining `type_resolve`
296
+ # from this method's bindiing
297
+ builder.build_scalar_type_coerce_method(self, :coerce_input, default_resolve)
298
+ builder.build_scalar_type_coerce_method(self, :coerce_result, default_resolve)
299
+ end
300
+ end
301
+ end
302
+
303
+ def build_scalar_type_coerce_method(scalar_class, method_name, default_definition_resolve)
304
+ scalar_class.define_singleton_method(method_name) do |val, ctx|
305
+ default_definition_resolve.public_send(method_name, self, val, ctx)
306
+ end
307
+ end
308
+
309
+ def build_union_type(union_type_definition, type_resolver)
310
+ builder = self
311
+ Class.new(GraphQL::Schema::Union) do
312
+ graphql_name(union_type_definition.name)
313
+ description(union_type_definition.description)
314
+ possible_types(*union_type_definition.types.map { |type_name| type_resolver.call(type_name) })
315
+ ast_node(union_type_definition)
316
+ builder.build_directives(self, union_type_definition, type_resolver)
317
+ end
318
+ end
319
+
320
+ def build_object_type(object_type_definition, type_resolver)
321
+ builder = self
322
+
323
+ Class.new(GraphQL::Schema::Object) do
324
+ graphql_name(object_type_definition.name)
325
+ description(object_type_definition.description)
326
+ ast_node(object_type_definition)
327
+ builder.build_directives(self, object_type_definition, type_resolver)
328
+
329
+ object_type_definition.interfaces.each do |interface_name|
330
+ interface_defn = type_resolver.call(interface_name)
331
+ implements(interface_defn)
332
+ end
333
+
334
+ builder.build_fields(self, object_type_definition.fields, type_resolver, default_resolve: true)
335
+ end
336
+ end
337
+
338
+ def build_input_object_type(input_object_type_definition, type_resolver)
339
+ builder = self
340
+ Class.new(GraphQL::Schema::InputObject) do
341
+ graphql_name(input_object_type_definition.name)
342
+ description(input_object_type_definition.description)
343
+ ast_node(input_object_type_definition)
344
+ builder.build_directives(self, input_object_type_definition, type_resolver)
345
+ builder.build_arguments(self, input_object_type_definition.fields, type_resolver)
346
+ end
347
+ end
348
+
349
+ def build_default_value(default_value)
350
+ case default_value
351
+ when GraphQL::Language::Nodes::Enum
352
+ default_value.name
353
+ when GraphQL::Language::Nodes::NullValue
354
+ nil
355
+ when GraphQL::Language::Nodes::InputObject
356
+ default_value.to_h
357
+ when Array
358
+ default_value.map { |v| build_default_value(v) }
359
+ else
360
+ default_value
361
+ end
362
+ end
363
+
364
+ NO_DEFAULT_VALUE = {}.freeze
365
+
366
+ def build_arguments(type_class, arguments, type_resolver)
367
+ builder = self
368
+
369
+ arguments.each do |argument_defn|
370
+ default_value_kwargs = if !argument_defn.default_value.nil?
371
+ { default_value: builder.build_default_value(argument_defn.default_value) }
372
+ else
373
+ NO_DEFAULT_VALUE
374
+ end
375
+
376
+ type_class.argument(
377
+ argument_defn.name,
378
+ type: type_resolver.call(argument_defn.type),
379
+ required: false,
380
+ description: argument_defn.description,
381
+ deprecation_reason: builder.build_deprecation_reason(argument_defn.directives),
382
+ ast_node: argument_defn,
383
+ camelize: false,
384
+ directives: prepare_directives(argument_defn, type_resolver),
385
+ **default_value_kwargs
386
+ )
387
+ end
388
+ end
389
+
390
+ def build_directive(directive_definition, type_resolver)
391
+ builder = self
392
+ Class.new(GraphQL::Schema::Directive) do
393
+ graphql_name(directive_definition.name)
394
+ description(directive_definition.description)
395
+ repeatable(directive_definition.repeatable)
396
+ locations(*directive_definition.locations.map { |location| location.name.to_sym })
397
+ ast_node(directive_definition)
398
+ builder.build_arguments(self, directive_definition.arguments, type_resolver)
399
+ end
400
+ end
401
+
402
+ def build_interface_type(interface_type_definition, type_resolver)
403
+ builder = self
404
+ Module.new do
405
+ include GraphQL::Schema::Interface
406
+ graphql_name(interface_type_definition.name)
407
+ description(interface_type_definition.description)
408
+ interface_type_definition.interfaces.each do |interface_name|
409
+ interface_defn = type_resolver.call(interface_name)
410
+ implements(interface_defn)
411
+ end
412
+ ast_node(interface_type_definition)
413
+ builder.build_directives(self, interface_type_definition, type_resolver)
414
+
415
+ builder.build_fields(self, interface_type_definition.fields, type_resolver, default_resolve: nil)
416
+ end
417
+ end
418
+
419
+ def build_fields(owner, field_definitions, type_resolver, default_resolve:)
420
+ builder = self
421
+
422
+ field_definitions.each do |field_definition|
423
+ type_name = resolve_type_name(field_definition.type)
424
+ resolve_method_name = -"resolve_field_#{field_definition.name}"
425
+ schema_field_defn = owner.field(
426
+ field_definition.name,
427
+ description: field_definition.description,
428
+ type: type_resolver.call(field_definition.type),
429
+ null: true,
430
+ connection: type_name.end_with?("Connection"),
431
+ connection_extension: nil,
432
+ deprecation_reason: build_deprecation_reason(field_definition.directives),
433
+ ast_node: field_definition,
434
+ method_conflict_warning: false,
435
+ camelize: false,
436
+ directives: prepare_directives(field_definition, type_resolver),
437
+ resolver_method: resolve_method_name,
438
+ )
439
+
440
+ builder.build_arguments(schema_field_defn, field_definition.arguments, type_resolver)
441
+
442
+ # Don't do this for interfaces
443
+ if default_resolve
444
+ owner.class_eval <<-RUBY, __FILE__, __LINE__
445
+ # frozen_string_literal: true
446
+ def #{resolve_method_name}(**args)
447
+ field_instance = self.class.get_field("#{field_definition.name}")
448
+ context.schema.definition_default_resolve.call(self.class, field_instance, object, args, context)
449
+ end
450
+ RUBY
451
+ end
452
+ end
453
+ end
454
+
455
+ def build_resolve_type(lookup_hash, directives, missing_type_handler)
456
+ resolve_type_proc = nil
457
+ resolve_type_proc = ->(ast_node) {
458
+ case ast_node
459
+ when GraphQL::Language::Nodes::TypeName
460
+ type_name = ast_node.name
461
+ if lookup_hash.key?(type_name)
462
+ lookup_hash[type_name]
463
+ else
464
+ missing_type_handler.call(type_name)
465
+ end
466
+ when GraphQL::Language::Nodes::NonNullType
467
+ resolve_type_proc.call(ast_node.of_type).to_non_null_type
468
+ when GraphQL::Language::Nodes::ListType
469
+ resolve_type_proc.call(ast_node.of_type).to_list_type
470
+ when String
471
+ directives[ast_node]
472
+ else
473
+ raise "Unexpected ast_node: #{ast_node.inspect}"
474
+ end
475
+ }
476
+ resolve_type_proc
477
+ end
478
+
479
+ def resolve_type_name(type)
480
+ case type
481
+ when GraphQL::Language::Nodes::TypeName
482
+ return type.name
483
+ else
484
+ resolve_type_name(type.of_type)
485
+ end
486
+ end
487
+ end
488
+
489
+ private_constant :Builder
490
+ end
491
+ end
492
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ class Schema
4
+ BUILT_IN_TYPES = {
5
+ "Int" => GraphQL::Types::Int,
6
+ "String" => GraphQL::Types::String,
7
+ "Float" => GraphQL::Types::Float,
8
+ "Boolean" => GraphQL::Types::Boolean,
9
+ "ID" => GraphQL::Types::ID,
10
+ }
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ class Schema
4
+ class Directive < GraphQL::Schema::Member
5
+ class Deprecated < GraphQL::Schema::Directive
6
+ description "Marks an element of a GraphQL schema as no longer supported."
7
+ locations(GraphQL::Schema::Directive::FIELD_DEFINITION, GraphQL::Schema::Directive::ENUM_VALUE, GraphQL::Schema::Directive::ARGUMENT_DEFINITION, GraphQL::Schema::Directive::INPUT_FIELD_DEFINITION)
8
+
9
+ reason_description = "Explains why this element was deprecated, usually also including a "\
10
+ "suggestion for how to access supported similar data. Formatted "\
11
+ "in [Markdown](https://daringfireball.net/projects/markdown/)."
12
+
13
+ argument :reason, String, reason_description, default_value: Directive::DEFAULT_DEPRECATION_REASON, required: false
14
+ default_directive true
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ class Schema
4
+ class Directive < GraphQL::Schema::Member
5
+ # An example directive to show how you might interact with the runtime.
6
+ #
7
+ # This directive might be used along with a server-side feature flag system like Flipper.
8
+ #
9
+ # With that system, you could use this directive to exclude parts of a query
10
+ # if the current viewer doesn't have certain flags enabled.
11
+ # (So, this flag would be for internal clients, like your iOS app, not third-party API clients.)
12
+ #
13
+ # To use it, you have to implement `.enabled?`, for example:
14
+ #
15
+ # @example Implementing the Feature directive
16
+ # # app/graphql/directives/feature.rb
17
+ # class Directives::Feature < GraphQL::Schema::Directive::Feature
18
+ # def self.enabled?(flag_name, _obj, context)
19
+ # # Translate some GraphQL data for Ruby:
20
+ # flag_key = flag_name.underscore
21
+ # current_user = context[:viewer]
22
+ # # Check the feature flag however your app does it:
23
+ # MyFeatureFlags.enabled?(current_user, flag_key)
24
+ # end
25
+ # end
26
+ #
27
+ # @example Flagging a part of the query
28
+ # viewer {
29
+ # # This field only runs if `.enabled?("recommendationEngine", obj, context)`
30
+ # # returns true. Otherwise, it's treated as if it didn't exist.
31
+ # recommendations @feature(flag: "recommendationEngine") {
32
+ # name
33
+ # rating
34
+ # }
35
+ # }
36
+ class Feature < Schema::Directive
37
+ description "Directs the executor to run this only if a certain server-side feature is enabled."
38
+
39
+ locations(
40
+ GraphQL::Schema::Directive::FIELD,
41
+ GraphQL::Schema::Directive::FRAGMENT_SPREAD,
42
+ GraphQL::Schema::Directive::INLINE_FRAGMENT
43
+ )
44
+
45
+ argument :flag, String,
46
+ description: "The name of the feature to check before continuing"
47
+
48
+ # Implement the Directive API
49
+ def self.include?(object, arguments, context)
50
+ flag_name = arguments[:flag]
51
+ self.enabled?(flag_name, object, context)
52
+ end
53
+
54
+ # Override this method in your app's subclass of this directive.
55
+ #
56
+ # @param flag_name [String] The client-provided string of a feature to check
57
+ # @param object [GraphQL::Schema::Objct] The currently-evaluated GraphQL object instance
58
+ # @param context [GraphQL::Query::Context]
59
+ # @return [Boolean] If truthy, execution will continue
60
+ def self.enabled?(flag_name, object, context)
61
+ raise GraphQL::RequiredImplementationMissingError, "Implement `.enabled?(flag_name, object, context)` to return true or false for the feature flag (#{flag_name.inspect})"
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ class Schema
4
+ class Directive < GraphQL::Schema::Member
5
+ # This is _similar_ to {Directive::Feature}, except it's prescribed by the server, not the client.
6
+ #
7
+ # In this case, the server hides types and fields _entirely_, unless the current context has certain `:flags` present.
8
+ class Flagged < GraphQL::Schema::Directive
9
+ def initialize(target, **options)
10
+ if target.is_a?(Module) && !target.ancestors.include?(VisibleByFlag)
11
+ # This is type class of some kind, `include` will put this module
12
+ # in between the type class itself and its super class, so `super` will work fine
13
+ target.include(VisibleByFlag)
14
+ elsif !target.is_a?(VisibleByFlag)
15
+ # This is an instance of a base class. `include` won't put this in front of the
16
+ # base class implementation, so we need to `.prepend`.
17
+ # `#visible?` could probably be moved to a module and then this could use `include` instead.
18
+ target.class.prepend(VisibleByFlag)
19
+ end
20
+ super
21
+ end
22
+
23
+ description "Hides this part of the schema unless the named flag is present in context[:flags]"
24
+
25
+ locations(
26
+ GraphQL::Schema::Directive::FIELD_DEFINITION,
27
+ GraphQL::Schema::Directive::OBJECT,
28
+ GraphQL::Schema::Directive::SCALAR,
29
+ GraphQL::Schema::Directive::ENUM,
30
+ GraphQL::Schema::Directive::UNION,
31
+ GraphQL::Schema::Directive::INTERFACE,
32
+ GraphQL::Schema::Directive::INPUT_OBJECT,
33
+ GraphQL::Schema::Directive::ENUM_VALUE,
34
+ GraphQL::Schema::Directive::ARGUMENT_DEFINITION,
35
+ GraphQL::Schema::Directive::INPUT_FIELD_DEFINITION,
36
+ )
37
+
38
+ argument :by, [String], "Flags to check for this schema member"
39
+
40
+ module VisibleByFlag
41
+ def self.included(schema_class)
42
+ schema_class.extend(self)
43
+ end
44
+
45
+ def visible?(context)
46
+ if dir = self.directives.find { |d| d.is_a?(Flagged) }
47
+ relevant_flags = (f = context[:flags]) && dir.arguments[:by] & f # rubocop:disable Development/ContextIsPassedCop -- definition-related
48
+ relevant_flags && relevant_flags.any? && super
49
+ else
50
+ super
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ class Schema
4
+ class Directive < GraphQL::Schema::Member
5
+ class Include < GraphQL::Schema::Directive
6
+ description "Directs the executor to include this field or fragment only when the `if` argument is true."
7
+
8
+ locations(
9
+ GraphQL::Schema::Directive::FIELD,
10
+ GraphQL::Schema::Directive::FRAGMENT_SPREAD,
11
+ GraphQL::Schema::Directive::INLINE_FRAGMENT
12
+ )
13
+
14
+ argument :if, Boolean,
15
+ description: "Included when true."
16
+
17
+ default_directive true
18
+
19
+ def self.static_include?(args, ctx)
20
+ !!args[:if]
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ class Schema
4
+ class Directive < GraphQL::Schema::Member
5
+ class OneOf < GraphQL::Schema::Directive
6
+ description "Requires that exactly one field must be supplied and that field must not be `null`."
7
+ locations(GraphQL::Schema::Directive::INPUT_OBJECT)
8
+ default_directive true
9
+ end
10
+ end
11
+ end
12
+ end