graphql_cody 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (444) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +5 -0
  3. data/MIT-LICENSE +20 -0
  4. data/lib/generators/graphql/core.rb +74 -0
  5. data/lib/generators/graphql/enum_generator.rb +33 -0
  6. data/lib/generators/graphql/install_generator.rb +190 -0
  7. data/lib/generators/graphql/interface_generator.rb +27 -0
  8. data/lib/generators/graphql/loader_generator.rb +21 -0
  9. data/lib/generators/graphql/mutation_generator.rb +55 -0
  10. data/lib/generators/graphql/object_generator.rb +79 -0
  11. data/lib/generators/graphql/relay.rb +63 -0
  12. data/lib/generators/graphql/relay_generator.rb +21 -0
  13. data/lib/generators/graphql/scalar_generator.rb +20 -0
  14. data/lib/generators/graphql/templates/base_argument.erb +6 -0
  15. data/lib/generators/graphql/templates/base_connection.erb +8 -0
  16. data/lib/generators/graphql/templates/base_edge.erb +8 -0
  17. data/lib/generators/graphql/templates/base_enum.erb +6 -0
  18. data/lib/generators/graphql/templates/base_field.erb +7 -0
  19. data/lib/generators/graphql/templates/base_input_object.erb +7 -0
  20. data/lib/generators/graphql/templates/base_interface.erb +9 -0
  21. data/lib/generators/graphql/templates/base_mutation.erb +10 -0
  22. data/lib/generators/graphql/templates/base_object.erb +7 -0
  23. data/lib/generators/graphql/templates/base_scalar.erb +6 -0
  24. data/lib/generators/graphql/templates/base_union.erb +6 -0
  25. data/lib/generators/graphql/templates/enum.erb +7 -0
  26. data/lib/generators/graphql/templates/graphql_controller.erb +52 -0
  27. data/lib/generators/graphql/templates/interface.erb +8 -0
  28. data/lib/generators/graphql/templates/loader.erb +19 -0
  29. data/lib/generators/graphql/templates/mutation.erb +16 -0
  30. data/lib/generators/graphql/templates/mutation_type.erb +12 -0
  31. data/lib/generators/graphql/templates/node_type.erb +9 -0
  32. data/lib/generators/graphql/templates/object.erb +8 -0
  33. data/lib/generators/graphql/templates/query_type.erb +15 -0
  34. data/lib/generators/graphql/templates/scalar.erb +15 -0
  35. data/lib/generators/graphql/templates/schema.erb +27 -0
  36. data/lib/generators/graphql/templates/union.erb +7 -0
  37. data/lib/generators/graphql/type_generator.rb +98 -0
  38. data/lib/generators/graphql/union_generator.rb +33 -0
  39. data/lib/graphql/analysis/analyze_query.rb +98 -0
  40. data/lib/graphql/analysis/ast/analyzer.rb +84 -0
  41. data/lib/graphql/analysis/ast/field_usage.rb +51 -0
  42. data/lib/graphql/analysis/ast/max_query_complexity.rb +23 -0
  43. data/lib/graphql/analysis/ast/max_query_depth.rb +22 -0
  44. data/lib/graphql/analysis/ast/query_complexity.rb +230 -0
  45. data/lib/graphql/analysis/ast/query_depth.rb +56 -0
  46. data/lib/graphql/analysis/ast/visitor.rb +268 -0
  47. data/lib/graphql/analysis/ast.rb +91 -0
  48. data/lib/graphql/analysis/field_usage.rb +45 -0
  49. data/lib/graphql/analysis/max_query_complexity.rb +26 -0
  50. data/lib/graphql/analysis/max_query_depth.rb +26 -0
  51. data/lib/graphql/analysis/query_complexity.rb +88 -0
  52. data/lib/graphql/analysis/query_depth.rb +43 -0
  53. data/lib/graphql/analysis/reducer_state.rb +48 -0
  54. data/lib/graphql/analysis.rb +9 -0
  55. data/lib/graphql/analysis_error.rb +5 -0
  56. data/lib/graphql/argument.rb +131 -0
  57. data/lib/graphql/authorization.rb +82 -0
  58. data/lib/graphql/backtrace/inspect_result.rb +50 -0
  59. data/lib/graphql/backtrace/legacy_tracer.rb +56 -0
  60. data/lib/graphql/backtrace/table.rb +159 -0
  61. data/lib/graphql/backtrace/traced_error.rb +54 -0
  62. data/lib/graphql/backtrace/tracer.rb +81 -0
  63. data/lib/graphql/backtrace.rb +64 -0
  64. data/lib/graphql/backwards_compatibility.rb +61 -0
  65. data/lib/graphql/base_type.rb +230 -0
  66. data/lib/graphql/boolean_type.rb +2 -0
  67. data/lib/graphql/coercion_error.rb +13 -0
  68. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +53 -0
  69. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +200 -0
  70. data/lib/graphql/compatibility/execution_specification.rb +436 -0
  71. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +111 -0
  72. data/lib/graphql/compatibility/lazy_execution_specification.rb +215 -0
  73. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +87 -0
  74. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +79 -0
  75. data/lib/graphql/compatibility/query_parser_specification.rb +266 -0
  76. data/lib/graphql/compatibility/schema_parser_specification.rb +682 -0
  77. data/lib/graphql/compatibility.rb +5 -0
  78. data/lib/graphql/dataloader/null_dataloader.rb +22 -0
  79. data/lib/graphql/dataloader/request.rb +19 -0
  80. data/lib/graphql/dataloader/request_all.rb +19 -0
  81. data/lib/graphql/dataloader/source.rb +155 -0
  82. data/lib/graphql/dataloader.rb +308 -0
  83. data/lib/graphql/define/assign_argument.rb +12 -0
  84. data/lib/graphql/define/assign_connection.rb +13 -0
  85. data/lib/graphql/define/assign_enum_value.rb +18 -0
  86. data/lib/graphql/define/assign_global_id_field.rb +11 -0
  87. data/lib/graphql/define/assign_mutation_function.rb +34 -0
  88. data/lib/graphql/define/assign_object_field.rb +42 -0
  89. data/lib/graphql/define/defined_object_proxy.rb +53 -0
  90. data/lib/graphql/define/instance_definable.rb +240 -0
  91. data/lib/graphql/define/no_definition_error.rb +7 -0
  92. data/lib/graphql/define/non_null_with_bang.rb +16 -0
  93. data/lib/graphql/define/type_definer.rb +31 -0
  94. data/lib/graphql/define.rb +31 -0
  95. data/lib/graphql/deprecated_dsl.rb +55 -0
  96. data/lib/graphql/deprecation.rb +9 -0
  97. data/lib/graphql/dig.rb +19 -0
  98. data/lib/graphql/directive/deprecated_directive.rb +2 -0
  99. data/lib/graphql/directive/include_directive.rb +2 -0
  100. data/lib/graphql/directive/skip_directive.rb +2 -0
  101. data/lib/graphql/directive.rb +107 -0
  102. data/lib/graphql/enum_type.rb +133 -0
  103. data/lib/graphql/execution/directive_checks.rb +37 -0
  104. data/lib/graphql/execution/errors.rb +163 -0
  105. data/lib/graphql/execution/execute.rb +333 -0
  106. data/lib/graphql/execution/flatten.rb +40 -0
  107. data/lib/graphql/execution/instrumentation.rb +92 -0
  108. data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
  109. data/lib/graphql/execution/interpreter/arguments.rb +88 -0
  110. data/lib/graphql/execution/interpreter/arguments_cache.rb +103 -0
  111. data/lib/graphql/execution/interpreter/execution_errors.rb +29 -0
  112. data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
  113. data/lib/graphql/execution/interpreter/resolve.rb +70 -0
  114. data/lib/graphql/execution/interpreter/runtime.rb +949 -0
  115. data/lib/graphql/execution/interpreter.rb +122 -0
  116. data/lib/graphql/execution/lazy/lazy_method_map.rb +98 -0
  117. data/lib/graphql/execution/lazy/resolve.rb +91 -0
  118. data/lib/graphql/execution/lazy.rb +83 -0
  119. data/lib/graphql/execution/lookahead.rb +307 -0
  120. data/lib/graphql/execution/multiplex.rb +214 -0
  121. data/lib/graphql/execution/typecast.rb +50 -0
  122. data/lib/graphql/execution.rb +11 -0
  123. data/lib/graphql/execution_error.rb +58 -0
  124. data/lib/graphql/field/resolve.rb +59 -0
  125. data/lib/graphql/field.rb +226 -0
  126. data/lib/graphql/filter.rb +53 -0
  127. data/lib/graphql/float_type.rb +2 -0
  128. data/lib/graphql/function.rb +128 -0
  129. data/lib/graphql/id_type.rb +2 -0
  130. data/lib/graphql/input_object_type.rb +138 -0
  131. data/lib/graphql/int_type.rb +2 -0
  132. data/lib/graphql/integer_decoding_error.rb +17 -0
  133. data/lib/graphql/integer_encoding_error.rb +36 -0
  134. data/lib/graphql/interface_type.rb +72 -0
  135. data/lib/graphql/internal_representation/document.rb +27 -0
  136. data/lib/graphql/internal_representation/node.rb +206 -0
  137. data/lib/graphql/internal_representation/print.rb +51 -0
  138. data/lib/graphql/internal_representation/rewrite.rb +184 -0
  139. data/lib/graphql/internal_representation/scope.rb +88 -0
  140. data/lib/graphql/internal_representation/visit.rb +36 -0
  141. data/lib/graphql/internal_representation.rb +7 -0
  142. data/lib/graphql/introspection/base_object.rb +13 -0
  143. data/lib/graphql/introspection/directive_location_enum.rb +15 -0
  144. data/lib/graphql/introspection/directive_type.rb +29 -0
  145. data/lib/graphql/introspection/dynamic_fields.rb +17 -0
  146. data/lib/graphql/introspection/entry_points.rb +35 -0
  147. data/lib/graphql/introspection/enum_value_type.rb +23 -0
  148. data/lib/graphql/introspection/field_type.rb +28 -0
  149. data/lib/graphql/introspection/input_value_type.rb +67 -0
  150. data/lib/graphql/introspection/introspection_query.rb +7 -0
  151. data/lib/graphql/introspection/schema_type.rb +44 -0
  152. data/lib/graphql/introspection/type_kind_enum.rb +13 -0
  153. data/lib/graphql/introspection/type_type.rb +95 -0
  154. data/lib/graphql/introspection.rb +114 -0
  155. data/lib/graphql/invalid_name_error.rb +11 -0
  156. data/lib/graphql/invalid_null_error.rb +50 -0
  157. data/lib/graphql/language/block_string.rb +99 -0
  158. data/lib/graphql/language/cache.rb +37 -0
  159. data/lib/graphql/language/definition_slice.rb +41 -0
  160. data/lib/graphql/language/document_from_schema_definition.rb +347 -0
  161. data/lib/graphql/language/generation.rb +24 -0
  162. data/lib/graphql/language/lexer.rb +1467 -0
  163. data/lib/graphql/language/lexer.rl +258 -0
  164. data/lib/graphql/language/nodes.rb +707 -0
  165. data/lib/graphql/language/parser.rb +1974 -0
  166. data/lib/graphql/language/parser.y +544 -0
  167. data/lib/graphql/language/printer.rb +366 -0
  168. data/lib/graphql/language/sanitized_printer.rb +222 -0
  169. data/lib/graphql/language/token.rb +34 -0
  170. data/lib/graphql/language/visitor.rb +242 -0
  171. data/lib/graphql/language.rb +36 -0
  172. data/lib/graphql/list_type.rb +80 -0
  173. data/lib/graphql/load_application_object_failed_error.rb +22 -0
  174. data/lib/graphql/name_validator.rb +11 -0
  175. data/lib/graphql/non_null_type.rb +71 -0
  176. data/lib/graphql/object_type.rb +130 -0
  177. data/lib/graphql/pagination/active_record_relation_connection.rb +48 -0
  178. data/lib/graphql/pagination/array_connection.rb +77 -0
  179. data/lib/graphql/pagination/connection.rb +226 -0
  180. data/lib/graphql/pagination/connections.rb +160 -0
  181. data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
  182. data/lib/graphql/pagination/relation_connection.rb +196 -0
  183. data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
  184. data/lib/graphql/pagination.rb +6 -0
  185. data/lib/graphql/parse_error.rb +24 -0
  186. data/lib/graphql/query/arguments.rb +189 -0
  187. data/lib/graphql/query/arguments_cache.rb +24 -0
  188. data/lib/graphql/query/context.rb +371 -0
  189. data/lib/graphql/query/executor.rb +52 -0
  190. data/lib/graphql/query/fingerprint.rb +26 -0
  191. data/lib/graphql/query/input_validation_result.rb +43 -0
  192. data/lib/graphql/query/literal_input.rb +136 -0
  193. data/lib/graphql/query/null_context.rb +55 -0
  194. data/lib/graphql/query/result.rb +63 -0
  195. data/lib/graphql/query/serial_execution/field_resolution.rb +92 -0
  196. data/lib/graphql/query/serial_execution/operation_resolution.rb +19 -0
  197. data/lib/graphql/query/serial_execution/selection_resolution.rb +23 -0
  198. data/lib/graphql/query/serial_execution/value_resolution.rb +87 -0
  199. data/lib/graphql/query/serial_execution.rb +40 -0
  200. data/lib/graphql/query/validation_pipeline.rb +139 -0
  201. data/lib/graphql/query/variable_validation_error.rb +44 -0
  202. data/lib/graphql/query/variables.rb +78 -0
  203. data/lib/graphql/query.rb +454 -0
  204. data/lib/graphql/railtie.rb +117 -0
  205. data/lib/graphql/rake_task/validate.rb +63 -0
  206. data/lib/graphql/rake_task.rb +145 -0
  207. data/lib/graphql/relay/array_connection.rb +83 -0
  208. data/lib/graphql/relay/base_connection.rb +189 -0
  209. data/lib/graphql/relay/connection_instrumentation.rb +54 -0
  210. data/lib/graphql/relay/connection_resolve.rb +43 -0
  211. data/lib/graphql/relay/connection_type.rb +41 -0
  212. data/lib/graphql/relay/edge.rb +27 -0
  213. data/lib/graphql/relay/edge_type.rb +19 -0
  214. data/lib/graphql/relay/edges_instrumentation.rb +39 -0
  215. data/lib/graphql/relay/global_id_resolve.rb +18 -0
  216. data/lib/graphql/relay/mongo_relation_connection.rb +50 -0
  217. data/lib/graphql/relay/mutation/instrumentation.rb +23 -0
  218. data/lib/graphql/relay/mutation/resolve.rb +56 -0
  219. data/lib/graphql/relay/mutation/result.rb +38 -0
  220. data/lib/graphql/relay/mutation.rb +106 -0
  221. data/lib/graphql/relay/node.rb +39 -0
  222. data/lib/graphql/relay/page_info.rb +7 -0
  223. data/lib/graphql/relay/range_add.rb +59 -0
  224. data/lib/graphql/relay/relation_connection.rb +188 -0
  225. data/lib/graphql/relay/type_extensions.rb +32 -0
  226. data/lib/graphql/relay.rb +18 -0
  227. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  228. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  229. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  230. data/lib/graphql/rubocop.rb +4 -0
  231. data/lib/graphql/runtime_type_error.rb +5 -0
  232. data/lib/graphql/scalar_type.rb +91 -0
  233. data/lib/graphql/schema/addition.rb +247 -0
  234. data/lib/graphql/schema/argument.rb +383 -0
  235. data/lib/graphql/schema/base_64_bp.rb +26 -0
  236. data/lib/graphql/schema/base_64_encoder.rb +21 -0
  237. data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +47 -0
  238. data/lib/graphql/schema/build_from_definition/resolve_map.rb +78 -0
  239. data/lib/graphql/schema/build_from_definition.rb +477 -0
  240. data/lib/graphql/schema/built_in_types.rb +12 -0
  241. data/lib/graphql/schema/catchall_middleware.rb +35 -0
  242. data/lib/graphql/schema/default_parse_error.rb +10 -0
  243. data/lib/graphql/schema/default_type_error.rb +17 -0
  244. data/lib/graphql/schema/directive/deprecated.rb +18 -0
  245. data/lib/graphql/schema/directive/feature.rb +66 -0
  246. data/lib/graphql/schema/directive/flagged.rb +57 -0
  247. data/lib/graphql/schema/directive/include.rb +25 -0
  248. data/lib/graphql/schema/directive/skip.rb +25 -0
  249. data/lib/graphql/schema/directive/transform.rb +60 -0
  250. data/lib/graphql/schema/directive.rb +210 -0
  251. data/lib/graphql/schema/enum.rb +193 -0
  252. data/lib/graphql/schema/enum_value.rb +97 -0
  253. data/lib/graphql/schema/field/connection_extension.rb +76 -0
  254. data/lib/graphql/schema/field/scope_extension.rb +22 -0
  255. data/lib/graphql/schema/field.rb +880 -0
  256. data/lib/graphql/schema/field_extension.rb +69 -0
  257. data/lib/graphql/schema/find_inherited_value.rb +36 -0
  258. data/lib/graphql/schema/finder.rb +155 -0
  259. data/lib/graphql/schema/input_object.rb +253 -0
  260. data/lib/graphql/schema/interface.rb +136 -0
  261. data/lib/graphql/schema/introspection_system.rb +169 -0
  262. data/lib/graphql/schema/invalid_type_error.rb +7 -0
  263. data/lib/graphql/schema/late_bound_type.rb +33 -0
  264. data/lib/graphql/schema/list.rb +75 -0
  265. data/lib/graphql/schema/loader.rb +226 -0
  266. data/lib/graphql/schema/member/accepts_definition.rb +159 -0
  267. data/lib/graphql/schema/member/base_dsl_methods.rb +129 -0
  268. data/lib/graphql/schema/member/build_type.rb +180 -0
  269. data/lib/graphql/schema/member/cached_graphql_definition.rb +31 -0
  270. data/lib/graphql/schema/member/graphql_type_names.rb +21 -0
  271. data/lib/graphql/schema/member/has_arguments.rb +332 -0
  272. data/lib/graphql/schema/member/has_ast_node.rb +20 -0
  273. data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
  274. data/lib/graphql/schema/member/has_directives.rb +98 -0
  275. data/lib/graphql/schema/member/has_fields.rb +163 -0
  276. data/lib/graphql/schema/member/has_interfaces.rb +90 -0
  277. data/lib/graphql/schema/member/has_path.rb +25 -0
  278. data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
  279. data/lib/graphql/schema/member/has_validators.rb +31 -0
  280. data/lib/graphql/schema/member/instrumentation.rb +131 -0
  281. data/lib/graphql/schema/member/relay_shortcuts.rb +47 -0
  282. data/lib/graphql/schema/member/scoped.rb +21 -0
  283. data/lib/graphql/schema/member/type_system_helpers.rb +38 -0
  284. data/lib/graphql/schema/member/validates_input.rb +33 -0
  285. data/lib/graphql/schema/member.rb +161 -0
  286. data/lib/graphql/schema/middleware_chain.rb +82 -0
  287. data/lib/graphql/schema/mutation.rb +94 -0
  288. data/lib/graphql/schema/non_null.rb +67 -0
  289. data/lib/graphql/schema/null_mask.rb +11 -0
  290. data/lib/graphql/schema/object.rb +150 -0
  291. data/lib/graphql/schema/possible_types.rb +44 -0
  292. data/lib/graphql/schema/printer.rb +100 -0
  293. data/lib/graphql/schema/relay_classic_mutation.rb +160 -0
  294. data/lib/graphql/schema/rescue_middleware.rb +60 -0
  295. data/lib/graphql/schema/resolver/has_payload_type.rb +96 -0
  296. data/lib/graphql/schema/resolver.rb +397 -0
  297. data/lib/graphql/schema/scalar.rb +69 -0
  298. data/lib/graphql/schema/subscription.rb +155 -0
  299. data/lib/graphql/schema/timeout.rb +123 -0
  300. data/lib/graphql/schema/timeout_middleware.rb +88 -0
  301. data/lib/graphql/schema/traversal.rb +228 -0
  302. data/lib/graphql/schema/type_expression.rb +43 -0
  303. data/lib/graphql/schema/type_membership.rb +48 -0
  304. data/lib/graphql/schema/union.rb +95 -0
  305. data/lib/graphql/schema/unique_within_type.rb +34 -0
  306. data/lib/graphql/schema/validation.rb +313 -0
  307. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  308. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  309. data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
  310. data/lib/graphql/schema/validator/format_validator.rb +48 -0
  311. data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
  312. data/lib/graphql/schema/validator/length_validator.rb +59 -0
  313. data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
  314. data/lib/graphql/schema/validator/required_validator.rb +68 -0
  315. data/lib/graphql/schema/validator.rb +174 -0
  316. data/lib/graphql/schema/warden.rb +409 -0
  317. data/lib/graphql/schema/wrapper.rb +29 -0
  318. data/lib/graphql/schema.rb +1945 -0
  319. data/lib/graphql/static_validation/all_rules.rb +40 -0
  320. data/lib/graphql/static_validation/base_visitor.rb +217 -0
  321. data/lib/graphql/static_validation/default_visitor.rb +15 -0
  322. data/lib/graphql/static_validation/definition_dependencies.rb +198 -0
  323. data/lib/graphql/static_validation/error.rb +46 -0
  324. data/lib/graphql/static_validation/interpreter_visitor.rb +14 -0
  325. data/lib/graphql/static_validation/literal_validator.rb +139 -0
  326. data/lib/graphql/static_validation/no_validate_visitor.rb +10 -0
  327. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +66 -0
  328. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +48 -0
  329. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +31 -0
  330. data/lib/graphql/static_validation/rules/argument_names_are_unique_error.rb +30 -0
  331. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +71 -0
  332. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +37 -0
  333. data/lib/graphql/static_validation/rules/directives_are_defined.rb +23 -0
  334. data/lib/graphql/static_validation/rules/directives_are_defined_error.rb +29 -0
  335. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +65 -0
  336. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations_error.rb +31 -0
  337. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +30 -0
  338. data/lib/graphql/static_validation/rules/fields_are_defined_on_type_error.rb +32 -0
  339. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +73 -0
  340. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections_error.rb +31 -0
  341. data/lib/graphql/static_validation/rules/fields_will_merge.rb +418 -0
  342. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +53 -0
  343. data/lib/graphql/static_validation/rules/fragment_names_are_unique.rb +30 -0
  344. data/lib/graphql/static_validation/rules/fragment_names_are_unique_error.rb +29 -0
  345. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +73 -0
  346. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible_error.rb +35 -0
  347. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +39 -0
  348. data/lib/graphql/static_validation/rules/fragment_types_exist_error.rb +29 -0
  349. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +21 -0
  350. data/lib/graphql/static_validation/rules/fragments_are_finite_error.rb +29 -0
  351. data/lib/graphql/static_validation/rules/fragments_are_named.rb +16 -0
  352. data/lib/graphql/static_validation/rules/fragments_are_named_error.rb +26 -0
  353. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +37 -0
  354. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types_error.rb +30 -0
  355. data/lib/graphql/static_validation/rules/fragments_are_used.rb +32 -0
  356. data/lib/graphql/static_validation/rules/fragments_are_used_error.rb +29 -0
  357. data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
  358. data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
  359. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +17 -0
  360. data/lib/graphql/static_validation/rules/mutation_root_exists_error.rb +26 -0
  361. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +41 -0
  362. data/lib/graphql/static_validation/rules/no_definitions_are_present_error.rb +25 -0
  363. data/lib/graphql/static_validation/rules/operation_names_are_valid.rb +36 -0
  364. data/lib/graphql/static_validation/rules/operation_names_are_valid_error.rb +28 -0
  365. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +37 -0
  366. data/lib/graphql/static_validation/rules/required_arguments_are_present_error.rb +35 -0
  367. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +59 -0
  368. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present_error.rb +35 -0
  369. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +17 -0
  370. data/lib/graphql/static_validation/rules/subscription_root_exists_error.rb +26 -0
  371. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +50 -0
  372. data/lib/graphql/static_validation/rules/unique_directives_per_location_error.rb +29 -0
  373. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +46 -0
  374. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed_error.rb +39 -0
  375. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +24 -0
  376. data/lib/graphql/static_validation/rules/variable_names_are_unique_error.rb +29 -0
  377. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +153 -0
  378. data/lib/graphql/static_validation/rules/variable_usages_are_allowed_error.rb +38 -0
  379. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +39 -0
  380. data/lib/graphql/static_validation/rules/variables_are_input_types_error.rb +32 -0
  381. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +155 -0
  382. data/lib/graphql/static_validation/rules/variables_are_used_and_defined_error.rb +37 -0
  383. data/lib/graphql/static_validation/type_stack.rb +216 -0
  384. data/lib/graphql/static_validation/validation_context.rb +49 -0
  385. data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
  386. data/lib/graphql/static_validation/validator.rb +96 -0
  387. data/lib/graphql/static_validation.rb +19 -0
  388. data/lib/graphql/string_encoding_error.rb +20 -0
  389. data/lib/graphql/string_type.rb +2 -0
  390. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +245 -0
  391. data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
  392. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +21 -0
  393. data/lib/graphql/subscriptions/event.rb +144 -0
  394. data/lib/graphql/subscriptions/instrumentation.rb +79 -0
  395. data/lib/graphql/subscriptions/serialize.rb +138 -0
  396. data/lib/graphql/subscriptions/subscription_root.rb +76 -0
  397. data/lib/graphql/subscriptions.rb +299 -0
  398. data/lib/graphql/tracing/active_support_notifications_tracing.rb +35 -0
  399. data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
  400. data/lib/graphql/tracing/appsignal_tracing.rb +51 -0
  401. data/lib/graphql/tracing/data_dog_tracing.rb +76 -0
  402. data/lib/graphql/tracing/new_relic_tracing.rb +51 -0
  403. data/lib/graphql/tracing/platform_tracing.rb +139 -0
  404. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +32 -0
  405. data/lib/graphql/tracing/prometheus_tracing.rb +67 -0
  406. data/lib/graphql/tracing/scout_tracing.rb +54 -0
  407. data/lib/graphql/tracing/skylight_tracing.rb +70 -0
  408. data/lib/graphql/tracing/statsd_tracing.rb +42 -0
  409. data/lib/graphql/tracing.rb +95 -0
  410. data/lib/graphql/type_kinds.rb +77 -0
  411. data/lib/graphql/types/big_int.rb +23 -0
  412. data/lib/graphql/types/boolean.rb +18 -0
  413. data/lib/graphql/types/float.rb +19 -0
  414. data/lib/graphql/types/id.rb +24 -0
  415. data/lib/graphql/types/int.rb +36 -0
  416. data/lib/graphql/types/iso_8601_date.rb +34 -0
  417. data/lib/graphql/types/iso_8601_date_time.rb +65 -0
  418. data/lib/graphql/types/json.rb +25 -0
  419. data/lib/graphql/types/relay/base_connection.rb +39 -0
  420. data/lib/graphql/types/relay/base_edge.rb +29 -0
  421. data/lib/graphql/types/relay/connection_behaviors.rb +156 -0
  422. data/lib/graphql/types/relay/default_relay.rb +27 -0
  423. data/lib/graphql/types/relay/edge_behaviors.rb +53 -0
  424. data/lib/graphql/types/relay/has_node_field.rb +41 -0
  425. data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
  426. data/lib/graphql/types/relay/node.rb +15 -0
  427. data/lib/graphql/types/relay/node_behaviors.rb +15 -0
  428. data/lib/graphql/types/relay/node_field.rb +25 -0
  429. data/lib/graphql/types/relay/nodes_field.rb +27 -0
  430. data/lib/graphql/types/relay/page_info.rb +11 -0
  431. data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
  432. data/lib/graphql/types/relay.rb +41 -0
  433. data/lib/graphql/types/string.rb +29 -0
  434. data/lib/graphql/types.rb +11 -0
  435. data/lib/graphql/unauthorized_error.rb +29 -0
  436. data/lib/graphql/unauthorized_field_error.rb +23 -0
  437. data/lib/graphql/union_type.rb +115 -0
  438. data/lib/graphql/unresolved_type_error.rb +35 -0
  439. data/lib/graphql/upgrader/member.rb +937 -0
  440. data/lib/graphql/upgrader/schema.rb +38 -0
  441. data/lib/graphql/version.rb +4 -0
  442. data/lib/graphql.rb +168 -0
  443. data/readme.md +49 -0
  444. metadata +714 -0
