rails-graphql 0.2.1 → 1.0.0.beta

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 (297) hide show
  1. checksums.yaml +4 -4
  2. data/ext/console.rb +18 -0
  3. data/ext/extconf.h +3 -0
  4. data/ext/extconf.rb +1 -54
  5. data/ext/gql_parser.c +646 -0
  6. data/ext/shared.c +482 -0
  7. data/ext/shared.h +177 -0
  8. data/lib/gql_parser.so +0 -0
  9. data/lib/rails/graphql/adapters/mysql_adapter.rb +59 -0
  10. data/lib/rails/graphql/adapters/pg_adapter.rb +25 -22
  11. data/lib/rails/graphql/adapters/sqlite_adapter.rb +17 -14
  12. data/lib/rails/graphql/alternative/field_set.rb +36 -0
  13. data/lib/rails/graphql/alternative/mutation.rb +17 -0
  14. data/lib/rails/graphql/alternative/query.rb +93 -0
  15. data/lib/rails/graphql/alternative/subscription.rb +17 -0
  16. data/lib/rails/graphql/alternative.rb +20 -0
  17. data/lib/rails/graphql/argument.rb +21 -24
  18. data/lib/rails/graphql/callback.rb +24 -9
  19. data/lib/rails/graphql/collectors/hash_collector.rb +14 -6
  20. data/lib/rails/graphql/collectors/idented_collector.rb +10 -7
  21. data/lib/rails/graphql/collectors/json_collector.rb +22 -17
  22. data/lib/rails/graphql/collectors.rb +4 -4
  23. data/lib/rails/graphql/config.rb +130 -15
  24. data/lib/rails/graphql/directive/cached_directive.rb +33 -0
  25. data/lib/rails/graphql/directive/deprecated_directive.rb +10 -10
  26. data/lib/rails/graphql/directive/include_directive.rb +5 -4
  27. data/lib/rails/graphql/directive/skip_directive.rb +5 -4
  28. data/lib/rails/graphql/directive.rb +118 -63
  29. data/lib/rails/graphql/errors.rb +33 -4
  30. data/lib/rails/graphql/event.rb +16 -5
  31. data/lib/rails/graphql/field/authorized_field.rb +19 -3
  32. data/lib/rails/graphql/field/input_field.rb +11 -10
  33. data/lib/rails/graphql/field/mutation_field.rb +42 -7
  34. data/lib/rails/graphql/field/output_field.rb +102 -13
  35. data/lib/rails/graphql/field/proxied_field.rb +31 -22
  36. data/lib/rails/graphql/field/resolved_field.rb +26 -24
  37. data/lib/rails/graphql/field/scoped_config.rb +10 -4
  38. data/lib/rails/graphql/field/subscription_field.rb +140 -0
  39. data/lib/rails/graphql/field/typed_field.rb +43 -22
  40. data/lib/rails/graphql/field.rb +70 -56
  41. data/lib/rails/graphql/global_id.rb +85 -0
  42. data/lib/rails/graphql/helpers/attribute_delegator.rb +5 -5
  43. data/lib/rails/graphql/helpers/inherited_collection/array.rb +50 -0
  44. data/lib/rails/graphql/helpers/inherited_collection/base.rb +43 -0
  45. data/lib/rails/graphql/helpers/inherited_collection/hash.rb +87 -0
  46. data/lib/rails/graphql/helpers/inherited_collection.rb +25 -76
  47. data/lib/rails/graphql/helpers/instantiable.rb +15 -0
  48. data/lib/rails/graphql/helpers/leaf_from_ar.rb +7 -7
  49. data/lib/rails/graphql/helpers/registerable.rb +44 -62
  50. data/lib/rails/graphql/helpers/unregisterable.rb +16 -0
  51. data/lib/rails/graphql/helpers/with_arguments.rb +31 -27
  52. data/lib/rails/graphql/helpers/with_assignment.rb +6 -6
  53. data/lib/rails/graphql/helpers/with_callbacks.rb +25 -8
  54. data/lib/rails/graphql/helpers/with_description.rb +71 -0
  55. data/lib/rails/graphql/helpers/with_directives.rb +54 -30
  56. data/lib/rails/graphql/helpers/with_events.rb +21 -23
  57. data/lib/rails/graphql/helpers/with_fields.rb +76 -22
  58. data/lib/rails/graphql/helpers/with_global_id.rb +22 -0
  59. data/lib/rails/graphql/helpers/with_name.rb +43 -0
  60. data/lib/rails/graphql/helpers/with_namespace.rb +7 -4
  61. data/lib/rails/graphql/helpers/with_owner.rb +8 -7
  62. data/lib/rails/graphql/helpers/with_schema_fields.rb +137 -55
  63. data/lib/rails/graphql/helpers/with_validator.rb +9 -9
  64. data/lib/rails/graphql/helpers.rb +10 -3
  65. data/lib/rails/graphql/introspection.rb +43 -36
  66. data/lib/rails/graphql/railtie.rb +88 -33
  67. data/lib/rails/graphql/railties/base_generator.rb +3 -9
  68. data/lib/rails/graphql/railties/channel.rb +157 -0
  69. data/lib/rails/graphql/railties/controller.rb +62 -17
  70. data/lib/rails/graphql/railties/controller_runtime.rb +5 -5
  71. data/lib/rails/graphql/railties/log_subscriber.rb +81 -14
  72. data/lib/rails/graphql/request/arguments.rb +24 -49
  73. data/lib/rails/graphql/request/backtrace.rb +191 -0
  74. data/lib/rails/graphql/request/component/field.rb +86 -65
  75. data/lib/rails/graphql/request/component/fragment.rb +72 -24
  76. data/lib/rails/graphql/request/component/operation/subscription.rb +164 -4
  77. data/lib/rails/graphql/request/component/operation.rb +63 -31
  78. data/lib/rails/graphql/request/component/spread.rb +68 -25
  79. data/lib/rails/graphql/request/component/typename.rb +27 -12
  80. data/lib/rails/graphql/request/component.rb +75 -36
  81. data/lib/rails/graphql/request/context.rb +18 -8
  82. data/lib/rails/graphql/request/errors.rb +16 -6
  83. data/lib/rails/graphql/request/event.rb +19 -8
  84. data/lib/rails/graphql/request/helpers/directives.rb +68 -27
  85. data/lib/rails/graphql/request/helpers/selection_set.rb +51 -25
  86. data/lib/rails/graphql/request/helpers/value_writers.rb +18 -16
  87. data/lib/rails/graphql/request/prepared_data.rb +98 -0
  88. data/lib/rails/graphql/request/steps/authorizable.rb +24 -14
  89. data/lib/rails/graphql/request/steps/organizable.rb +110 -48
  90. data/lib/rails/graphql/request/steps/{prepareable.rb → preparable.rb} +20 -7
  91. data/lib/rails/graphql/request/steps/{resolveable.rb → resolvable.rb} +15 -6
  92. data/lib/rails/graphql/request/strategy/cached_strategy.rb +64 -0
  93. data/lib/rails/graphql/request/strategy/dynamic_instance.rb +6 -6
  94. data/lib/rails/graphql/request/strategy/multi_query_strategy.rb +6 -13
  95. data/lib/rails/graphql/request/strategy/sequenced_strategy.rb +9 -9
  96. data/lib/rails/graphql/request/strategy.rb +131 -75
  97. data/lib/rails/graphql/request/subscription.rb +80 -0
  98. data/lib/rails/graphql/request.rb +305 -86
  99. data/lib/rails/graphql/schema.rb +240 -48
  100. data/lib/rails/graphql/shortcuts.rb +22 -3
  101. data/lib/rails/graphql/source/active_record/builders.rb +49 -35
  102. data/lib/rails/graphql/source/active_record_source.rb +70 -54
  103. data/lib/rails/graphql/source/base.rb +111 -0
  104. data/lib/rails/graphql/source/builder.rb +128 -0
  105. data/lib/rails/graphql/source/scoped_arguments.rb +31 -19
  106. data/lib/rails/graphql/source.rb +89 -213
  107. data/lib/rails/graphql/subscription/provider/action_cable.rb +112 -0
  108. data/lib/rails/graphql/subscription/provider/base.rb +191 -0
  109. data/lib/rails/graphql/subscription/provider.rb +18 -0
  110. data/lib/rails/graphql/subscription/store/base.rb +145 -0
  111. data/lib/rails/graphql/subscription/store/memory.rb +127 -0
  112. data/lib/rails/graphql/subscription/store.rb +19 -0
  113. data/lib/rails/graphql/subscription.rb +17 -0
  114. data/lib/rails/graphql/to_gql.rb +29 -32
  115. data/lib/rails/graphql/type/enum/directive_location_enum.rb +11 -11
  116. data/lib/rails/graphql/type/enum/type_kind_enum.rb +3 -3
  117. data/lib/rails/graphql/type/enum.rb +34 -48
  118. data/lib/rails/graphql/type/input.rb +74 -23
  119. data/lib/rails/graphql/type/interface.rb +16 -26
  120. data/lib/rails/graphql/type/object/directive_object.rb +4 -4
  121. data/lib/rails/graphql/type/object/enum_value_object.rb +3 -3
  122. data/lib/rails/graphql/type/object/field_object.rb +24 -6
  123. data/lib/rails/graphql/type/object/input_value_object.rb +3 -3
  124. data/lib/rails/graphql/type/object/schema_object.rb +5 -8
  125. data/lib/rails/graphql/type/object/type_object.rb +29 -19
  126. data/lib/rails/graphql/type/object.rb +26 -23
  127. data/lib/rails/graphql/type/scalar/any_scalar.rb +30 -0
  128. data/lib/rails/graphql/type/scalar/bigint_scalar.rb +5 -5
  129. data/lib/rails/graphql/type/scalar/binary_scalar.rb +3 -3
  130. data/lib/rails/graphql/type/scalar/boolean_scalar.rb +8 -8
  131. data/lib/rails/graphql/type/scalar/date_scalar.rb +3 -3
  132. data/lib/rails/graphql/type/scalar/date_time_scalar.rb +3 -3
  133. data/lib/rails/graphql/type/scalar/decimal_scalar.rb +3 -3
  134. data/lib/rails/graphql/type/scalar/float_scalar.rb +5 -5
  135. data/lib/rails/graphql/type/scalar/id_scalar.rb +6 -5
  136. data/lib/rails/graphql/type/scalar/int_scalar.rb +6 -5
  137. data/lib/rails/graphql/type/scalar/json_scalar.rb +39 -0
  138. data/lib/rails/graphql/type/scalar/string_scalar.rb +18 -4
  139. data/lib/rails/graphql/type/scalar/time_scalar.rb +5 -5
  140. data/lib/rails/graphql/type/scalar.rb +25 -22
  141. data/lib/rails/graphql/type/union.rb +14 -16
  142. data/lib/rails/graphql/type.rb +34 -25
  143. data/lib/rails/graphql/type_map.rb +256 -164
  144. data/lib/rails/graphql/uri.rb +166 -0
  145. data/lib/rails/graphql/version.rb +15 -3
  146. data/lib/rails/graphql.rake +3 -0
  147. data/lib/rails/graphql.rb +85 -52
  148. data/lib/rails-graphql.rb +1 -1
  149. data/test/assets/en.yml +29 -0
  150. data/test/assets/introspection-mem.txt +1 -1
  151. data/test/assets/mem.gql +18 -45
  152. data/test/assets/mysql.gql +392 -0
  153. data/test/assets/sqlite.gql +21 -12
  154. data/test/assets/translate.gql +335 -0
  155. data/test/config.rb +18 -8
  156. data/test/graphql/schema_test.rb +12 -19
  157. data/test/graphql/source_test.rb +8 -75
  158. data/test/graphql/type/enum_test.rb +207 -203
  159. data/test/graphql/type/input_test.rb +14 -9
  160. data/test/graphql/type/interface_test.rb +4 -4
  161. data/test/graphql/type/scalar/any_scalar_test.rb +38 -0
  162. data/test/graphql/type/scalar/boolean_scalar_test.rb +6 -3
  163. data/test/graphql/type/scalar/json_scalar_test.rb +23 -0
  164. data/test/graphql/type_map_test.rb +51 -66
  165. data/test/graphql/type_test.rb +0 -19
  166. data/test/graphql_test.rb +1 -1
  167. data/test/integration/{authorization/authorization_test.rb → authorization_test.rb} +40 -14
  168. data/test/integration/config.rb +36 -3
  169. data/test/integration/customization_test.rb +39 -0
  170. data/test/integration/global_id_test.rb +99 -0
  171. data/test/integration/memory/star_wars_introspection_test.rb +24 -16
  172. data/test/integration/memory/star_wars_query_test.rb +54 -3
  173. data/test/integration/memory/star_wars_validation_test.rb +1 -1
  174. data/test/integration/mysql/star_wars_introspection_test.rb +25 -0
  175. data/test/integration/persisted_query_test.rb +87 -0
  176. data/test/integration/resolver_precedence_test.rb +154 -0
  177. data/test/integration/schemas/memory.rb +22 -7
  178. data/test/integration/schemas/mysql.rb +62 -0
  179. data/test/integration/schemas/sqlite.rb +21 -12
  180. data/test/integration/sqlite/star_wars_global_id_test.rb +83 -0
  181. data/test/integration/sqlite/star_wars_introspection_test.rb +10 -0
  182. data/test/integration/sqlite/star_wars_query_test.rb +14 -1
  183. data/test/integration/translate_test.rb +61 -0
  184. data/test/test_ext.rb +16 -13
  185. metadata +108 -157
  186. data/ext/depend +0 -3
  187. data/ext/graphqlparser/Ast.cpp +0 -346
  188. data/ext/graphqlparser/Ast.h +0 -1214
  189. data/ext/graphqlparser/AstNode.h +0 -36
  190. data/ext/graphqlparser/AstVisitor.h +0 -137
  191. data/ext/graphqlparser/GraphQLParser.cpp +0 -76
  192. data/ext/graphqlparser/GraphQLParser.h +0 -55
  193. data/ext/graphqlparser/JsonVisitor.cpp +0 -161
  194. data/ext/graphqlparser/JsonVisitor.cpp.inc +0 -456
  195. data/ext/graphqlparser/JsonVisitor.h +0 -121
  196. data/ext/graphqlparser/JsonVisitor.h.inc +0 -110
  197. data/ext/graphqlparser/VERSION +0 -1
  198. data/ext/graphqlparser/c/GraphQLAst.cpp +0 -324
  199. data/ext/graphqlparser/c/GraphQLAst.h +0 -180
  200. data/ext/graphqlparser/c/GraphQLAstForEachConcreteType.h +0 -44
  201. data/ext/graphqlparser/c/GraphQLAstNode.cpp +0 -25
  202. data/ext/graphqlparser/c/GraphQLAstNode.h +0 -33
  203. data/ext/graphqlparser/c/GraphQLAstToJSON.cpp +0 -21
  204. data/ext/graphqlparser/c/GraphQLAstToJSON.h +0 -24
  205. data/ext/graphqlparser/c/GraphQLAstVisitor.cpp +0 -55
  206. data/ext/graphqlparser/c/GraphQLAstVisitor.h +0 -53
  207. data/ext/graphqlparser/c/GraphQLParser.cpp +0 -35
  208. data/ext/graphqlparser/c/GraphQLParser.h +0 -54
  209. data/ext/graphqlparser/dump_json_ast.cpp +0 -48
  210. data/ext/graphqlparser/lexer.lpp +0 -324
  211. data/ext/graphqlparser/parser.ypp +0 -693
  212. data/ext/graphqlparser/parsergen/lexer.cpp +0 -2633
  213. data/ext/graphqlparser/parsergen/lexer.h +0 -528
  214. data/ext/graphqlparser/parsergen/location.hh +0 -189
  215. data/ext/graphqlparser/parsergen/parser.tab.cpp +0 -3300
  216. data/ext/graphqlparser/parsergen/parser.tab.hpp +0 -646
  217. data/ext/graphqlparser/parsergen/position.hh +0 -179
  218. data/ext/graphqlparser/parsergen/stack.hh +0 -156
  219. data/ext/graphqlparser/syntaxdefs.h +0 -19
  220. data/ext/libgraphqlparser/AstNode.h +0 -36
  221. data/ext/libgraphqlparser/CMakeLists.txt +0 -148
  222. data/ext/libgraphqlparser/CONTRIBUTING.md +0 -23
  223. data/ext/libgraphqlparser/GraphQLParser.cpp +0 -76
  224. data/ext/libgraphqlparser/GraphQLParser.h +0 -55
  225. data/ext/libgraphqlparser/JsonVisitor.cpp +0 -161
  226. data/ext/libgraphqlparser/JsonVisitor.h +0 -121
  227. data/ext/libgraphqlparser/LICENSE +0 -22
  228. data/ext/libgraphqlparser/README.clang-tidy +0 -7
  229. data/ext/libgraphqlparser/README.md +0 -84
  230. data/ext/libgraphqlparser/ast/ast.ast +0 -203
  231. data/ext/libgraphqlparser/ast/ast.py +0 -61
  232. data/ext/libgraphqlparser/ast/c.py +0 -100
  233. data/ext/libgraphqlparser/ast/c.pyc +0 -0
  234. data/ext/libgraphqlparser/ast/c_impl.py +0 -61
  235. data/ext/libgraphqlparser/ast/c_impl.pyc +0 -0
  236. data/ext/libgraphqlparser/ast/c_visitor_impl.py +0 -39
  237. data/ext/libgraphqlparser/ast/c_visitor_impl.pyc +0 -0
  238. data/ext/libgraphqlparser/ast/casing.py +0 -26
  239. data/ext/libgraphqlparser/ast/casing.pyc +0 -0
  240. data/ext/libgraphqlparser/ast/cxx.py +0 -197
  241. data/ext/libgraphqlparser/ast/cxx.pyc +0 -0
  242. data/ext/libgraphqlparser/ast/cxx_impl.py +0 -61
  243. data/ext/libgraphqlparser/ast/cxx_impl.pyc +0 -0
  244. data/ext/libgraphqlparser/ast/cxx_json_visitor_header.py +0 -42
  245. data/ext/libgraphqlparser/ast/cxx_json_visitor_header.pyc +0 -0
  246. data/ext/libgraphqlparser/ast/cxx_json_visitor_impl.py +0 -80
  247. data/ext/libgraphqlparser/ast/cxx_json_visitor_impl.pyc +0 -0
  248. data/ext/libgraphqlparser/ast/cxx_visitor.py +0 -64
  249. data/ext/libgraphqlparser/ast/cxx_visitor.pyc +0 -0
  250. data/ext/libgraphqlparser/ast/js.py +0 -65
  251. data/ext/libgraphqlparser/ast/license.py +0 -10
  252. data/ext/libgraphqlparser/ast/license.pyc +0 -0
  253. data/ext/libgraphqlparser/c/GraphQLAstNode.cpp +0 -25
  254. data/ext/libgraphqlparser/c/GraphQLAstNode.h +0 -33
  255. data/ext/libgraphqlparser/c/GraphQLAstToJSON.cpp +0 -21
  256. data/ext/libgraphqlparser/c/GraphQLAstToJSON.h +0 -24
  257. data/ext/libgraphqlparser/c/GraphQLAstVisitor.cpp +0 -55
  258. data/ext/libgraphqlparser/c/GraphQLAstVisitor.h +0 -53
  259. data/ext/libgraphqlparser/c/GraphQLParser.cpp +0 -35
  260. data/ext/libgraphqlparser/c/GraphQLParser.h +0 -54
  261. data/ext/libgraphqlparser/clang-tidy-all.sh +0 -3
  262. data/ext/libgraphqlparser/cmake/version.cmake +0 -16
  263. data/ext/libgraphqlparser/dump_json_ast.cpp +0 -48
  264. data/ext/libgraphqlparser/go/README.md +0 -20
  265. data/ext/libgraphqlparser/go/callbacks.go +0 -18
  266. data/ext/libgraphqlparser/go/gotest.go +0 -64
  267. data/ext/libgraphqlparser/lexer.lpp +0 -324
  268. data/ext/libgraphqlparser/libgraphqlparser.pc.in +0 -11
  269. data/ext/libgraphqlparser/parser.ypp +0 -693
  270. data/ext/libgraphqlparser/parsergen/lexer.cpp +0 -2633
  271. data/ext/libgraphqlparser/parsergen/lexer.h +0 -528
  272. data/ext/libgraphqlparser/parsergen/location.hh +0 -189
  273. data/ext/libgraphqlparser/parsergen/parser.tab.cpp +0 -3300
  274. data/ext/libgraphqlparser/parsergen/parser.tab.hpp +0 -646
  275. data/ext/libgraphqlparser/parsergen/position.hh +0 -179
  276. data/ext/libgraphqlparser/parsergen/stack.hh +0 -156
  277. data/ext/libgraphqlparser/python/CMakeLists.txt +0 -14
  278. data/ext/libgraphqlparser/python/README.md +0 -5
  279. data/ext/libgraphqlparser/python/example.py +0 -31
  280. data/ext/libgraphqlparser/syntaxdefs.h +0 -19
  281. data/ext/libgraphqlparser/test/BuildCAPI.c +0 -5
  282. data/ext/libgraphqlparser/test/CMakeLists.txt +0 -25
  283. data/ext/libgraphqlparser/test/JsonVisitorTests.cpp +0 -28
  284. data/ext/libgraphqlparser/test/ParserTests.cpp +0 -352
  285. data/ext/libgraphqlparser/test/kitchen-sink.graphql +0 -59
  286. data/ext/libgraphqlparser/test/kitchen-sink.json +0 -1
  287. data/ext/libgraphqlparser/test/schema-kitchen-sink.graphql +0 -78
  288. data/ext/libgraphqlparser/test/schema-kitchen-sink.json +0 -1
  289. data/ext/libgraphqlparser/test/valgrind.supp +0 -33
  290. data/ext/version.cpp +0 -21
  291. data/lib/graphqlparser.so +0 -0
  292. data/lib/rails/graphql/native/functions.rb +0 -38
  293. data/lib/rails/graphql/native/location.rb +0 -41
  294. data/lib/rails/graphql/native/pointers.rb +0 -23
  295. data/lib/rails/graphql/native/visitor.rb +0 -349
  296. data/lib/rails/graphql/native.rb +0 -56
  297. data/test/integration/schemas/authorization.rb +0 -12
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Rails # :nodoc:
4
- module GraphQL # :nodoc:
5
- module Helpers # :nodoc:
3
+ module Rails
4
+ module GraphQL
5
+ module Helpers
6
6
  # Helper module allowing leaf values to be collected direct from
