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
- class Type # :nodoc:
3
+ module Rails
4
+ module GraphQL
5
+ class Type
6
6
  # Bigint basically removes the limit of the value, but it serializes as
7
7
  # a string so it won't go against the spec
8
8
  class Enum::DirectiveLocationEnum < Enum
@@ -12,17 +12,17 @@ module Rails # :nodoc:
12
12
 
13
13
  desc 'The valid locations that a directive may be placed.'
14
14
 
15
- %w[QUERY MUTATION SUBSCRIPTION FIELD FRAGMENT_DEFINITION
16
- FRAGMENT_SPREAD INLINE_FRAGMENT].each do |value|
17
- desc = value.downcase.tr('_', ' ')
18
- add(value, desc: "Mark as a executable directive usable on #{desc} objects.")
15
+ Directive::EXECUTION_LOCATIONS.each do |value|
16
+ name = value.to_s.upcase
17
+ desc = value.to_s.tr('_', ' ')
18
+ add(name, desc: "Mark as a executable directive usable on #{desc} objects.")
19
19
  end
20
20
 
21
- %w[SCHEMA SCALAR OBJECT FIELD_DEFINITION ARGUMENT_DEFINITION INTERFACE UNION
22
- ENUM ENUM_VALUE INPUT_OBJECT INPUT_FIELD_DEFINITION].each do |value|
23
- desc = value.downcase.tr('_', ' ')
21
+ Directive::DEFINITION_LOCATIONS.each do |value|
22
+ name = value.to_s.upcase
23
+ desc = value.to_s.tr('_', ' ')
24
24
  desc = "Mark as a type system directive usable on #{desc} definitions."
25
- add(value, desc: desc.gsub(/definition definitions\.$/, 'definitions.'))
25
+ add(name, desc: desc.sub('definition definitions.', 'definitions.'))
26
26
  end
27
27
  end
28
28
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Rails # :nodoc:
4
- module GraphQL # :nodoc:
5
- class Type # :nodoc:
3
+ module Rails
4
+ module GraphQL
5
+ class Type
6
6
  # Bigint basically removes the limit of the value, but it serializes as
7
7
  # a string so it won't go against the spec
8
8
  class Enum::TypeKindEnum < Enum
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Rails # :nodoc:
4
- module GraphQL # :nodoc:
5
- class Type # :nodoc:
3
+ module Rails
4
+ module GraphQL
5
+ class Type
6
6
  # = GraphQL EnumType
7
7
  #
8
8
  # Enum types, like scalar types, also represent leaf values in a GraphQL
@@ -13,10 +13,8 @@ module Rails # :nodoc:
13
13
 
14
14
  setup! leaf: true, input: true, output: true
15
15
 
16
- eager_autoload do
17
- autoload :DirectiveLocationEnum
18
- autoload :TypeKindEnum
19
- end
16
+ autoload :DirectiveLocationEnum
17
+ autoload :TypeKindEnum
20
18
 
21
19
  # Define the methods for accessing the values attribute
22
20
  inherited_collection :values
@@ -25,7 +23,7 @@ module Rails # :nodoc:
25
23
  inherited_collection :value_description, type: :hash
26
24
 
27
25
  # Define the methods for accessing the directives of each enum value
28
- inherited_collection :value_directives, type: :hash
26
+ inherited_collection :value_directives, type: :hash_set
29
27
 
30
28
  class << self
31
29
  # Mark the enum as indexed, allowing values being set by number
@@ -40,7 +38,8 @@ module Rails # :nodoc:
40
38
 
41
39
  # Check if a given value is a valid non-deserialized input
42
40
  def valid_input?(value)
43
- value.is_a?(String) && all_values.include?(value)
41
+ (valid_token?(value, :enum) && all_values.include?(value.to_s)) ||
42
+ (value.is_a?(String) && all_values.include?(value))
44
43
  end
45
44
 
