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,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Rails # :nodoc:
4
- module GraphQL # :nodoc:
3
+ module Rails
4
+ module GraphQL
5
5
  # = GraphQL Field
6
6
  #
7
7
  # A field has multiple purposes, which is defined by the specific subclass
@@ -20,8 +20,6 @@ module Rails # :nodoc:
20
20
  # (defaults to true).
21
21
  # * <tt>:full</tt> - Shortcut for +null: false, nullable: false, array: true+
22
22
  # (defaults to false).
23
- # * <tt>:method_name</tt> - The name of the method used to fetch the field data
24
- # (defaults to nil).
25
23
  # * <tt>:enabled</tt> - Mark the field as enabled
26
24
  # (defaults to true).
27
25
  # * <tt>:disabled</tt> - Works as the oposite of the enabled option
@@ -35,6 +33,7 @@ module Rails # :nodoc:
35
33
  class Field
36
34
  extend ActiveSupport::Autoload
37
35
  include Helpers::WithDirectives
36
+ include Helpers::WithDescription
38
37
 
39
38
  autoload :ScopedConfig
40
39
 
@@ -46,19 +45,25 @@ module Rails # :nodoc:
46
45
  autoload :InputField
47
46
  autoload :OutputField
48
47
  autoload :MutationField
48
+ autoload :SubscriptionField
49
49
 
50
50
  attr_reader :name, :gql_name, :owner
51
51
 
52
- delegate :input_type?, :output_type?, :leaf_type?, :proxy?, :mutation?, to: :class
52
+ alias gid_base_class owner
53
+ alias proxied_owner owner
54
+ alias to_sym name
55
+
53
56
  delegate :namespaces, to: :owner
57
+ delegate :input_type?, :output_type?, :leaf_type?, :proxy?,
58
+ :mutation?, :subscription?, to: :class
54
59
 
55
60
  class << self
56
61
  # A small shared helper method that allows field information to be
57
62
  # proxied
58
63
  def proxyable_methods(*list, klass:, allow_nil: false)
59
64
  list = list.flatten.compact.map do |method_name|
60
- ivar = '@' + method_name.delete_suffix('?')
61
- accessor = 'field' + (allow_nil ? '&.' : '.') + method_name
65
+ ivar = +'@' + method_name.delete_suffix('?')
66
+ accessor = +'field' + (allow_nil ? '&.' : '.') + method_name
62
67
  "def #{method_name}; defined?(#{ivar}) ? #{ivar} : #{accessor}; end"
63
68
  end
64
69
 
@@ -89,13 +94,21 @@ module Rails # :nodoc:
89
94
  def mutation?
90
95
  false
91
96
  end
97
+
98
+ # Checks if the field is associated with a subscription
99
+ def subscription?
100
+ false
101
+ end
92
102
  end
93
103
 
94
104
  def initialize(name, owner:, **xargs, &block)
95
105
  @owner = owner
96
106
  normalize_name(name)
97
107
 
98
- @directives = GraphQL.directives_to_set(xargs[:directives], source: self)
108
+ # TODO: Replace by a proper method to build and set @directives
109
+ directives = GraphQL.directives_to_set(xargs[:directives], source: self)
110
+ @directives = directives unless directives.nil?
111
+
99
112
  @method_name = xargs[:method_name].to_s.underscore.to_sym \
100
113
  unless xargs[:method_name].nil?
101
114
 
@@ -104,13 +117,13 @@ module Rails # :nodoc:
104
117
  @array = full ? true : xargs.fetch(:array, false)
105
118
  @nullable = full ? false : xargs.fetch(:nullable, true)
106
119
 
107
- @desc = xargs[:desc]&.strip_heredoc&.chomp
120
+ self.description = xargs[:desc]
108
121
  @enabled = xargs.fetch(:enabled, !xargs.fetch(:disabled, false))
109
122
 
110
123
  configure(&block) if block.present?
111
124
  end
112
125
 
113
- def initialize_copy(*) # :nodoc:
126
+ def initialize_copy(*)
114
127
  super