7
7
  # ActiveRecord. It also helps AR Adapters to define the necessary
8
8
  # methods and settings to operate with this extractor.
@@ -12,10 +12,10 @@ module Rails # :nodoc:
12
12
  def self.extended(other)
13
13
  # Defines which type exactly represents the scalar type on the
14
14
  # ActiveRecord adapter for casting purposes
15
- other.class_attribute :ar_adapter_type, instance_writer: false, default: {}
15
+ other.class_attribute :ar_adapter_type, instance_accessor: false, default: {}
16
16
 
17
17
  # A list of ActiveRecord aliases per adapter to skip casting
18
- other.class_attribute :ar_adapter_aliases, instance_writer: false,
18
+ other.class_attribute :ar_adapter_aliases, instance_accessor: false,
19
19
  default: (Hash.new { |h, k| h[k] = Set.new })
20
20
  end
21
21
 
@@ -87,7 +87,7 @@ module Rails # :nodoc:
87
87
  # equivalent
88
88
  def define_for(adapter, **settings)
89
89
  adapter = ar_adapters[adapter] if ar_adapters.key?(adapter)
90
- raise ArgumentError, <<~MSG.squish unless ar_adapters.values.include?(adapter)
90
+ raise ArgumentError, (+<<~MSG).squish unless ar_adapters.values.include?(adapter)
91
91
  The given #{adapter.inspect} adapter is not a valid option.