46
45
  # Check if a given value is a valid non-serialized output
@@ -63,7 +62,7 @@ module Rails # :nodoc:
63
62
 
64
63
  # Turn a user input of this given type into an ruby object
65
64
  def deserialize(value)
66
- new(value) if valid_input?(value)
65
+ new(value.is_a?(::GQLParser::Token) ? value.to_s : value) if valid_input?(value)
67
66
  end
68
67
 
69
68
  # Use the instance as decorator
@@ -84,17 +83,18 @@ module Rails # :nodoc:
84
83
  # See {DeprecatedDirective}[rdoc-ref:Rails::GraphQL::Directive::DeprecatedDirective]
85
84
  # (defaults to false).
86
85
  def add(value, desc: nil, directives: nil, deprecated: false)
87
- raise ArgumentError, <<~MSG.squish unless value.is_a?(String) && value.present?
86
+ value = value&.to_s
87
+ raise ArgumentError, (+<<~MSG).squish unless value.is_a?(String) && value.present?
88
88
  The "#{value}" is invalid.
89
89
  MSG
90
90
 
91
91
  value = value.upcase
92
- raise ArgumentError, <<~MSG.squish if all_values.include?(value)
92
+ raise ArgumentError, (+<<~MSG).squish if all_values&.include?(value)
93
93
  The "#{value}" is already defined for #{gql_name} enum.
94
94
  MSG
95
95
 