115
128
 
116
129
  @owner = nil
@@ -123,7 +136,7 @@ module Rails # :nodoc:
123
136
  disable! if xargs.fetch(:disabled, false)
124
137
  enable! if xargs.fetch(:enabled, false)
125
138
 
126
- @desc = xargs[:desc].strip_heredoc.chomp if xargs.key?(:desc)
139
+ self.description = xargs[:desc] if xargs.key?(:desc)
127
140
  configure(&block) if block.present?
128
141
  end
129
142
 
@@ -132,22 +145,40 @@ module Rails # :nodoc:
132
145
  Field::ScopedConfig.new(self, block.binding.receiver).instance_exec(&block)
133
146
  end
134
147
 
148
+ # Return the owner as the single item of the list
149
+ def all_owners
150
+ [owner]
151
+ end
152
+
135
153
  # Returns the name of the method used to retrieve the information
136
154
  def method_name
137
- defined?(@method_name) ? @method_name : @name
155
+ if defined?(@method_name)
156
+ @method_name
157
+ elsif from_alternative?
158
+ :resolve
159
+ else
160
+ @name
161
+ end
138
162
  end
139
163
 
140
- # Check if the other field is equivalent
141
- def =~(other)
142
- other.is_a?(GraphQL::Field) &&
143
- other.array? == array? &&
144
- (other.null? == null? || other.null? && !null?) &&
145
- (other.nullable? == nullable? || other.nullable? && !nullable?)
164
+ # Mark the field as globally enabled
165
+ def enable!
166
+ @enabled = true
146
167
  end
147
168
 
148
- # Return the owner as the single item of the list
149
- def all_owners
150
- [owner]
169
+ # Mark the field as globally disabled
170
+ def disable!
171
+ @enabled = false
172
+ end
173
+
174
+ # Update the null value
175
+ def required!
176
+ @null = false
177
+ end
178
+
179
+ # Update the nullable value
180
+ def required_items!
181
+ @nullable = false
151
182
  end
152
183
 
153
184
  # Checks if the argument can be null
@@ -175,24 +206,9 @@ module Rails # :nodoc:
175
206
  !enabled?
176
207
  end
177
208
 
178
- # Mark the field as globally enabled
179
- def enable!
180
- @enabled = true
181
- end
182
-
183
- # Mark the field as globally disabled
184
- def disable!
185
- @enabled = false
186
- end
187
-
188
- # Return the description of the argument
189
- def description
190
- @desc
191
- end
192
-
193
- # Checks if a description was provided
194
- def description?
195
- defined?(@desc) && !!@desc
209
+ # Override to add the kind
210
+ def description(namespace = nil, *)
211
+ super(namespace, :field)
196
212
  end
197
213
 
198
214
  # Check if the field is an internal one
@@ -241,22 +257,12 @@ module Rails # :nodoc:
241
257
  def validate!(*)
242
258
  super if defined? super
243
259
 
244
- raise NameError, <<~MSG.squish if gql_name.start_with?('__') && !internal?
260
+ raise NameError, (+<<~MSG).squish if gql_name.start_with?('__') && !internal?
245
261
  The name "#{gql_name}" is invalid. Only internal fields from the
246
262
  spec can have a name starting with "__".
247
263
  MSG
248
264
  end
249
265
 
250
- # Update the null value
251
- def required!
252
- @null = false
253
- end
254
-
255
- # Update the nullable value
256
- def required_items!
257
- @nullable = false
258
- end
259
-
260
266
  # Create a proxy of the current field
261
267
  def to_proxy(*args, **xargs, &block)
262
268
  proxy = self.class.allocate
@@ -266,8 +272,16 @@ module Rails # :nodoc:
266
272
  proxy
267
273
  end
268
274
 
269
- def inspect # :nodoc:
270
- <<~INSPECT.squish + '>'
275
+ # Check if the other field is equivalent
276
+ def =~(other)
277
+ other.is_a?(GraphQL::Field) &&
278
+ other.array? == array? &&
279
+ (other.null? == null? || other.null? && !null?) &&
280
+ (other.nullable? == nullable? || other.nullable? && !nullable?)
281
+ end
282
+
283
+ def inspect
284
+ (+<<~INFO).squish << '>'
271
285
  #<#{self.class.name}