92
92
  The valid options are: #{ar_adapters.to_a.flatten.map(&:inspect).to_sentence}.
93
93
  MSG
@@ -99,7 +99,7 @@ module Rails # :nodoc:
99
99
  if settings.key?(:cast)
100
100
 
101
101
  ar_adapter_type[adapter] = settings[:type] if settings.key?(:type)
102
- ar_adapter_aliases[adapter] += Array.wrap(settings[:aliases]) \
102
+ ar_adapter_aliases[adapter] += ::Array.wrap(settings[:aliases]) \
103
103
  if settings.key?(:aliases)
104
104
  end
105
105
 
@@ -1,77 +1,52 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Rails # :nodoc:
4
- module GraphQL # :nodoc:
5
- module Helpers # :nodoc:
6
- # Helper module responsible for name stuff and also responsible for
7
- # registering the objects to the type map, which also checks for the
8
- # uniqueness of the name of things.
3
+ module Rails
4
+ module GraphQL
5
+ module Helpers
6
+ # Helper module responsible for registering the objects to the type map,
7
+ # which also checks for the uniqueness of the name of things.
9
8
  module Registerable
10
- NAME_EXP = /GraphQL::(?:Type::\w+::|Directive::)?([:\w]+?)([A-Z][a-z]+)?\z/.freeze
11
-
12
9
  # Here we define a couple of attributes used by registration