@@ -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,25 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ class Schema
4
+ class Directive < GraphQL::Schema::Member
5
+ class Skip < Schema::Directive
6
+ description "Directs the executor to skip this field or fragment 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: "Skipped 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,60 @@
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 takes the return value of the tagged part of the query,
8
+ # and if the named transform is whitelisted and applies to the return value,
9
+ # it's applied by calling a method with that name.
10
+ #
11
+ # @example Installing the directive
12
+ # class MySchema < GraphQL::Schema
13
+ # directive(GraphQL::Schema::Directive::Transform)
14
+ # end
15
+ #
16
+ # @example Transforming strings
17
+ # viewer {
18
+ # username @transform(by: "upcase")
19
+ # }
20
+ class Transform < Schema::Directive
21
+ description "Directs the executor to run named transform on the return value."
22
+
23
+ locations(
24
+ GraphQL::Schema::Directive::FIELD,
25
+ )
26
+
27
+ argument :by, String,
28
+ description: "The name of the transform to run if applicable"
29
+
30
+ TRANSFORMS = [
31
+ "upcase",
32
+ "downcase",
33
+ # ??
34
+ ]
35
+ # Implement the Directive API
36
+ def self.resolve(object, arguments, context)
37
+ path = context.namespace(:interpreter)[:current_path]
38
+ return_value = yield
39
+ transform_name = arguments[:by]
40
+ if TRANSFORMS.include?(transform_name) && return_value.respond_to?(transform_name)
41
+ return_value = return_value.public_send(transform_name)
42
+ response = context.namespace(:interpreter)[:runtime].final_result
43
+ *keys, last = path
44
+ keys.each do |key|
45
+ if response && (response = response[key])
46
+ next
47
+ else
48
+ break
49
+ end
50
+ end
51
+ if response
52
+ response[last] = return_value
53
+ end
54
+ nil
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,210 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ class Schema
5
+ # Subclasses of this can influence how {GraphQL::Execution::Interpreter} runs queries.
6
+ #
7
+ # - {.include?}: if it returns `false`, the field or fragment will be skipped altogether, as if it were absent
8
+ # - {.resolve}: Wraps field resolution (so it should call `yield` to continue)
9
+ class Directive < GraphQL::Schema::Member
10
+ extend GraphQL::Schema::Member::HasArguments
11
+ class << self
12
+ # Directives aren't types, they don't have kinds.
13
+ undef_method :kind
14
+
15
+ def path
16
+ "@#{super}"
17
+ end
18
+
19
+ # Return a name based on the class name,
20
+ # but downcase the first letter.
21
+ def default_graphql_name
22
+ @default_graphql_name ||= begin
23
+ camelized_name = super
24
+ camelized_name[0] = camelized_name[0].downcase
25
+ camelized_name
26
+ end
27
+ end
28
+
29
+ def locations(*new_locations)
30
+ if new_locations.any?
31
+ new_locations.each do |new_loc|
32
+ if !LOCATIONS.include?(new_loc.to_sym)
33
+ raise ArgumentError, "#{self} (#{self.graphql_name}) has an invalid directive location: `locations #{new_loc}` "
34
+ end
35
+ end
36
+ @locations = new_locations
37
+ else
38
+ @locations ||= (superclass.respond_to?(:locations) ? superclass.locations : [])
39
+ end
40
+ end
41
+
42
+ def default_directive(new_default_directive = nil)
43
+ if new_default_directive != nil
44
+ @default_directive = new_default_directive
45
+ elsif @default_directive.nil?
46
+ @default_directive = (superclass.respond_to?(:default_directive) ? superclass.default_directive : false)
47
+ else
48
+ !!@default_directive
49
+ end
50
+ end
51
+
52
+ def default_directive?
53
+ default_directive
54
+ end
55
+
56
+ def to_graphql
57
+ defn = GraphQL::Directive.new
58
+ defn.name = self.graphql_name
59
+ defn.description = self.description
60
+ defn.locations = self.locations
61
+ defn.default_directive = self.default_directive
62
+ defn.ast_node = ast_node
63
+ defn.metadata[:type_class] = self
64
+ all_argument_definitions.each do |arg_defn|
65
+ arg_graphql = arg_defn.to_graphql
66
+ defn.arguments[arg_graphql.name] = arg_graphql # rubocop:disable Development/ContextIsPassedCop -- legacy-related
67
+ end
68
+ # Make a reference to a classic-style Arguments class
69
+ defn.arguments_class = GraphQL::Query::Arguments.construct_arguments_class(defn)
70
+
71
+ defn
72
+ end
73
+
74
+ # If false, this part of the query won't be evaluated
75
+ def include?(_object, arguments, context)
76
+ static_include?(arguments, context)
77
+ end
78
+
79
+ # Determines whether {Execution::Lookahead} considers the field to be selected
80
+ def static_include?(_arguments, _context)
81
+ true
82
+ end
83
+
84
+ # Continuing is passed as a block; `yield` to continue
85
+ def resolve(object, arguments, context)
86
+ yield
87
+ end
88
+
89
+ def on_field?
90
+ locations.include?(FIELD)
91
+ end
92
+
93
+ def on_fragment?
94
+ locations.include?(FRAGMENT_SPREAD) && locations.include?(INLINE_FRAGMENT)
95
+ end
96
+
97
+ def on_operation?
98
+ locations.include?(QUERY) && locations.include?(MUTATION) && locations.include?(SUBSCRIPTION)
99
+ end
100
+ end
101
+
102
+ # @return [GraphQL::Schema::Field, GraphQL::Schema::Argument, Class, Module]
103
+ attr_reader :owner
104
+
105
+ # @return [GraphQL::Interpreter::Arguments]
106
+ attr_reader :arguments
107
+
108
+ def initialize(owner, **arguments)
109
+ @owner = owner
110
+ assert_valid_owner
111
+ # It's be nice if we had the real context here, but we don't. What we _would_ get is:
112
+ # - error handling
113
+ # - lazy resolution
114
+ # Probably, those won't be needed here, since these are configuration arguments,
115
+ # not runtime arguments.
116
+ @arguments = self.class.coerce_arguments(nil, arguments, Query::NullContext)
117
+ end
118
+
119
+ LOCATIONS = [
120
+ QUERY = :QUERY,
121
+ MUTATION = :MUTATION,
122
+ SUBSCRIPTION = :SUBSCRIPTION,
123
+ FIELD = :FIELD,
124
+ FRAGMENT_DEFINITION = :FRAGMENT_DEFINITION,
125
+ FRAGMENT_SPREAD = :FRAGMENT_SPREAD,
126
+ INLINE_FRAGMENT = :INLINE_FRAGMENT,
127
+ SCHEMA = :SCHEMA,
128
+ SCALAR = :SCALAR,
129
+ OBJECT = :OBJECT,
130
+ FIELD_DEFINITION = :FIELD_DEFINITION,
131
+ ARGUMENT_DEFINITION = :ARGUMENT_DEFINITION,
132
+ INTERFACE = :INTERFACE,
133
+ UNION = :UNION,
134
+ ENUM = :ENUM,
135
+ ENUM_VALUE = :ENUM_VALUE,
136
+ INPUT_OBJECT = :INPUT_OBJECT,
137
+ INPUT_FIELD_DEFINITION = :INPUT_FIELD_DEFINITION,
138
+ ]
139
+
140
+ DEFAULT_DEPRECATION_REASON = 'No longer supported'
141
+ LOCATION_DESCRIPTIONS = {
142
+ QUERY: 'Location adjacent to a query operation.',
143
+ MUTATION: 'Location adjacent to a mutation operation.',
144
+ SUBSCRIPTION: 'Location adjacent to a subscription operation.',
145
+ FIELD: 'Location adjacent to a field.',
146
+ FRAGMENT_DEFINITION: 'Location adjacent to a fragment definition.',
147
+ FRAGMENT_SPREAD: 'Location adjacent to a fragment spread.',
148
+ INLINE_FRAGMENT: 'Location adjacent to an inline fragment.',
149
+ SCHEMA: 'Location adjacent to a schema definition.',
150
+ SCALAR: 'Location adjacent to a scalar definition.',
151
+ OBJECT: 'Location adjacent to an object type definition.',
152
+ FIELD_DEFINITION: 'Location adjacent to a field definition.',
153
+ ARGUMENT_DEFINITION: 'Location adjacent to an argument definition.',
154
+ INTERFACE: 'Location adjacent to an interface definition.',
155
+ UNION: 'Location adjacent to a union definition.',
156
+ ENUM: 'Location adjacent to an enum definition.',
157
+ ENUM_VALUE: 'Location adjacent to an enum value definition.',
158
+ INPUT_OBJECT: 'Location adjacent to an input object type definition.',
159
+ INPUT_FIELD_DEFINITION: 'Location adjacent to an input object field definition.',
160
+ }
161
+
162
+ private
163
+
164
+ def assert_valid_owner
165
+ case @owner
166
+ when Class
167
+ if @owner < GraphQL::Schema::Object
168
+ assert_has_location(OBJECT)
169
+ elsif @owner < GraphQL::Schema::Union
170
+ assert_has_location(UNION)
171
+ elsif @owner < GraphQL::Schema::Enum
172
+ assert_has_location(ENUM)
173
+ elsif @owner < GraphQL::Schema::InputObject
174
+ assert_has_location(INPUT_OBJECT)
175
+ elsif @owner < GraphQL::Schema::Scalar
176
+ assert_has_location(SCALAR)
177
+ elsif @owner < GraphQL::Schema
178
+ assert_has_location(SCHEMA)
179
+ else
180
+ raise "Unexpected directive owner class: #{@owner}"
181
+ end
182
+ when Module
183
+ assert_has_location(INTERFACE)
184
+ when GraphQL::Schema::Argument
185
+ if @owner.owner.is_a?(GraphQL::Schema::Field)
186
+ assert_has_location(ARGUMENT_DEFINITION)
187
+ else
188
+ assert_has_location(INPUT_FIELD_DEFINITION)
189
+ end
190
+ when GraphQL::Schema::Field
191
+ assert_has_location(FIELD_DEFINITION)
192
+ when GraphQL::Schema::EnumValue
193
+ assert_has_location(ENUM_VALUE)
194
+ else
195
+ raise "Unexpected directive owner: #{@owner.inspect}"
196
+ end
197
+ end
198
+
199
+ def assert_has_location(location)
200
+ if !self.class.locations.include?(location)
201
+ raise ArgumentError, <<-MD
202
+ Directive `@#{self.class.graphql_name}` can't be attached to #{@owner.graphql_name} because #{location} isn't included in its locations (#{self.class.locations.join(", ")}).
203
+
204
+ Use `locations(#{location})` to update this directive's definition, or remove it from #{@owner.graphql_name}.
205
+ MD
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,193 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ # Extend this class to define GraphQL enums in your schema.
5
+ #
6
+ # By default, GraphQL enum values are translated into Ruby strings.
7
+ # You can provide a custom value with the `value:` keyword.
8
+ #
9
+ # @example
10
+ # # equivalent to
11
+ # # enum PizzaTopping {
12
+ # # MUSHROOMS
13
+ # # ONIONS
14
+ # # PEPPERS
15
+ # # }
16
+ # class PizzaTopping < GraphQL::Enum
17
+ # value :MUSHROOMS
18
+ # value :ONIONS
19
+ # value :PEPPERS
20
+ # end
21
+ class Schema
22
+ class Enum < GraphQL::Schema::Member
23
+ extend GraphQL::Schema::Member::AcceptsDefinition
24
+ extend GraphQL::Schema::Member::ValidatesInput
25
+
26
+ class UnresolvedValueError < GraphQL::EnumType::UnresolvedValueError
27
+ def initialize(value:, enum:, context:)
28
+ fix_message = ", but this isn't a valid value for `#{enum.graphql_name}`. Update the field or resolver to return one of `#{enum.graphql_name}`'s values instead."
29
+ message = if (cp = context[:current_path]) && (cf = context[:current_field])
30
+ "`#{cf.path}` returned `#{value.inspect}` at `#{cp.join(".")}`#{fix_message}"
31
+ else
32
+ "`#{value.inspect}` was returned for `#{enum.graphql_name}`#{fix_message}"
33
+ end
34
+ super(message)
35
+ end
36
+ end
37
+
38
+ class << self
39
+ # Define a value for this enum
40
+ # @param graphql_name [String, Symbol] the GraphQL value for this, usually `SCREAMING_CASE`
41
+ # @param description [String], the GraphQL description for this value, present in documentation
42
+ # @param value [Object], the translated Ruby value for this object (defaults to `graphql_name`)
43
+ # @param deprecation_reason [String] if this object is deprecated, include a message here
44
+ # @return [void]
45
+ # @see {Schema::EnumValue} which handles these inputs by default
46
+ def value(*args, **kwargs, &block)
47
+ kwargs[:owner] = self
48
+ value = enum_value_class.new(*args, **kwargs, &block)
49
+ key = value.graphql_name
50
+ prev_value = own_values[key]
51
+ case prev_value
52
+ when nil
53
+ own_values[key] = value
54
+ when GraphQL::Schema::EnumValue
55
+ own_values[key] = [prev_value, value]
56
+ when Array
57
+ prev_value << value
58
+ else
59
+ raise "Invariant: Unexpected enum value for #{key.inspect}: #{prev_value.inspect}"
60
+ end
61
+ value
62
+ end
63
+
64
+ # @return [Array<GraphQL::Schema::EnumValue>] Possible values of this enum
65
+ def enum_values(context = GraphQL::Query::NullContext)
66
+ inherited_values = superclass.respond_to?(:enum_values) ? superclass.enum_values(context) : nil
67
+ visible_values = []
68
+ warden = Warden.from_context(context)
69
+ own_values.each do |key, values_entry|
70
+ if (v = Warden.visible_entry?(:visible_enum_value?, values_entry, context, warden))
71
+ visible_values << v
72
+ end
73
+ end
74
+
75
+ if inherited_values
76
+ # Local values take precedence over inherited ones
77
+ inherited_values.each do |i_val|
78
+ if !visible_values.any? { |v| v.graphql_name == i_val.graphql_name }
79
+ visible_values << i_val
80
+ end
81
+ end
82
+ end
83
+
84
+ visible_values
85
+ end
86
+
87
+ # @return [Array<Schema::EnumValue>] An unfiltered list of all definitions
88
+ def all_enum_value_definitions
89
+ all_defns = if superclass.respond_to?(:all_enum_value_definitions)
90
+ superclass.all_enum_value_definitions
91
+ else
92
+ []
93
+ end
94
+
95
+ @own_values && @own_values.each do |_key, value|
96
+ if value.is_a?(Array)
97
+ all_defns.concat(value)
98
+ else
99
+ all_defns << value
100
+ end
101
+ end
102
+
103
+ all_defns
104
+ end
105
+
106
+ # @return [Hash<String => GraphQL::Schema::EnumValue>] Possible values of this enum, keyed by name.
107
+ def values(context = GraphQL::Query::NullContext)
108
+ enum_values(context).each_with_object({}) { |val, obj| obj[val.graphql_name] = val }
109
+ end
110
+
111
+ # @return [GraphQL::EnumType]
112
+ def to_graphql
113
+ enum_type = GraphQL::EnumType.new
114
+ enum_type.name = graphql_name
115
+ enum_type.description = description
116
+ enum_type.introspection = introspection
117
+ enum_type.ast_node = ast_node
118
+ values.each do |name, val|
119
+ enum_type.add_value(val.to_graphql)
120
+ end
121
+ enum_type.metadata[:type_class] = self
122
+ enum_type
123
+ end
124
+
125
+ # @return [Class] for handling `value(...)` inputs and building `GraphQL::Enum::EnumValue`s out of them
126
+ def enum_value_class(new_enum_value_class = nil)
127
+ if new_enum_value_class
128
+ @enum_value_class = new_enum_value_class
129
+ elsif defined?(@enum_value_class) && @enum_value_class
130
+ @enum_value_class
131
+ else
132
+ superclass <= GraphQL::Schema::Enum ? superclass.enum_value_class : nil
133
+ end
134
+ end
135
+
136
+ def kind
137
+ GraphQL::TypeKinds::ENUM
138
+ end
139
+
140
+ def validate_non_null_input(value_name, ctx)
141
+ result = GraphQL::Query::InputValidationResult.new
142
+
143
+ allowed_values = ctx.warden.enum_values(self)
144
+ matching_value = allowed_values.find { |v| v.graphql_name == value_name }
145
+
146
+ if matching_value.nil?
147
+ result.add_problem("Expected #{GraphQL::Language.serialize(value_name)} to be one of: #{allowed_values.map(&:graphql_name).join(', ')}")
148
+ end
149
+
150
+ result
151
+ end
152
+
153
+ def coerce_result(value, ctx)
154
+ warden = ctx.warden
155
+ all_values = warden ? warden.enum_values(self) : values.each_value
156
+ enum_value = all_values.find { |val| val.value == value }
157
+ if enum_value
158
+ enum_value.graphql_name
159
+ else
160
+ raise self::UnresolvedValueError.new(enum: self, value: value, context: ctx)
161
+ end
162
+ end
163
+
164
+ def coerce_input(value_name, ctx)
165
+ all_values = ctx.warden ? ctx.warden.enum_values(self) : values.each_value
166
+
167
+ if v = all_values.find { |val| val.graphql_name == value_name }
168
+ v.value
169
+ elsif v = all_values.find { |val| val.value == value_name }
170
+ # this is for matching default values, which are "inputs", but they're
171
+ # the Ruby value, not the GraphQL string.
172
+ v.value
173
+ else
174
+ nil
175
+ end
176
+ end
177
+
178
+ def inherited(child_class)
179
+ child_class.const_set(:UnresolvedValueError, Class.new(Schema::Enum::UnresolvedValueError))
180
+ super
181
+ end
182
+
183
+ private
184
+
185
+ def own_values
186
+ @own_values ||= {}
187
+ end
188
+ end
189
+
190
+ enum_value_class(GraphQL::Schema::EnumValue)
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ class Schema
5
+ # A possible value for an {Enum}.
6
+ #
7
+ # You can extend this class to customize enum values in your schema.
8
+ #
9
+ # @example custom enum value class
10
+ # # define a custom class:
11
+ # class CustomEnumValue < GraphQL::Schema::EnumValue
12
+ # def initialize(*args)
13
+ # # arguments to `value(...)` in Enum classes are passed here
14
+ # super
15
+ # end
16
+ #
17
+ # def to_graphql
18
+ # enum_value = super
19
+ # # customize the derived GraphQL::EnumValue here
20
+ # enum_value
21
+ # end
22
+ # end
23
+ #
24
+ # class BaseEnum < GraphQL::Schema::Enum
25
+ # # use it for these enums:
26
+ # enum_value_class CustomEnumValue
27
+ # end
28
+ class EnumValue < GraphQL::Schema::Member
29
+ include GraphQL::Schema::Member::CachedGraphQLDefinition
30
+ include GraphQL::Schema::Member::AcceptsDefinition
31
+ include GraphQL::Schema::Member::HasPath
32
+ include GraphQL::Schema::Member::HasAstNode
33
+ include GraphQL::Schema::Member::HasDirectives
34
+ include GraphQL::Schema::Member::HasDeprecationReason
35
+
36
+ attr_reader :graphql_name
37
+
38
+ # @return [Class] The enum type that owns this value
39
+ attr_reader :owner
40
+
41
+ def initialize(graphql_name, desc = nil, owner:, ast_node: nil, directives: nil, description: nil, value: nil, deprecation_reason: nil, &block)
42
+ @graphql_name = graphql_name.to_s
43
+ GraphQL::NameValidator.validate!(@graphql_name)
44
+ @description = desc || description
45
+ @value = value.nil? ? @graphql_name : value
46
+ if deprecation_reason
47
+ self.deprecation_reason = deprecation_reason
48
+ end
49
+ @owner = owner
50
+ @ast_node = ast_node
51
+ if directives
52
+ directives.each do |dir_class, dir_options|
53
+ directive(dir_class, **dir_options)
54
+ end
55
+ end
56
+
57
+ if block_given?
58
+ instance_eval(&block)
59
+ end
60
+ end
61
+
62
+ def description(new_desc = nil)
63
+ if new_desc
64
+ @description = new_desc
65
+ end
66
+ @description
67
+ end
68
+
69
+ def value(new_val = nil)
70
+ unless new_val.nil?
71
+ @value = new_val
72
+ end
73
+ @value
74
+ end
75
+
76
+ # @return [GraphQL::EnumType::EnumValue] A runtime-ready object derived from this object
77
+ def to_graphql
78
+ enum_value = GraphQL::EnumType::EnumValue.new
79
+ enum_value.name = @graphql_name
80
+ enum_value.description = @description
81
+ enum_value.value = @value
82
+ enum_value.deprecation_reason = self.deprecation_reason
83
+ enum_value.metadata[:type_class] = self
84
+ enum_value.ast_node = ast_node
85
+ enum_value
86
+ end
87
+
88
+ def inspect
89
+ "#<#{self.class} #{path} @value=#{@value.inspect}#{description ? " @description=#{description.inspect}" : ""}>"
90
+ end
91
+
92
+ def visible?(_ctx); true; end
93
+ def accessible?(_ctx); true; end
94
+ def authorized?(_ctx); true; end
95
+ end
96
+ end
97
+ end