272
286
  #{inspect_owner}
273
287
  #{inspect_source}
@@ -275,7 +289,7 @@ module Rails # :nodoc:
275
289
  #{gql_name}#{inspect_arguments}#{inspect_type}
276
290
  #{inspect_default_value}
277
291
  #{inspect_directives}
278
- INSPECT
292
+ INFO
279
293
  end
280
294
 
281
295
  protected
@@ -304,9 +318,9 @@ module Rails # :nodoc:
304
318
  end
305
319
  end
306
320
 
307
- # Helper method to inspect the directives
308
- def inspect_directives
309
- all_directives.map(&:inspect)
321
+ # Check if the field was defined as an alternative class
322
+ def from_alternative?
323
+ proxied_owner.is_a?(Module) && proxied_owner <= Alternative::Query
310
324
  end
311
325
 
312
326
  # Show the name of the owner of the object for inspection
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'globalid'
4
+
5
+ module Rails
6
+ module GraphQL
7
+ # = GraphQL Global ID
8
+ #
9
+ # GraphQL implementation of the Global ID that adds extended support to how
10
+ # things are located and stored. Mostly used for caching and custom access
11
+ # to the tree and request process.
12
+ #
13
+ # TODO: Implement signed operations
14
+ class GlobalID < ::GlobalID
15
+ SERIALIZER_KEY = "_gql_globalid"
16
+
17
+ # This adds support to ActiveJob serialization, which can be used to pass
18
+ # GraphQL objects to jobs and also deserialize things for subscriptions
19
+ class Serializer
20
+ include Singleton
21
+
22
+ class << self
23
+ delegate :serialize?, :serialize, :deserialize, to: :instance
24
+ end
25
+
26
+ # Determines if an argument should be serialized by this serializer.
27
+ def serialize?(argument)
28
+ argument.is_a?(Helpers::WithGlobalID) || argument.class.is_a?(Helpers::WithGlobalID)
29
+ end
30
+
31
+ # Serializes an argument to a JSON primitive type.
32
+ def serialize(argument)
33
+ { GlobalID::SERIALIZER_KEY => argument.to_global_id.to_s }
34
+ end
35
+
36
+ # Deserializes an argument from a JSON primitive type.
37
+ def deserialize(argument)
38
+ GlobalID.find argument[GlobalID::SERIALIZER_KEY]
39
+ end
40
+
41
+ private
42
+ # The class of the object that will be serialized.
43
+ def klass
44
+ GlobalID
45
+ end
46
+ end
47
+
48
+ class << self
49
+ undef_method :app, :app=
50
+
51
+ # Create a new GraphQL Global identifier
52
+ def create(object, options = nil)
53
+ scope = options&.delete(:scope) || scope_of(object)
54
+ new(URI::GQL.create(object, scope, options), options)
55
+ end
56
+
57
+ # Find the scope on which the object is applied to
58
+ def scope_of(object)
59
+ object.try(:schema_type) if object.gid_base_class.is_a?(Helpers::WithSchemaFields)
60
+ end
61
+ end
62
+
63
+ undef_method :app, :model_name, :model_id
64
+ delegate :namespace, :class_name, :scope, :name, :instantiate?, to: :uri
65
+
66
+ def initialize(gid, options = {})
67
+ @uri = gid.is_a?(URI::GQL) ? gid : URI::GQL.parse(gid)
68
+ end
69
+
70
+ def find(options = {})
71
+ base_class.try(:find_by_gid, self)
72
+ end
73
+
74
+ def base_class
75
+ ::GraphQL.const_get(class_name, false)
76
+ end
77
+
78
+ def ==(other)
79
+ other.is_a?(GlobalID) && @uri == other.uri
80
+ end
81
+
82
+ alias eql? ==
83
+ end
84
+ end
85
+ 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
  # This is an extra magic on top of the delegator class from the standard