13
10
  def self.extended(other)
14
- other.extend(Registerable::ClassMethods)
11
+ other.extend(Helpers::Unregisterable)
15
12
  other.extend(Helpers::WithNamespace)
16
-
17
- # If a type is marked as abstract, it's then used as a base and it
18
- # won't appear in the introspection
19
- other.class_attribute :abstract, instance_writer: false, default: false
13
+ other.extend(Helpers::WithName)
14
+ other.extend(Helpers::WithDescription)
20
15
 
21
16
  # Marks if the object is one of those defined on the spec, which
22
17
  # marks the object as part of the introspection system
23
- other.class_attribute :spec_object, instance_writer: false, default: false
24
-
25
- # The given description of the type
26
- other.class_attribute :description, instance_writer: false
18
+ other.class_attribute :spec_object, instance_accessor: false, default: false
27
19
  end
28
20
 
29
- module ClassMethods # :nodoc: all
30
- # Here we wait for the class to be fully loaded so that we can
31
- # correctly trigger the registration
32
- def inherited(subclass)
33
- super if defined? super
34
- return if subclass.try(:abstract)
35
- GraphQL.type_map.postpone_registration(subclass)
36
- end
37
-
38
- # Check if the class is already registered in the typemap
39
- def registered?
40
- GraphQL.type_map.object_exist?(self, exclusive: true)
41
- end
42
-
43
- # The process to register a class and it's name on the index
44
- def register!
45
- return if abstract? || gql_name.blank?
46
-
47
- raise DuplicatedError, <<~MSG.squish if registered?
48
- The "#{gql_name}" is already defined, the only way to change its
49
- definition is by using extensions.
50
- MSG
51
-
52
- invalid_internal = !spec_object && gql_name.start_with?('__')
53
- raise NameError, <<~MSG.squish if invalid_internal
54
- The name "#{gql_name}" is invalid. Only internal objects from the
55
- spec can have a name starting with "__".
56
- MSG
57
-
58
- super if defined? super
59
- GraphQL.type_map.register(self).method(:validate!)
60
- end
21
+ # Here we wait for the class to be fully loaded so that we can
22
+ # correctly trigger the registration
23
+ def inherited(subclass)
24
+ super if defined? super
25
+ GraphQL.type_map.postpone_registration(subclass)
61
26
  end