96
- directives = Array.wrap(directives)
97
- directives << deprecated_klass.new(
96
+ directives = ::Array.wrap(directives)
97
+ directives << Directive::DeprecatedDirective.new(
98
98
  reason: (deprecated.is_a?(String) ? deprecated : nil),
99
99
  ) if deprecated.present?
100
100
 
@@ -105,47 +105,38 @@ module Rails # :nodoc:
105
105
 
106
106
  values << value
107
107
  value_description[value] = desc unless desc.nil?
108
- value_directives[value] = directives
108
+ value_directives[value] = directives if directives
109
109
  end
110
110
 
111
111
  # Check if a given +value+ is using a +directive+
112
112
  def value_using?(value, directive)
113
- raise ArgumentError, <<~MSG.squish unless directive < GraphQL::Directive
113
+ raise ArgumentError, (+<<~MSG).squish unless directive < GraphQL::Directive
114
114
  The provided #{item_or_symbol.inspect} is not a valid directive.
115
115
  MSG
116
116
 
117
- !!value_directives[as_json(value)]&.any? { |item| item.is_a?(directive) }
117
+ all_value_directives.try(:[], as_json(value))&.any?(directive) || false
118
118
  end
119
119
 
120
120
  # Build a hash with deprecated values and their respective reason for
121
121
  # logging and introspection purposes
122
122
  def all_deprecated_values
123
123
  @all_deprecated_values ||= begin
124
- all_value_directives.to_a.inject({}) do |list, (value, dirs)|
125
- obj = dirs.find { |dir| dir.is_a?(deprecated_klass) }
126
- obj ? list.merge(value => obj.args.reason) : list
124
+ all_value_directives&.each&.with_object({}) do |(value, dirs), hash|
125
+ obj = dirs&.find { |dir| dir.is_a?(Directive::DeprecatedDirective) }
126
+ hash[value] = obj.args.reason || true unless obj.nil?
127
127
  end
128
128
  end.freeze
129
129
  end
130
130
 
131
- # This returns the field directives and all value directives
132
- def all_directives
133
- all_value_directives.each_value.reduce(:+)
134
- end
135
-
136
- def inspect # :nodoc:
137
- <<~INFO.squish + '>'
131
+ def inspect
132
+ return super if self.eql?(Type::Enum)
133
+ (+<<~INFO).squish << '>'
138
134
  #<GraphQL::Enum #{gql_name}
139
135
  (#{all_values.size})
140
136
  {#{all_values.to_a.join(' | ')}}
137
+ #{inspect_directives}
141
138
  INFO
142
139
  end
143
-
144
- private
145
-
146
- def deprecated_klass
147
- Directive::DeprecatedDirective
148
- end
149
140
  end
150
141
 
151
142
  attr_reader :value
@@ -163,7 +154,7 @@ module Rails # :nodoc:
163
154
 
164
155
  # Allow finding the indexed position of the value
165
156
  def to_i
166
- self.class.all_values.find_index(@value)
157
+ values.find_index(@value)
167
158
  end
168
159
 
169
160
  # Checks if the current value is valid
@@ -173,33 +164,28 @@ module Rails # :nodoc:
173
164
 
174
165
  # Gets all the description of the current value
175
166
  def description
176
- @description ||= @value && self.class.all_value_description[@value]
167
+ return unless @value
168
+ @description ||= all_value_description.try(:[], @value)
177
169
  end
178
170
 
179
171
  # Gets all the directives associated with the current value
180
172
  def directives
181
- @directives ||= @value && self.class.all_value_directives[@value]
173
+ return unless @value
174
+ @directives ||= all_value_directives.try(:[], @value)
182
175
  end
183
176
 
184
177
  # Checks if the current value is marked as deprecated
185
178
  def deprecated?
186
- self.class.all_deprecated_values.include?(@value)
179
+ directives&.any?(Directive::DeprecatedDirective) || false
187
180
  end
188
181
 
189
182
  # Return the deprecated reason
190
183
  def deprecated_reason
191
- deprecated_directive&.args&.reason
184
+ return unless deprecated?
185
+ directives.find do |dir|
186
+ dir.is_a?(Directive::DeprecatedDirective)
187
+ end.args.reason
192
188
  end
193
-
194
- private
195
-
196
- # Find and store the directive that marked the current value as
197
- # deprecated
198
- def deprecated_directive
199
- @deprecated_directive ||= directives.find do |dir|
200
- dir.is_a?(Directive::DeprecatedDirective)
201
- end
202
- end
203
189
  end
204
190
  end
205
191
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Rails # :nodoc:
4
- module GraphQL # :nodoc:
5
- class Type # :nodoc:
3
+ module Rails
4
+ module GraphQL
5
+ class Type
6
6
  # = GraphQL InputType
7
7
  #
8
8
  # Input defines a set of input fields; the input fields are either
@@ -34,49 +34,82 @@ module Rails # :nodoc:
34
34
  @gql_name = result
35
35
  end
36
36
 
37
+ # Transforms the given value to its representation in a JSON string
38
+ def as_json(value)
39
+ parse_arguments(value, using: :as_json, key: :gql_name)
40
+ end
41
+
42
+ # Transforms the given value to its representation in a Hash object
43
+ def to_json(value)
44
+ as_json(value).to_json
45
+ end
46
+
37
47
  # Check if a given value is a valid non-deserialized input
38
48
  def valid_input?(value)
49
+ value = GraphQL.config.literal_input_parser.call(value) \
50
+ if valid_token?(value, :hash)
51
+
39
52
  value = value.to_h if value.respond_to?(:to_h)
40
- return false unless value.is_a?(Hash)
53
+ return false unless value.is_a?(::Hash)
41
54
 
42
55
  fields = enabled_fields
43
56
  value = value.transform_keys { |key| key.to_s.camelize(:lower) }
44
57
  value = build_defaults.merge(value)
45
58
 
46
- return false unless value.size.eql?(fields.size)
59
+ return false unless value.size.eql?(fields&.count || 0)
47
60
 
48
- fields.all? { |item| item.valid_input?(value[item.gql_name]) }
61
+ fields&.all? { |item| item.valid_input?(value[item.gql_name]) }
49
62
  end
50
63
 
51
- # Turn the given value into an isntance of the input object
52
- def deserialize(value)
53
- value = value.to_h if value.respond_to?(:to_h)
54
- value = {} unless value.is_a?(Hash)
55
- value = enabled_fields.map do |field|
56
- next unless value.key?(field.gql_name) || value.key?(field.name)
57
- [field.name, field.deserialize(value[field.gql_name] || value[field.name])]
58
- end.compact.to_h
59
-
60
- new(OpenStruct.new(value))
64
+ # Turn the given value into an instance of the input object
65
+ def deserialize(value = nil, **value_as_hash)
66
+ value = value_as_hash if value.nil?
67
+ new(OpenStruct.new(parse_arguments(value, using: :deserialize)))
61
68
  end
62
69
 
70
+ alias build deserialize
71
+
63
72
  # Build a hash with the default values for each of the given fields
64
73
  def build_defaults
65
- enabled_fields.map { |field| [field.gql_name, field.default] }.to_h
74
+ return {} unless fields?
75
+ enabled_fields.each.with_object({}) do |field, hash|
76
+ hash[field.gql_name] = field.default
77
+ end
66
78
  end
67
79
 
68
- def inspect # :nodoc:
69
- args = fields.each_value.map(&:inspect)
70
- args = args.presence && "(#{args.join(', ')})"
71
- "#<GraphQL::Input #{gql_name}#{args}>"
80
+ def inspect
81
+ return super if self.eql?(Type::Input)
82
+ args = fields.values.map(&:inspect)
83
+ args = args.presence && +"(#{args.join(', ')})"
84
+
85
+ directives = inspect_directives
86
+ directives.prepend(' ') if directives.present?
87
+ +"#<GraphQL::Input #{gql_name}#{args}#{directives}>"
72
88
  end
89
+
90
+ private
91
+
92
+ def parse_arguments(value, using:, key: :name)
93
+ value = GraphQL.config.literal_input_parser.call(value) \
94
+ if valid_token?(value, :hash)
95
+
96
+ value = value.to_h if value.respond_to?(:to_h)
97
+ value = {} unless value.is_a?(::Hash)
98
+ value = value.stringify_keys
99
+
100
+ enabled_fields.each.with_object({}) do |field, hash|
101
+ next unless value.key?(field.gql_name) || value.key?(field.name.to_s)
102
+ result = value[field.gql_name] || value[field.name.to_s]
103
+ hash[field.public_send(key)] = field.public_send(using, result)
104
+ end.compact
105
+ end
73
106
  end
74
107
 
75
108
  attr_reader :args
76
109
  attr_writer :resource
77
110
 
78
111
  delegate :fields, to: :class
79
- delegate :[], to: :args
112
+ delegate :to_h, :[], to: :args
80
113
 
81
114
  delegate_missing_to :resource
82
115
 
@@ -102,6 +135,18 @@ module Rails # :nodoc:
102
135
  parametrize(self)
103
136
  end
104
137
 
138
+ # Corretly turn all the arguments into their +as_json+ version and
139
+ # return a hash of them
140
+ def args_as_json
141
+ self.class.as_json(@args.to_h)
142
+ end
143
+
144
+ # Corretly turn all the arguments into their +to_json+ version and
145
+ # return a hash of them
146
+ def args_to_json
147
+ self.class.to_json(@args.to_h)
148
+ end
149
+
105
150
  # Checks if all the values provided to the input instance are valid
106
151
  def validate!(*)
107
152
  errors = []
@@ -112,11 +157,17 @@ module Rails # :nodoc:
112
157
  end
113
158
 
114
159
  return if errors.empty?
115
- raise InvalidValueError, <<~MSG.squish
160
+ raise InvalidValueError, (+<<~MSG).squish
116
161
  Invalid value provided to #{gql_name} field: #{errors.to_sentence}.
117
162
  MSG
118
163
  end
119
164
 
165
+ %i[to_global_id to_gid to_gid_param].each do |method_name|
166
+ define_method(method_name) do
167
+ self.class.public_send(method_name, args_as_json.compact)
168
+ end
169
+ end
170
+
120
171
  private
121
172
 
122
173
  # Make sure to turn inputs into params
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Rails # :nodoc:
4
- module GraphQL # :nodoc:
5
- class Type # :nodoc:
3
+ module Rails
4
+ module GraphQL
5
+ class Type
6
6
  # = GraphQL InterfaceType
7
7
  #
8
8
  # Interfaces represent a list of named fields and their types.
@@ -16,30 +16,16 @@ module Rails # :nodoc:
16
16
  extend Helpers::WithAssignment
17
17
  extend Helpers::WithFields
18
18
 
19
+ include Helpers::Instantiable
20
+
19
21
  setup! output: true
20
22
 
21
23
  self.field_type = Field::OutputField
22
24
 
23
- # The purpose of instantiating an interface is to have access to its
24
- # public methods. It then runs from the strategy perspective, pointing
25
- # out any other methods to the manually set event
26
- delegate_missing_to :event
27
- attr_reader :event
25
+ # Define the methods for accessing the types attribute
26
+ inherited_collection :types, instance_reader: false
28
27
 
29
28
  class << self
30
- # TODO: Use inherited attribute for types
31
-
32
- # Stores the list of types associated with the interface so it can
33
- # be used during the execution step to find the right object type
34
- def types
35
- @types ||= Set.new
36
- end
37
-
38
- # Get the list of all inherited-aware associated types
39
- def all_types
40
- (superclass.try(:all_types) || Set.new) + (defined?(@types) ? @types : Set.new)
41
- end
42
-
43
29
  # Check if the other type is equivalent, by checking if the other is
44
30
  # an object and the object implements this interface
45
31
  def =~(other)
@@ -53,7 +39,7 @@ module Rails # :nodoc:
53
39
  fields.each do |name, field|
54
40
  defined = object.field?(name)
55
41
  invalid = defined && object.fields[name] !~ field
56
- raise ArgumentError, <<~MSG.squish if invalid
42
+ raise ArgumentError, (+<<~MSG).squish if invalid
57
43
  The "#{object.gql_name}" object already has a "#{field.gql_name}" field and it
58
44
  is not equivalent to the one defined on the "#{gql_name}" interface.
59
45
  MSG
@@ -64,10 +50,14 @@ module Rails # :nodoc:
64
50
  types << object
65
51
  end
66
52
 
67
- def inspect # :nodoc:
68
- fields = @fields.values.map(&:inspect)
69
- fields = fields.presence && " {#{fields.join(', ')}}"
70
- "#<GraphQL::Interface #{gql_name}#{fields}>"
53
+ def inspect
54
+ return super if self.eql?(Type::Interface)
55
+ fields = @fields.values.map(&:inspect) if defined?(@fields)
56
+ fields = fields.presence && +" {#{fields.join(', ')}}"
57
+
58
+ directives = inspect_directives
59
+ directives.prepend(' ') if directives.present?
60
+ +"#<GraphQL::Interface #{gql_name}#{fields}#{directives}>"
71
61
  end
72
62
 
73
63
  # Check if the given object is properly implementing this interface
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Rails # :nodoc:
4
- module GraphQL # :nodoc:
5
- class Type # :nodoc:
3
+ module Rails
4
+ module GraphQL
5
+ class Type
6
6
  # The introspection object for directives
7
7
  class Object::DirectiveObject < Object
8
8
  self.assigned_to = 'Rails::GraphQL::Directive'
@@ -14,7 +14,7 @@ module Rails # :nodoc:
14
14
  Directives provide a way to describe alternate runtime execution
15
15
  and type validation behavior in a GraphQL document.
16
16
 
17
- In some cases, you need to provide options to alter GraphQLs execution
17
+ In some cases, you need to provide options to alter GraphQL's execution
18
18
  behavior in ways field arguments will not suffice, such as conditionally
19
19
  including or skipping a field. Directives provide this by describing
20
20
  additional information to the executor.
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Rails # :nodoc:
4
- module GraphQL # :nodoc:
5
- class Type # :nodoc:
3
+ module Rails
4
+ module GraphQL
5
+ class Type
6
6
  # The introspection object for an enum value
7
7
  class Object::EnumValueObject < Object
8
8
  self.spec_object = true
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Rails # :nodoc:
4
- module GraphQL # :nodoc:
5
- class Type # :nodoc:
3
+ module Rails
4
+ module GraphQL
5
+ class Type
6
6
  # The introspection object for a field on objects and interfaces
7
7
  class Object::FieldObject < Object
8
8
  self.assigned_to = 'Rails::GraphQL::Field'
@@ -25,6 +25,14 @@ module Rails # :nodoc:
25
25
  field :is_deprecated, :boolean, null: false, method_name: :deprecated?
26
26
  field :deprecation_reason, :string
27
27
 
28
+ def description
29
+ if current.method(:description).arity == 0
30
+ current.description
31
+ else
32
+ current.description(schema.namespace)
33
+ end
34
+ end
35
+
28
36
  def build_type
29
37
  result = current.type_klass
30
38
 
@@ -38,16 +46,26 @@ module Rails # :nodoc:
38
46
  end
39
47
 
40
48
  def args
41
- all_arguments.values
49
+ all_arguments&.values || EMPTY_ARRAY
42
50
  end
43
51
 
44
52
  def deprecated?
45
- current.using?(deprecated_directive)
53
+ !deprecated_instance.nil?
46
54
  end
47
55
 
48
56
  def deprecation_reason
49
- current.all_directives.find { |item| item.is_a?(deprecated_directive) }&.args&.reason
57
+ deprecated_instance&.args&.reason
50
58
  end
59
+
60
+ private
61
+
62
+ def deprecated_instance
63
+ current.all_directives&.reverse_each do |item|
64
+ return item if item.class <= deprecated_directive
65
+ end
66
+
67
+ nil
68
+ end
51
69
  end
52
70
  end
53
71
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Rails # :nodoc:
4
- module GraphQL # :nodoc:
5
- class Type # :nodoc:
3
+ module Rails
4
+ module GraphQL
5
+ class Type
6
6
  # The introspection object for a input object
7
7
  class Object::InputValueObject < Object
8
8
  self.assigned_to = 'Rails::GraphQL::Field::InputField'
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Rails # :nodoc:
4
- module GraphQL # :nodoc:
5
- class Type # :nodoc:
3
+ module Rails
4
+ module GraphQL
5
+ class Type
6
6
  # The introspection object for a schema object
7
7
  class Object::SchemaObject < Object
8
8
  self.assigned_to = 'Rails::GraphQL::Schema'
@@ -11,8 +11,8 @@ module Rails # :nodoc:
11
11
  rename! '__Schema'
12
12
 
13
13
  desc <<~DESC
14
- A GraphQL services collective type system capabilities are referred
15
- to as that services "schema". A schema is defined in terms of the
14
+ A GraphQL service's collective type system capabilities are referred
15
+ to as that service's "schema". A schema is defined in terms of the
16
16
  types and directives it supports as well as the root operation types
17
17
  for each kind of operation: query, mutation, and subscription; this
18
18
  determines the place in the type system where those operations begin.
@@ -24,14 +24,11 @@ module Rails # :nodoc:
24
24
  field :subscription_type, '__Type'
25
25
  field :directives, '__Directive', full: true, method_name: :read_directives
26
26
 
27
- # TODO: make it work for lazy enumerator
28
27
  def read_types
29
28
  event.schema.types(base_class: :Type).force
30
29
  end
31
30
 
32
- # TODO: it only works after eager_load!
33
31
  def read_directives
34
- Directive.eager_load!
35
32
  event.schema.types(base_class: :Directive).force
36
33
  end
37
34
  end