7
7
  # lib that allows fetching a specific property of the delegated object
8
8
  class AttributeDelegator < ActiveSupport::ProxyObject
@@ -14,11 +14,11 @@ module Rails # :nodoc:
14
14
 
15
15
  private
16
16
 
17
- def respond_to_missing?(method_name, include_private = false) # :nodoc:
17
+ def respond_to_missing?(method_name, include_private = false)
18
18
  __getobj__.respond_to?(method_name, include_private) || super
19
19
  end
20
20
 
21
- def method_missing(method_name, *args, **xargs, &block) # :nodoc:
21
+ def method_missing(method_name, *args, **xargs, &block)
22
22
  return super unless __getobj__.respond_to?(method_name)
23
23
  __getobj__.public_send(method_name, *args, **xargs, &block)
24
24
  end
@@ -0,0 +1,50 @@
1
+ module Rails
2
+ module GraphQL
3
+ module Helpers
4
+ # A inherited collection of arrays that can be unique when it is a set
5
+ class InheritedCollection::Array < InheritedCollection::Base
6
+ alias size count
7
+
8
+ # Provide similar functionality of any? but returns the object instead
9
+ def find(value = nil, &block)
10
+ block ||= !value.is_a?(Module) ? value.method(:==) : ->(val) { val.class <= value }
11
+ reverse_each { |item| return item if block.call(item) }
12
+ nil
13
+ end
14
+
15
+ # Check if a given +value+ is included in any of the definitions
16
+ def include?(value)
17
+ each_definition.any? { |definition| definition.include?(value) }
18
+ end
19
+
20
+ # If any elements appears, the each block will run and return true
21
+ def empty?
22
+ lazy.each { return true }
23
+ false
24
+ end
25
+
26
+ # The normal each is the reverse each of the definitions
27
+ def each(&block)
28
+ lazy.reverse_each(&block)
29
+ end
30
+
31
+ # The reverse each is the normal each of the definitions
32
+ def reverse_each(&block)
33
+ block.nil? ? lazy : lazy.each(&block)
34
+ end
35
+
36
+ # Overrides the lazy operator
37
+ def lazy
38
+ (@type == :set) ? super.uniq : super
39
+ end
40
+
41
+ # Allow concatenating objects
42
+ def +(other)
43
+ result = to_a
44
+ result = result.to_set if @type == :set
45
+ result + other
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,43 @@
1
+ module Rails
2
+ module GraphQL
3
+ module Helpers
4
+ # The base class for inherited collections. It helps softly dealing with
5
+ # values defined in multiple class instance variables and look up the tree
6
+ # to make it possible to iterate over combined result
7
+ class InheritedCollection::Base
8
+ include Enumerable
9
+
10
+ # Just a little helper to initialize the iterator form a given +source+
11
+ def self.handle(source, ivar, type)
12
+ klass = (type == :array || type == :set) ? :Array : :Hash
13
+ InheritedCollection.const_get(klass).new(source, ivar, type)
14
+ end
15
+
16
+ def initialize(source, ivar, type)
17
+ @source = source
18
+ @ivar = ivar
19
+ @type = type
20
+ end
21
+
22
+ # Overrides the lazy enumerator because each instance variable defined
23
+ # and found by the +each_definition+ will be iterated over lazily
24
+ def lazy
25
+ Enumerator::Lazy.new(each_definition) { |y, d| d.each(&y) }
26
+ end
27
+
28
+ protected
29
+
30
+ def each_definition
31
+ Enumerator.new do |yielder|
32
+ current = @source
33
+ until current === Object
34
+ yielder << current.instance_variable_get(@ivar) \
35
+ if current.instance_variable_defined?(@ivar)
36
+ current = current.superclass
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,87 @@
1
+ module Rails
2
+ module GraphQL
3
+ module Helpers
4
+ # A inherited collection of Hash that can contain simple values, arrays,
5
+ # or sets
6
+ class InheritedCollection::Hash < InheritedCollection::Base
7
+ delegate :transform_values, :transform_keys, to: :to_hash
8
+
9
+ # Simply go over each definition and check for the given key
10
+ def key?(value)
11
+ each_definition.any? { |definition| definition.key?(value) }
12
+ end
13
+
14
+ # Collect all the keys of all the definitions
15
+ def keys
16
+ each_definition.reverse_each.flat_map(&:keys).uniq
17
+ end
18
+
19
+ # Go over each key and value
20
+ def each
21
+ Enumerator::Lazy.new(keys) do |yielder, key|
22
+ val = self[key]
23
+ yield(key, val) if block_given?
24
+ yielder.yield(key, val)
25
+ end
26
+ end
27
+
28
+ # Go over each value exclusively
29
+ def each_value(&block)
30
+ Enumerator::Lazy.new(keys) do |yielder, key|
31
+ val = self[key]
32
+ yield(val) if block_given?
33
+ yielder.yield(val)
34
+ end
35
+ end
36
+
37
+ # Go over each key exclusively
38
+ def each_key(&block)
39
+ keys.each(&block)
40
+ end
41
+
42
+ # Get all the values by lazy iterating over all the keys
43
+ def values
44
+ keys.lazy.map(&method(:[]))
45
+ end
46
+
47
+ # Basically allow this lazy operator to be merged with other hashes
48
+ def to_hash
49
+ each.to_h
50
+ end
51
+
52
+ # A simple way to get the result of one single key
53
+ def [](key)
54
+ lazy[key]
55
+ end
56
+
57
+ # Build a lazy hash
58
+ def lazy
59
+ @table ||= Hash.new(&method(_combine? ? :_combined_hash : :_simple_hash))
60
+ end
61
+
62
+ private
63
+
64
+ # Check if it has to combine the values
65
+ def _combine?
66
+ @type != :hash
67
+ end
68
+
69
+ # Builds a values for a combined hash
70
+ def _combined_hash(hash, key)
71
+ hash[key] = each_definition.reverse_each.inject(nil) do |result, definition|
72
+ next result unless definition.key?(key)
73
+ next definition[key] if result.nil?
74
+ result + definition[key]
75
+ end
76
+ end
77
+
78
+ # Builds a values for a simple hash
79
+ def _simple_hash(hash, key)
80
+ hash[key] = each_definition.reverse_each do |definition|
81
+ break definition[key] if definition.key?(key)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -1,15 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Rails # :nodoc:
4
- module GraphQL # :nodoc:
5
- module Helpers # :nodoc:
6
- module InheritedCollection # :nodoc:
3
+ module Rails
4
+ module GraphQL
5
+ module Helpers
6
+ # Helper module that allow classes to have specific type of attributes
7
+ # that are corretly delt when it is inherited by another class. It keeps
8
+ # track of its own value and allow access to all values of the property
9
+ # in the tree,
10
+ #
11
+ # TODO: Rewrite this!
12
+ module InheritedCollection
13
+ # All possible types of inheritable values
7
14
  DEFAULT_TYPES = {
8
15
  array: '[]',
9
16
  set: 'Set.new',
10
17
  hash: '{}',
11
- hash_array: 'Hash.new { |h, k| h[k] = [] }',
12
- hash_set: 'Hash.new { |h, k| h[k] = Set.new }',
18
+ hash_array: '::Hash.new { |h, k| h[k] = [] }',
19
+ hash_set: '::Hash.new { |h, k| h[k] = Set.new }',
13
20
  }.freeze