62
27
 
63
- # Return the name of the object as a GraphQL name
64
- def gql_name
65
- @gql_name ||= begin
66
- name.match(NAME_EXP).try(:[], 1)&.tr(':', '')
67
- end unless anonymous?
28
+ # Check if the class is already registered in the typemap
29
+ def registered?
30
+ GraphQL.type_map.object_exist?(self, exclusive: true)
68
31
  end
69
32
 
70
- alias graphql_name gql_name
33
+ # The process to register a class and it's name on the index
34
+ def register!
35
+ return if abstract? || gql_name.blank?
36
+
37
+ raise DuplicatedError, (+<<~MSG).squish if registered?
38
+ The "#{gql_name}" is already defined, the only way to change its
39
+ definition is by using extensions.
40
+ MSG
71
41
 
72
- # Return the name of the object as a symbol
73
- def to_sym
74
- @gql_key ||= gql_name&.underscore&.to_sym
42
+ invalid_internal = !spec_object && gql_name.start_with?('__')
43
+ raise NameError, (+<<~MSG).squish if invalid_internal
44
+ The name "#{gql_name}" is invalid. Only internal objects from the
45
+ spec can have a name starting with "__".
46
+ MSG
47
+
48
+ super if defined? super
49
+ GraphQL.type_map.register(self)
75
50
  end
76
51
 
77
52
  # Get or set a list of aliases for this object
@@ -85,17 +60,24 @@ module Rails # :nodoc:
85
60
  end
86
61
  end
87
62
 
63
+ # TODO: When an object is frozen, it was successfully validated
64
+ # alias valid? frozen?
65
+
88
66
  protected
89
67
 
90
68
  # An alias for +description = value.strip_heredoc.chomp+ that can be
91
69
  # used as method
92
70
  def desc(value)
93
- self.description = value.strip_heredoc.chomp
71
+ self.description = value
94
72
  end
95
73
 