14
21
 
15
22
  # Declare a class-level attribute whose value is both isolated and also
@@ -60,20 +67,19 @@ module Rails # :nodoc:
60
67
  type: :set
61
68
  )
62
69
  attrs.each do |name|
63
- module_eval(<<~RUBY, __FILE__, __LINE__ + 1)
64
- def self.all_#{name}
65
- ::Rails::GraphQL::Helpers::AttributeDelegator.new do
66
- fetch_inherited_#{type}('@#{name}')
67
- end
70
+ instance_eval(<<~RUBY, __FILE__, __LINE__ + 1)
71
+ def all_#{name}
72
+ return superclass.try(:all_#{name}) unless defined?(@#{name})
73
+ InheritedCollection::Base.handle(self, :@#{name}, :#{type})
68
74
  end
69
75
 
70
- def self.#{name}
76
+ def #{name}
71
77
  @#{name} ||= #{DEFAULT_TYPES[type]}
72
78
  end
73
79
  RUBY
74
80
 
75
- module_eval(<<~RUBY, __FILE__, __LINE__ + 1) if instance_predicate
76
- def self.#{name}?
81
+ instance_eval(<<~RUBY, __FILE__, __LINE__ + 1) if instance_predicate
82
+ def #{name}?
77
83
  (defined?(@#{name}) && @#{name}.present?) || superclass.try(:#{name}?)
78
84
  end
79
85
  RUBY
@@ -84,69 +90,12 @@ module Rails # :nodoc:
84
90
  end
85
91
  end
86
92
  end
87
-
88
- protected
89
-
90
- # Combine an inherited list of arrays
91
- def fetch_inherited_array(ivar)
92
- inherited_ancestors.each_with_object([]) do |klass, result|
93
- next result unless klass.instance_variable_defined?(ivar)
94
- val = klass.instance_variable_get(ivar)
95
- result.merge(val) unless val.blank?
96
- end
97
- end
98
-
99
- # Combine an inherited list of set objects
100
- def fetch_inherited_set(ivar)
101
- inherited_ancestors.each_with_object(Set.new) do |klass, result|
102
- next result unless klass.instance_variable_defined?(ivar)
103
- val = klass.instance_variable_get(ivar)
104
- result.merge(val) unless val.blank?
105
- end
106
- end
107
-
108
- # Combine an inherited list of hashes but keeping only the most recent
109
- # value, which means that keys might be replaced
110
- def fetch_inherited_hash(ivar)
111
- inherited_ancestors.each_with_object({}) do |klass, result|
112
- next result unless klass.instance_variable_defined?(ivar)
113
- val = klass.instance_variable_get(ivar)
114
- result.merge!(val) unless val.blank?
115
- end
116
- end
117
-
118
- # Right now we can't use Hash with default proc for equivalency due to
119
- # a bug on Ruby https://bugs.ruby-lang.org/issues/17181
120
-
121
- # Combine an inherited list of hashes, which also will combine arrays,
122
- # ensuring that same key items will be combined
123
- def fetch_inherited_hash_array(ivar)
124
- inherited_ancestors.inject({}) do |result, klass|
125
- next result unless klass.instance_variable_defined?(ivar)
126
- val = klass.instance_variable_get(ivar)
127
- Helpers.merge_hash_array(result, val)
128
- end
129
- end
130
-
131
- # Combine an inherited list of hashes, which also will combine arrays,
132
- # ensuring that same key items will be combined
133
- def fetch_inherited_hash_set(ivar)
134
- inherited_ancestors.inject({}) do |result, klass|
135
- next result unless klass.instance_variable_defined?(ivar)
136
- val = klass.instance_variable_get(ivar)
137
- Helpers.merge_hash_array(result, val)
138
- end
139
- end
140
-
141
- private
142
-
143
- # Return a list of all the ancestor classes up until object
144
- def inherited_ancestors
145
- [self].tap do |list|
146
- list.unshift(list.first.superclass) until list.first.superclass === Object
147
- end
148
- end
149
93
  end
150
94
  end
151
95
  end
152
96
  end
97
+
98
+ require_relative 'inherited_collection/base'
99
+
100
+ require_relative 'inherited_collection/array'
101
+ require_relative 'inherited_collection/hash'
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails
4
+ module GraphQL
5
+ module Helpers
6
+ # This marks an object as instantiable during a requesting, which means it
7
+ # will be associated with an event and most of it's information comes from
8
+ # the running event.
9
+ module Instantiable
10
+ delegate_missing_to :event
11
+ attr_reader :event
12
+ end
13
+ end
14
+ end
15
+ end