96
- # Change the gql name of the object
97
- def rename!(name)
98
- @gql_name = name
74
+ def rename!(*)
75
+ GraphQL.logger.warn((+<<~MSG).squish) if registered?
76
+ \e[95m[GraphQL] Renaming #{name} after it has being registered
77
+ may cause unexpected behaviors.\e[0m
78
+ MSG
79
+
80
+ super
99
81
  end
100
82
  end
101
83
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails
4
+ module GraphQL
5
+ module Helpers
6
+ # Helper that allows unregisterable objects to be both identified and
7
+ # removed from type map
8
+ module Unregisterable
9
+ # Simply remove itself from the type map
10
+ def unregister!
11
+ GraphQL.type_map.unregister(self)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Rails # :nodoc:
4
- module GraphQL # :nodoc:
5
- module Helpers # :nodoc:
3
+ module Rails
4
+ module GraphQL
5
+ module Helpers
6
6
  # Helper module that allows other objects to hold arguments
7
7
  module WithArguments
8
8
  def self.extended(other)
@@ -13,14 +13,22 @@ module Rails # :nodoc:
13
13
 
14
14
  def self.included(other)
15
15
  other.define_method(:arguments) do
16
- defined?(@arguments) ? @arguments : {}
16
+ @arguments ||= {}
17
+ end
18
+
19
+ other.define_method(:all_arguments) do
20
+ @arguments if defined?(@arguments)
21
+ end
22
+
23
+ other.define_method(:arguments?) do
24
+ defined?(@arguments) && @arguments.present?
17
25
  end
18
26
  end
19
27
 
20
- module ClassMethods # :nodoc: all
28
+ module ClassMethods
21
29
  def inherited(subclass)
22
30
  super if defined? super
23
- return if arguments.empty?
31
+ return if arguments.blank?
24
32
 
25
33
  new_arguments = Helpers.dup_all_with_owner(arguments.transform_values, subclass)
26
34
  subclass.instance_variable_set(:@arguments, new_arguments)
@@ -28,13 +36,13 @@ module Rails # :nodoc:
28
36
  end
29
37
 
30
38
  def initialize(*args, arguments: nil, **xargs, &block)
31
- @arguments = Array.wrap(arguments).map do |object|
32
- raise ArgumentError, <<~MSG.squish unless object.is_a?(Argument)
33
- The given "#{object.inspect}" is not a valid Argument object.
39
+ @arguments = GraphQL.enumerate(arguments).each_with_object({}) do |item, hash|
40
+ raise ArgumentError, (+<<~MSG).squish unless item.is_a?(Argument)
41
+ The given "#{item.inspect}" is not a valid Argument object.
34
42
  MSG
35
43
 
36
- [object.name, Helpers.dup_with_owner(object, self)]
37
- end.to_h unless arguments.nil?
44
+ hash[item.name] = Helpers.dup_with_owner(item, self)
45
+ end unless arguments.nil?
38
46
 
39
47
  super(*args, **xargs, &block)
40
48
  end
@@ -50,39 +58,33 @@ module Rails # :nodoc:
50
58
  super && other.respond_to?(:all_arguments) && match_arguments?(other)
51
59
  end
52
60
 
53
- # Mostly for correct inheritance on instances
54
- def all_arguments
55
- defined?(@arguments) ? @arguments : {}
56
- end
57
-
58
61
  # See {Argument}[rdoc-ref:Rails::GraphQL::Argument] class.
59
62
  def argument(name, base_type, **xargs)
60
- xargs[:owner] = self
61
- object = GraphQL::Argument.new(name, base_type, **xargs)
63
+ object = GraphQL::Argument.new(name, base_type, **xargs, owner: self)
62
64
 
63
- raise DuplicatedError, <<~MSG.squish if has_argument?(object.name)
65
+ raise DuplicatedError, (+<<~MSG).squish if has_argument?(object.name)
64
66
  The #{name.inspect} argument is already defined and can't be redefined.
65
67
  MSG
66
68
 
67
- (@arguments ||= {})[object.name] = object
69
+ arguments[object.name] = object
68
70
  rescue DefinitionError => e
69
- raise e.class, e.message + "\n Defined at: #{caller(2)[0]}"
71
+ raise e.class, +"#{e.message}\n Defined at: #{caller(2)[0]}"
70
72
  end
71
73
 
72
74
  # Since arguments' owner are more flexible, their instances can be
73
75
  # directly associated to objects that have argument
74
76
  def ref_argument(object)
75
- raise ArgumentError, <<~MSG.squish unless object.is_a?(GraphQL::Argument)
77
+ raise ArgumentError, (+<<~MSG).squish unless object.is_a?(GraphQL::Argument)
76
78
  The given object #{object.inspect} is not a valid argument.
77
79
  MSG
78
80
 
79
- raise DuplicatedError, <<~MSG.squish if has_argument?(object.name)
81
+ raise DuplicatedError, (+<<~MSG).squish if has_argument?(object.name)
80
82
  The #{object.name.inspect} argument is already defined and can't be redefined.
81
83
  MSG
82
84
 
83
85
  (@arguments ||= {})[object.name] = object
84
86
  rescue DefinitionError => e
85
- raise e.class, e.message + "\n Defined at: #{caller(2)[0]}"
87
+ raise e.class, +"#{e.message}\n Defined at: #{caller(2)[0]}"
86
88
  end
87
89
 
88
90
  # A short cute for arguments named and typed as id
@@ -110,14 +112,16 @@ module Rails # :nodoc:
110
112
 
111
113
  # Show all the arguments as their inspect version
112
114
  def inspect_arguments
113
- args = all_arguments.each_value.map(&:inspect)
114
- args.presence && "(#{args.join(', ')})"
115
+ args = all_arguments&.each_value&.map(&:inspect)
116
+ args.presence && +"(#{args.join(', ')})"
115
117
  end
116
118
 
117
119
  # Check the equivalency of arguments
118
120
  def match_arguments?(other)
119
121
  l_args, r_args = all_arguments, other.all_arguments
120
- l_args.size <= r_args.size && l_args.all? { |key, arg| arg =~ r_args[key] }
122
+ l_args.class == r_args.class &&
123
+ l_args.size <= r_args.size &&
124
+ l_args.all? { |key, arg| arg =~ r_args[key] }
121
125
  end
122
126
  end
123
127
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Rails # :nodoc:
4
- module GraphQL # :nodoc:
5
- module Helpers # :nodoc:
3
+ module Rails
4
+ module GraphQL
5
+ module Helpers
6
6
  # Helper module that allows other objects to hold an +assigned_to+ object
7
7
  module WithAssignment
8
8
  # Add extra instance based methods
@@ -11,7 +11,7 @@ module Rails # :nodoc:
11
11
  :assigned_class, to: :class
12
12
  end
13
13
 
14
- # Check if the class is assgined
14
+ # Check if the class is assigned
15
15
  def assigned?
16
16
  assigned_to.present?
17
17
  end
@@ -65,7 +65,7 @@ module Rails # :nodoc:
65
65
  return result unless (klass = safe_assigned_class)
66
66
  return result if GraphQL.type_map.exist?(klass, namespaces: namespaces)
67
67
 
68
- GraphQL.type_map.register_alias(klass, namespaces: namespaces, &method(:itself))
68
+ GraphQL.type_map.register_alias(klass, to_sym, namespaces: namespaces)
69
69
  result
70
70
  end
71
71
 
@@ -93,7 +93,7 @@ module Rails # :nodoc:
93
93
  klass = klass.superclass
94
94
  end
95
95
 
96
- message = !block.nil? ? block.call(klass) : <<~MSG.squish
96
+ message = !block.nil? ? block.call(klass) : (+<<~MSG).squish
97
97
  The "#{klass.name}" is not a subclass of #{base_class.name}.
98
98
  MSG
99
99
 
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Rails # :nodoc:
4
- module GraphQL # :nodoc:
5
- module Helpers # :nodoc:
3
+ module Rails
4
+ module GraphQL
5
+ module Helpers
6
6
  # Callbacks is an extension of the events which works with the
7
7
  # {Callback}[rdoc-ref:Rails::GraphQL::Callback] class, then having extra
8
8
  # powers when actually executing the event against procs or owner-based
@@ -17,7 +17,7 @@ module Rails # :nodoc:
17
17
 
18
18
  def self.included(other)
19
19
  other.extend(WithCallbacks::Setup)
20
- other.delegate(:event_filters, to: :class)
20
+ other.delegate(:event_filters, :default_exclusive?, to: :class)
21
21
  end
22
22
 
23
23
  # Add the ability to set up filters before the actual execution of the
@@ -31,15 +31,32 @@ module Rails # :nodoc:
31
31
  # Return the list of event filters hooks
32
32
  def event_filters
33
33
  return @event_filters if defined? @event_filters
34
- superclass.try(:event_filters) || {}
34
+ superclass.try(:event_filters) || EMPTY_HASH
35
+ end
36
+
37
+ # Set the default +exclusive+ value for the given +for+ event names
38
+ def default_exclusive(value, **xargs)
39
+ new_values = Array.wrap(xargs.fetch(:for)).map(&:to_sym).product([value]).to_h
40
+ @callback_exclusive ||= superclass.try(:callback_exclusive)&.dup || {}
41
+ @callback_exclusive.merge!(new_values)
42
+ end
43
+
44
+ # Check if the given +event_name+ should be thread as exclusive or
45
+ # non-exclusive by default
46
+ def default_exclusive?(event_name)
47
+ if defined?(@callback_exclusive)
48
+ @callback_exclusive[event_name]
49
+ else
50
+ superclass.try(:default_exclusive?, event_name)
51
+ end
35
52
  end
36
53
 
37
54
  protected
38
55
 
39
56
  # Attach a new key based event filter
40
- def event_filter(key, sanitizer = nil, &block)
57
+ def event_filter(key, &block)
41
58
  @event_filters ||= superclass.try(:event_filters)&.dup || {}
42
- @event_filters[key.to_sym] = { block: block, sanitizer: sanitizer }
59
+ @event_filters[key.to_sym] = block
43
60
  end
44
61
  end
45
62
 
@@ -47,7 +64,7 @@ module Rails # :nodoc:
47
64
  # {Callback}[rdoc-ref:Rails::GraphQL::Callback] object.
48
65
  def on(event_name, *args, unshift: false, **xargs, &block)
49
66
  block = Callback.new(self, event_name, *args, **xargs, &block)
50
- super(event_name, unshift: unshift, &block)
67
+ super(event_name, block, unshift: unshift)
51
68
  end
52
69
  end
53
70
  end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails
4
+ module GraphQL
5
+ module Helpers
6
+ module WithDescription
7
+
8
+ # A getter or setter in the same function
9
+ def desc(value = nil)
10
+ value.nil? ? description : (self.description = value)
11
+ end
12
+
13
+ # Define and format description
14
+ def description=(value)
15
+ @description = value.to_s.presence&.strip_heredoc&.chomp
16
+ end
17
+
18
+ # Return the description of the argument
19
+ def description(namespace = nil, kind = nil)
20
+ return @description if description?
21
+ return unless GraphQL.config.enable_i18n_descriptions
22
+
23
+ # If it has been defined, but as nil, then it will always be nil
24
+ return if defined?(@description)
25
+ @description = i18n_description(namespace, kind)
26
+ end
27
+
28
+ # Checks if a description was provided
29
+ def description?
30
+ defined?(@description) && !!@description
31
+ end
32
+
33
+ protected
34
+
35
+ # Return a description from I18n
36
+ def i18n_description(namespace = nil, kind = nil)
37
+ return if (parent = try(:owner)).try(:spec_object?)
38
+
39
+ values = {
40
+ kind: kind || try(:kind),
41
+ parent: i18n_parent_value(parent),
42
+ namespace: GraphQL.enumerate(namespace || try(:namespaces)).first,
43
+ name: is_a?(Module) ? to_sym : name,
44
+ }
45
+
46
+ options = GraphQL.config.i18n_scopes.dup
47
+ while option = options.shift
48
+ key = format(option, values)
49
+ next if key.include?('..')
50
+
51
+ result = catch(:exception) { ::I18n.translate(key, throw: true) }
52
+ return result unless result.is_a?(Hash) ||
53
+ result.is_a?(I18n::MissingTranslation)
54
+ end
55
+ end
56
+
57
+ # Properly figure out the parent value for the interpolation
58
+ def i18n_parent_value(parent)
59
+ if parent.respond_to?(:i18n_scope)
60
+ parent.i18n_scope(self)
61
+ elsif parent.is_a?(Helpers::WithSchemaFields) && respond_to?(:schema_type)
62
+ schema_type
63
+ else
64
+ parent.try(:to_sym)
65
+ end
66
+ end
67
+
68
+ end
69
+ end
70
+ end
71
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Rails # :nodoc:
4
- module GraphQL # :nodoc:
5
- module Helpers # :nodoc:
3
+ module Rails
4
+ module GraphQL
5
+ module Helpers
6
6
  # Helper module that allows other objects to hold directives during the
7
7
  # definition process
8
8
  module WithDirectives
@@ -15,12 +15,14 @@ module Rails # :nodoc:
15
15
  def self.included(other)
16
16
  other.extend(WithDirectives::DirectiveLocation)
17
17
  other.define_method(:directives) { @directives ||= Set.new }
18
- other.class_attribute(:directive_location, instance_writer: false)
18
+ other.define_method(:all_directives) { @directives if defined?(@directives) }
19
+ other.define_method(:directives?) { defined?(@directives) && @directives.present? }
19
20
  end
20
21
 
21
22
  def initialize_copy(orig)
22
23
  super
23
24
 
25
+ return if orig.directives.nil?
24
26
  @directives = orig.directives.dup
25
27
  end
26
28
 
@@ -35,25 +37,20 @@ module Rails # :nodoc:
35
37
 
36
38
  # Use this once to define the directive location
37
39
  def directive_location=(value)
38
- raise ArgumentError, 'Directive location is already defined' \
40
+ raise ArgumentError, +'Directive location is already defined' \
39
41
  unless directive_location.nil?
40
42
 
41
43
  @directive_location = value
42
44
  end
43
45
  end
44
46
 
45
- # Mostly for correct inheritance on instances
46
- def all_directives
47
- defined?(@directives) ? @directives : Set.new
48
- end
49
-
50
47
  # Use this method to assign directives to the given definition. You can
51
48
  # also provide a symbol as a first argument and extra named-arguments
52
49
  # to auto initialize a new instance of that directive.
53
50
  def use(item_or_symbol, *list, **xargs)
54
51
  if item_or_symbol.is_a?(Symbol)
55
52
  directive = fetch!(item_or_symbol)
56
- raise ArgumentError, <<~MSG.squish unless directive < GraphQL::Directive
53
+ raise ArgumentError, (+<<~MSG).squish unless directive < GraphQL::Directive
57
54
  Unable to find the #{item_or_symbol.inspect} directive.
58
55
  MSG
59
56
 
@@ -62,21 +59,19 @@ module Rails # :nodoc:
62
59
  list << item_or_symbol
63
60
  end
64
61
 
65
- current = try(:all_directives) || @directives
66
- items = GraphQL.directives_to_set(list, current, source: self)
67
- directives.merge(items)
62
+ directives += GraphQL.directives_to_set(list, all_directives, source: self)
68
63
  rescue DefinitionError => e
69
- raise e.class, e.message + "\n Defined at: #{caller(2)[0]}"
64
+ raise e.class, +"#{e.message}\n Defined at: #{caller(2)[0]}"
70
65
  end
71
66
 
72
- # Check wheter a given directive is being used
73
- def using?(item_or_symbol)
74
- directive = item_or_symbol.is_a?(Symbol) ? fetch!(item_or_symbol) : item_or_symbol
75
- raise ArgumentError, <<~MSG.squish unless directive < GraphQL::Directive
76
- The provided #{item_or_symbol.inspect} is not a valid directive.
67
+ # Check whether a given directive is being used
68
+ def using?(item)
69
+ directive = (item.is_a?(Symbol) || item.is_a?(String)) ? fetch!(item) : item
70
+ raise ArgumentError, (+<<~MSG).squish unless directive < GraphQL::Directive
71
+ The provided #{item.inspect} is not a valid directive.
77
72
  MSG
78
73
 
79
- all_directives.any? { |item| item.is_a?(directive) }
74
+ !!all_directives&.any?(directive)
80
75
  end
81
76
 
82
77
  alias has_directive? using?
@@ -84,23 +79,45 @@ module Rails # :nodoc:
84
79
  # Override the +all_listeners+ method since callbacks can eventually be
85
80
  # attached to objects that have directives, which then they need to
86
81
  # be combined
87
- def all_listeners
88
- current = all_directives.map(&:all_listeners).reduce(:+) || Set.new
89
- (defined?(super) ? super : Set.new) + current
82
+ def all_directive_listeners
83
+ inherited = super if defined?(super)
84
+ return inherited unless directives?
85
+
86
+ current = all_directives.map(&:all_listeners).compact.reduce(:+)
87
+ inherited.nil? ? current : inherited + current
88
+ end
89
+
90
+ alias all_listeners all_directive_listeners
91
+
92
+ # Make sure to consider directive listeners while checking for listeners
93
+ def directive_listeners?
94
+ (defined?(super) && super) || all_directives&.any?(&:listeners?)
90
95
  end
91
96
 
97
+ alias listeners? directive_listeners?
98
+
92
99
  # Override the +all_events+ method since callbacks can eventually be
93
100
  # attached to objects that have directives, which then they need to
94
101
  # be combined
95
- def all_events
96
- Helpers::AttributeDelegator.new do
97
- base = defined?(super) ? super : {}
98
- all_directives.map(&:all_events).inject(base) do |lhash, rhash|
99
- Helpers.merge_hash_array(lhash, rhash)
100
- end
102
+ def all_directive_events
103
+ inherited = super if defined?(super)
104
+ return inherited unless directives?
105
+
106
+ all_directives.inject(inherited || {}) do |result, directive|
107
+ next result if (val = directive.all_events).blank?
108
+ Helpers.merge_hash_array(result, val)
101
109
  end
102
110
  end
103
111
 
112
+ alias all_events all_directive_events
113
+
114
+ # Make sure to consider directive events while checking for events
115
+ def directive_events?
116
+ (defined?(super) && super) || all_directives&.any?(&:events?)
117
+ end
118
+
119
+ alias events? directive_events?
120
+
104
121
  # Validate all the directives to make sure the definition is valid
105
122
  def validate!(*)
106
123
  super if defined? super
@@ -110,6 +127,13 @@ module Rails # :nodoc:
110
127
  @directives.freeze
111
128
  end
112
129
 
130
+ protected
131
+
132
+ # Helper method to inspect the directives
133
+ def inspect_directives
134
+ all_directives&.map(&:inspect)&.join(' ')
135
+ end
136
+
113
137
  private
114
138
 
115
139
  # Find a directive for its symbolized name