rails-graphql 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (266) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +19 -0
  4. data/Rakefile +31 -0
  5. data/ext/depend +3 -0
  6. data/ext/extconf.rb +57 -0
  7. data/ext/graphqlparser/Ast.cpp +346 -0
  8. data/ext/graphqlparser/Ast.h +1214 -0
  9. data/ext/graphqlparser/AstNode.h +36 -0
  10. data/ext/graphqlparser/AstVisitor.h +137 -0
  11. data/ext/graphqlparser/GraphQLParser.cpp +76 -0
  12. data/ext/graphqlparser/GraphQLParser.h +55 -0
  13. data/ext/graphqlparser/JsonVisitor.cpp +161 -0
  14. data/ext/graphqlparser/JsonVisitor.cpp.inc +456 -0
  15. data/ext/graphqlparser/JsonVisitor.h +121 -0
  16. data/ext/graphqlparser/JsonVisitor.h.inc +110 -0
  17. data/ext/graphqlparser/VERSION +1 -0
  18. data/ext/graphqlparser/c/GraphQLAst.cpp +324 -0
  19. data/ext/graphqlparser/c/GraphQLAst.h +180 -0
  20. data/ext/graphqlparser/c/GraphQLAstForEachConcreteType.h +44 -0
  21. data/ext/graphqlparser/c/GraphQLAstNode.cpp +25 -0
  22. data/ext/graphqlparser/c/GraphQLAstNode.h +33 -0
  23. data/ext/graphqlparser/c/GraphQLAstToJSON.cpp +21 -0
  24. data/ext/graphqlparser/c/GraphQLAstToJSON.h +24 -0
  25. data/ext/graphqlparser/c/GraphQLAstVisitor.cpp +55 -0
  26. data/ext/graphqlparser/c/GraphQLAstVisitor.h +53 -0
  27. data/ext/graphqlparser/c/GraphQLParser.cpp +35 -0
  28. data/ext/graphqlparser/c/GraphQLParser.h +54 -0
  29. data/ext/graphqlparser/dump_json_ast.cpp +48 -0
  30. data/ext/graphqlparser/lexer.lpp +324 -0
  31. data/ext/graphqlparser/parser.ypp +693 -0
  32. data/ext/graphqlparser/parsergen/lexer.cpp +2633 -0
  33. data/ext/graphqlparser/parsergen/lexer.h +528 -0
  34. data/ext/graphqlparser/parsergen/location.hh +189 -0
  35. data/ext/graphqlparser/parsergen/parser.tab.cpp +3300 -0
  36. data/ext/graphqlparser/parsergen/parser.tab.hpp +646 -0
  37. data/ext/graphqlparser/parsergen/position.hh +179 -0
  38. data/ext/graphqlparser/parsergen/stack.hh +156 -0
  39. data/ext/graphqlparser/syntaxdefs.h +19 -0
  40. data/ext/libgraphqlparser/AstNode.h +36 -0
  41. data/ext/libgraphqlparser/CMakeLists.txt +148 -0
  42. data/ext/libgraphqlparser/CONTRIBUTING.md +23 -0
  43. data/ext/libgraphqlparser/GraphQLParser.cpp +76 -0
  44. data/ext/libgraphqlparser/GraphQLParser.h +55 -0
  45. data/ext/libgraphqlparser/JsonVisitor.cpp +161 -0
  46. data/ext/libgraphqlparser/JsonVisitor.h +121 -0
  47. data/ext/libgraphqlparser/LICENSE +22 -0
  48. data/ext/libgraphqlparser/README.clang-tidy +7 -0
  49. data/ext/libgraphqlparser/README.md +84 -0
  50. data/ext/libgraphqlparser/ast/ast.ast +203 -0
  51. data/ext/libgraphqlparser/ast/ast.py +61 -0
  52. data/ext/libgraphqlparser/ast/c.py +100 -0
  53. data/ext/libgraphqlparser/ast/c.pyc +0 -0
  54. data/ext/libgraphqlparser/ast/c_impl.py +61 -0
  55. data/ext/libgraphqlparser/ast/c_impl.pyc +0 -0
  56. data/ext/libgraphqlparser/ast/c_visitor_impl.py +39 -0
  57. data/ext/libgraphqlparser/ast/c_visitor_impl.pyc +0 -0
  58. data/ext/libgraphqlparser/ast/casing.py +26 -0
  59. data/ext/libgraphqlparser/ast/casing.pyc +0 -0
  60. data/ext/libgraphqlparser/ast/cxx.py +197 -0
  61. data/ext/libgraphqlparser/ast/cxx.pyc +0 -0
  62. data/ext/libgraphqlparser/ast/cxx_impl.py +61 -0
  63. data/ext/libgraphqlparser/ast/cxx_impl.pyc +0 -0
  64. data/ext/libgraphqlparser/ast/cxx_json_visitor_header.py +42 -0
  65. data/ext/libgraphqlparser/ast/cxx_json_visitor_header.pyc +0 -0
  66. data/ext/libgraphqlparser/ast/cxx_json_visitor_impl.py +80 -0
  67. data/ext/libgraphqlparser/ast/cxx_json_visitor_impl.pyc +0 -0
  68. data/ext/libgraphqlparser/ast/cxx_visitor.py +64 -0
  69. data/ext/libgraphqlparser/ast/cxx_visitor.pyc +0 -0
  70. data/ext/libgraphqlparser/ast/js.py +65 -0
  71. data/ext/libgraphqlparser/ast/license.py +10 -0
  72. data/ext/libgraphqlparser/ast/license.pyc +0 -0
  73. data/ext/libgraphqlparser/c/GraphQLAstNode.cpp +25 -0
  74. data/ext/libgraphqlparser/c/GraphQLAstNode.h +33 -0
  75. data/ext/libgraphqlparser/c/GraphQLAstToJSON.cpp +21 -0
  76. data/ext/libgraphqlparser/c/GraphQLAstToJSON.h +24 -0
  77. data/ext/libgraphqlparser/c/GraphQLAstVisitor.cpp +55 -0
  78. data/ext/libgraphqlparser/c/GraphQLAstVisitor.h +53 -0
  79. data/ext/libgraphqlparser/c/GraphQLParser.cpp +35 -0
  80. data/ext/libgraphqlparser/c/GraphQLParser.h +54 -0
  81. data/ext/libgraphqlparser/clang-tidy-all.sh +3 -0
  82. data/ext/libgraphqlparser/cmake/version.cmake +16 -0
  83. data/ext/libgraphqlparser/dump_json_ast.cpp +48 -0
  84. data/ext/libgraphqlparser/go/README.md +20 -0
  85. data/ext/libgraphqlparser/go/callbacks.go +18 -0
  86. data/ext/libgraphqlparser/go/gotest.go +64 -0
  87. data/ext/libgraphqlparser/lexer.lpp +324 -0
  88. data/ext/libgraphqlparser/libgraphqlparser.pc.in +11 -0
  89. data/ext/libgraphqlparser/parser.ypp +693 -0
  90. data/ext/libgraphqlparser/parsergen/lexer.cpp +2633 -0
  91. data/ext/libgraphqlparser/parsergen/lexer.h +528 -0
  92. data/ext/libgraphqlparser/parsergen/location.hh +189 -0
  93. data/ext/libgraphqlparser/parsergen/parser.tab.cpp +3300 -0
  94. data/ext/libgraphqlparser/parsergen/parser.tab.hpp +646 -0
  95. data/ext/libgraphqlparser/parsergen/position.hh +179 -0
  96. data/ext/libgraphqlparser/parsergen/stack.hh +156 -0
  97. data/ext/libgraphqlparser/python/CMakeLists.txt +14 -0
  98. data/ext/libgraphqlparser/python/README.md +5 -0
  99. data/ext/libgraphqlparser/python/example.py +31 -0
  100. data/ext/libgraphqlparser/syntaxdefs.h +19 -0
  101. data/ext/libgraphqlparser/test/BuildCAPI.c +5 -0
  102. data/ext/libgraphqlparser/test/CMakeLists.txt +25 -0
  103. data/ext/libgraphqlparser/test/JsonVisitorTests.cpp +28 -0
  104. data/ext/libgraphqlparser/test/ParserTests.cpp +352 -0
  105. data/ext/libgraphqlparser/test/kitchen-sink.graphql +59 -0
  106. data/ext/libgraphqlparser/test/kitchen-sink.json +1 -0
  107. data/ext/libgraphqlparser/test/schema-kitchen-sink.graphql +78 -0
  108. data/ext/libgraphqlparser/test/schema-kitchen-sink.json +1 -0
  109. data/ext/libgraphqlparser/test/valgrind.supp +33 -0
  110. data/ext/version.cpp +21 -0
  111. data/lib/generators/graphql/controller_generator.rb +22 -0
  112. data/lib/generators/graphql/schema_generator.rb +22 -0
  113. data/lib/generators/graphql/templates/controller.erb +5 -0
  114. data/lib/generators/graphql/templates/schema.erb +6 -0
  115. data/lib/graphqlparser.so +0 -0
  116. data/lib/rails-graphql.rb +2 -0
  117. data/lib/rails/graphql.rake +1 -0
  118. data/lib/rails/graphql.rb +185 -0
  119. data/lib/rails/graphql/adapters/mysql_adapter.rb +0 -0
  120. data/lib/rails/graphql/adapters/pg_adapter.rb +50 -0
  121. data/lib/rails/graphql/adapters/sqlite_adapter.rb +39 -0
  122. data/lib/rails/graphql/argument.rb +220 -0
  123. data/lib/rails/graphql/callback.rb +124 -0
  124. data/lib/rails/graphql/collectors.rb +14 -0
  125. data/lib/rails/graphql/collectors/hash_collector.rb +83 -0
  126. data/lib/rails/graphql/collectors/idented_collector.rb +73 -0
  127. data/lib/rails/graphql/collectors/json_collector.rb +114 -0
  128. data/lib/rails/graphql/config.rb +61 -0
  129. data/lib/rails/graphql/directive.rb +203 -0
  130. data/lib/rails/graphql/directive/deprecated_directive.rb +59 -0
  131. data/lib/rails/graphql/directive/include_directive.rb +24 -0
  132. data/lib/rails/graphql/directive/skip_directive.rb +24 -0
  133. data/lib/rails/graphql/errors.rb +42 -0
  134. data/lib/rails/graphql/event.rb +141 -0
  135. data/lib/rails/graphql/field.rb +318 -0
  136. data/lib/rails/graphql/field/input_field.rb +92 -0
  137. data/lib/rails/graphql/field/mutation_field.rb +52 -0
  138. data/lib/rails/graphql/field/output_field.rb +96 -0
  139. data/lib/rails/graphql/field/proxied_field.rb +131 -0
  140. data/lib/rails/graphql/field/resolved_field.rb +96 -0
  141. data/lib/rails/graphql/field/scoped_config.rb +22 -0
  142. data/lib/rails/graphql/field/typed_field.rb +104 -0
  143. data/lib/rails/graphql/helpers.rb +40 -0
  144. data/lib/rails/graphql/helpers/attribute_delegator.rb +39 -0
  145. data/lib/rails/graphql/helpers/inherited_collection.rb +152 -0
  146. data/lib/rails/graphql/helpers/leaf_from_ar.rb +141 -0
  147. data/lib/rails/graphql/helpers/registerable.rb +103 -0
  148. data/lib/rails/graphql/helpers/with_arguments.rb +125 -0
  149. data/lib/rails/graphql/helpers/with_assignment.rb +113 -0
  150. data/lib/rails/graphql/helpers/with_callbacks.rb +55 -0
  151. data/lib/rails/graphql/helpers/with_directives.rb +126 -0
  152. data/lib/rails/graphql/helpers/with_events.rb +81 -0
  153. data/lib/rails/graphql/helpers/with_fields.rb +141 -0
  154. data/lib/rails/graphql/helpers/with_namespace.rb +40 -0
  155. data/lib/rails/graphql/helpers/with_owner.rb +35 -0
  156. data/lib/rails/graphql/helpers/with_schema_fields.rb +230 -0
  157. data/lib/rails/graphql/helpers/with_validator.rb +52 -0
  158. data/lib/rails/graphql/introspection.rb +53 -0
  159. data/lib/rails/graphql/native.rb +56 -0
  160. data/lib/rails/graphql/native/functions.rb +38 -0
  161. data/lib/rails/graphql/native/location.rb +41 -0
  162. data/lib/rails/graphql/native/pointers.rb +23 -0
  163. data/lib/rails/graphql/native/visitor.rb +349 -0
  164. data/lib/rails/graphql/railtie.rb +85 -0
  165. data/lib/rails/graphql/railties/base_generator.rb +35 -0
  166. data/lib/rails/graphql/railties/controller.rb +101 -0
  167. data/lib/rails/graphql/railties/controller_runtime.rb +40 -0
  168. data/lib/rails/graphql/railties/log_subscriber.rb +62 -0
  169. data/lib/rails/graphql/request.rb +343 -0
  170. data/lib/rails/graphql/request/arguments.rb +93 -0
  171. data/lib/rails/graphql/request/component.rb +100 -0
  172. data/lib/rails/graphql/request/component/field.rb +225 -0
  173. data/lib/rails/graphql/request/component/fragment.rb +118 -0
  174. data/lib/rails/graphql/request/component/operation.rb +178 -0
  175. data/lib/rails/graphql/request/component/operation/subscription.rb +16 -0
  176. data/lib/rails/graphql/request/component/spread.rb +119 -0
  177. data/lib/rails/graphql/request/component/typename.rb +82 -0
  178. data/lib/rails/graphql/request/context.rb +51 -0
  179. data/lib/rails/graphql/request/errors.rb +54 -0
  180. data/lib/rails/graphql/request/event.rb +112 -0
  181. data/lib/rails/graphql/request/helpers/directives.rb +64 -0
  182. data/lib/rails/graphql/request/helpers/selection_set.rb +87 -0
  183. data/lib/rails/graphql/request/helpers/value_writers.rb +115 -0
  184. data/lib/rails/graphql/request/steps/organizable.rb +146 -0
  185. data/lib/rails/graphql/request/steps/prepareable.rb +33 -0
  186. data/lib/rails/graphql/request/steps/resolveable.rb +32 -0
  187. data/lib/rails/graphql/request/strategy.rb +249 -0
  188. data/lib/rails/graphql/request/strategy/dynamic_instance.rb +41 -0
  189. data/lib/rails/graphql/request/strategy/multi_query_strategy.rb +36 -0
  190. data/lib/rails/graphql/request/strategy/sequenced_strategy.rb +28 -0
  191. data/lib/rails/graphql/schema.rb +272 -0
  192. data/lib/rails/graphql/shortcuts.rb +77 -0
  193. data/lib/rails/graphql/source.rb +371 -0
  194. data/lib/rails/graphql/source/active_record/builders.rb +154 -0
  195. data/lib/rails/graphql/source/active_record_source.rb +231 -0
  196. data/lib/rails/graphql/source/scoped_arguments.rb +87 -0
  197. data/lib/rails/graphql/to_gql.rb +368 -0
  198. data/lib/rails/graphql/type.rb +138 -0
  199. data/lib/rails/graphql/type/enum.rb +206 -0
  200. data/lib/rails/graphql/type/enum/directive_location_enum.rb +30 -0
  201. data/lib/rails/graphql/type/enum/type_kind_enum.rb +57 -0
  202. data/lib/rails/graphql/type/input.rb +134 -0
  203. data/lib/rails/graphql/type/interface.rb +82 -0
  204. data/lib/rails/graphql/type/object.rb +111 -0
  205. data/lib/rails/graphql/type/object/directive_object.rb +34 -0
  206. data/lib/rails/graphql/type/object/enum_value_object.rb +25 -0
  207. data/lib/rails/graphql/type/object/field_object.rb +54 -0
  208. data/lib/rails/graphql/type/object/input_value_object.rb +49 -0
  209. data/lib/rails/graphql/type/object/schema_object.rb +40 -0
  210. data/lib/rails/graphql/type/object/type_object.rb +136 -0
  211. data/lib/rails/graphql/type/scalar.rb +71 -0
  212. data/lib/rails/graphql/type/scalar/bigint_scalar.rb +34 -0
  213. data/lib/rails/graphql/type/scalar/binary_scalar.rb +30 -0
  214. data/lib/rails/graphql/type/scalar/boolean_scalar.rb +37 -0
  215. data/lib/rails/graphql/type/scalar/date_scalar.rb +34 -0
  216. data/lib/rails/graphql/type/scalar/date_time_scalar.rb +32 -0
  217. data/lib/rails/graphql/type/scalar/decimal_scalar.rb +35 -0
  218. data/lib/rails/graphql/type/scalar/float_scalar.rb +32 -0
  219. data/lib/rails/graphql/type/scalar/id_scalar.rb +39 -0
  220. data/lib/rails/graphql/type/scalar/int_scalar.rb +36 -0
  221. data/lib/rails/graphql/type/scalar/string_scalar.rb +28 -0
  222. data/lib/rails/graphql/type/scalar/time_scalar.rb +40 -0
  223. data/lib/rails/graphql/type/union.rb +87 -0
  224. data/lib/rails/graphql/type_map.rb +347 -0
  225. data/lib/rails/graphql/version.rb +7 -0
  226. data/test/assets/introspection-db.json +0 -0
  227. data/test/assets/introspection-mem.txt +1 -0
  228. data/test/assets/introspection.gql +91 -0
  229. data/test/assets/luke.jpg +0 -0
  230. data/test/assets/mem.gql +428 -0
  231. data/test/assets/sqlite.gql +423 -0
  232. data/test/config.rb +80 -0
  233. data/test/graphql/request/context_test.rb +70 -0
  234. data/test/graphql/schema_test.rb +190 -0
  235. data/test/graphql/source_test.rb +237 -0
  236. data/test/graphql/type/enum_test.rb +203 -0
  237. data/test/graphql/type/input_test.rb +138 -0
  238. data/test/graphql/type/interface_test.rb +72 -0
  239. data/test/graphql/type/object_test.rb +104 -0
  240. data/test/graphql/type/scalar/bigint_scalar_test.rb +42 -0
  241. data/test/graphql/type/scalar/binary_scalar_test.rb +17 -0
  242. data/test/graphql/type/scalar/boolean_scalar_test.rb +40 -0
  243. data/test/graphql/type/scalar/date_scalar_test.rb +29 -0
  244. data/test/graphql/type/scalar/date_time_scalar_test.rb +29 -0
  245. data/test/graphql/type/scalar/decimal_scalar_test.rb +28 -0
  246. data/test/graphql/type/scalar/float_scalar_test.rb +22 -0
  247. data/test/graphql/type/scalar/id_scalar_test.rb +26 -0
  248. data/test/graphql/type/scalar/int_scalar_test.rb +26 -0
  249. data/test/graphql/type/scalar/string_scalar_test.rb +17 -0
  250. data/test/graphql/type/scalar/time_scalar_test.rb +36 -0
  251. data/test/graphql/type/scalar_test.rb +45 -0
  252. data/test/graphql/type/union_test.rb +82 -0
  253. data/test/graphql/type_map_test.rb +362 -0
  254. data/test/graphql/type_test.rb +68 -0
  255. data/test/graphql_test.rb +55 -0
  256. data/test/integration/config.rb +56 -0
  257. data/test/integration/memory/star_wars_introspection_test.rb +144 -0
  258. data/test/integration/memory/star_wars_query_test.rb +184 -0
  259. data/test/integration/memory/star_wars_validation_test.rb +99 -0
  260. data/test/integration/schemas/memory.rb +232 -0
  261. data/test/integration/schemas/sqlite.rb +82 -0
  262. data/test/integration/sqlite/star_wars_introspection_test.rb +15 -0
  263. data/test/integration/sqlite/star_wars_mutation_test.rb +82 -0
  264. data/test/integration/sqlite/star_wars_query_test.rb +71 -0
  265. data/test/test_ext.rb +48 -0
  266. metadata +509 -0
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails # :nodoc:
4
+ module GraphQL # :nodoc:
5
+ # = Rails GraphQL Callback
6
+ #
7
+ # An extra powerfull proc that can handle way more situations than the
8
+ # original block caller
9
+ class Callback
10
+ attr_reader :event_name, :block, :target, :filters
11
+
12
+ delegate :event_filters, to: :target
13
+ delegate :callback_inject_arguments, :callback_inject_named_arguments,
14
+ to: '::Rails::GraphQL.config'
15
+
16
+ # Directives need to be contextualized by the given instance as +context+
17
+ def self.set_context(item, context)
18
+ lambda { |*args| item.call(*args, context: context) }
19
+ end
20
+
21
+ def initialize(target, event_name, *args, **xargs, &block)
22
+ raise ::ArgumentError, <<~MSG.squish if block.nil? && !args.first.present?
23
+ Either provide a block or a method name when setting a #{event_name}
24
+ callback on #{target.inspect}.
25
+ MSG
26
+
27
+ if block.nil?
28
+ block = args.shift
29
+ valid_format = block.is_a?(Symbol) || block.is_a?(Proc)
30
+ raise ::ArgumentError, <<~MSG.squish unless valid_format
31
+ The given #{block.class.name} class is not a valid callback.
32
+ MSG
33
+ end
34
+
35
+ @target = target
36
+ @event_name = event_name
37
+
38
+ @pre_args = args
39
+ @pre_xargs = xargs.slice!(*event_filters.keys)
40
+ @filters = xargs.map do |key, value|
41
+ [key, event_filters[key][:sanitizer]&.call(value) || value]
42
+ end.to_h
43
+
44
+ @block = block
45
+ end
46
+
47
+ # This does the whole checking and preparation in order to really execute
48
+ # the callback method
49
+ def call(event, context: nil)
50
+ return unless event.name === event_name && can_run?(event)
51
+ block.is_a?(Symbol) ? call_symbol(event) : call_proc(event, context)
52
+ end
53
+
54
+ # Get a described source location for the callback
55
+ def source_location
56
+ block.is_a?(Proc) ? block.source_location : [
57
+ "(symbolized-callback/#{target.inspect})",
58
+ block,
59
+ ]
60
+ end
61
+
62
+ # This basically allows the class to be passed as +&block+
63
+ def to_proc
64
+ method(:call).to_proc.tap do |block|
65
+ block.define_singleton_method(:source_location, &method(:source_location))
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ # Using the filters, check if the current callback can be executed
72
+ def can_run?(event)
73
+ filters.all? { |key, options| event_filters[key][:block].call(options, event) }
74
+ end
75
+
76
+ # Call the callback block as a symbol
77
+ def call_symbol(event)
78
+ owner = target.try(:proxied_owner) || target.try(:owner) || target
79
+ event.on_instance(owner) do |instance|
80
+ block = instance.method(@block)
81
+ args, xargs = collect_parameters(event, block)
82
+ block.call(*args, **xargs)
83
+ end
84
+ end
85
+
86
+ # Call the callback block as a proc
87
+ def call_proc(event, context = nil)
88
+ args, xargs = collect_parameters(event)
89
+ (context || event).instance_exec(*args, **xargs, &block)
90
+ end
91
+
92
+ # Read the arguments needed for a block then collect them from the
93
+ # event and return the execution args
94
+ def collect_parameters(event, block = @block)
95
+ args_source = event.send(:args_source) || event
96
+ start_args = [@pre_args.deep_dup, @pre_xargs.deep_dup]
97
+ return start_args unless inject_arguments?
98
+
99
+ # TODO: Maybe we need to turn procs into lambdas so the optional
100
+ # arguments doesn't suffer any kind of change
101
+ idx = -1
102
+ block.parameters.each_with_object(start_args) do |(type, name), result|
103
+ case type
104
+ when :opt, :req
105
+ idx += 1
106
+ next unless callback_inject_arguments
107
+ result[0][idx] ||= event.parameter(name) if event.parameter?(name)
108
+ when :keyreq
109
+ next unless callback_inject_named_arguments
110
+ result[1][name] ||= args_source[name]
111
+ when :key
112
+ next unless callback_inject_named_arguments
113
+ result[1][name] ||= args_source[name] if args_source.key?(name)
114
+ end
115
+ end
116
+ end
117
+
118
+ # Check if the callback should inject arguments
119
+ def inject_arguments?
120
+ callback_inject_arguments || callback_inject_named_arguments
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails # :nodoc:
4
+ module GraphQL # :nodoc:
5
+ module Collectors # :nodoc:
6
+ extend ActiveSupport::Autoload
7
+
8
+ autoload :HashCollector
9
+ autoload :IdentedCollector
10
+ autoload :JsonCollector
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,83 @@
1
+ module Rails # :nodoc:
2
+ module GraphQL # :nodoc:
3
+ module Collectors # :nodoc:
4
+ # This collector helps building a JSON response using the hash approach,
5
+ # where the value is kept as an hash and later turn into a string
6
+ class HashCollector
7
+ def initialize(request)
8
+ @request = request
9
+ @stack = []
10
+ @data = {}
11
+ end
12
+
13
+ # Shortcut for starting and ending a stack while execute a block.
14
+ def with_stack(key, array: false, plain: false)
15
+ return unless block_given?
16
+ start_stack(array, plain)
17
+ yield
18
+ end_stack(key, array, plain)
19
+ rescue
20
+ pop_size = array && !plain ? 2 : 1
21
+ @data = @stack.pop(pop_size).first
22
+ raise
23
+ end
24
+
25
+ # Add the given +value+ to the given +key+.
26
+ def add(key, value)
27
+ @data.is_a?(Array) ? @data << value : @data[key.to_s] = value
28
+ end
29
+
30
+ alias safe_add add
31
+
32
+ # Serialize is a helper to call the correct method on types before add
33
+ def serialize(klass, key, value)
34
+ add(key, klass.as_json(value))
35
+ end
36
+
37
+ # Mark the start of a new element on the array.
38
+ def next
39
+ return unless @stack.last.is_a?(Array)
40
+ @stack.last << @data
41
+ @data = {}
42
+ end
43
+
44
+ # Append to the responsa data all the errors that happened during the
45
+ # request process
46
+ def append_errors(errors)
47
+ return if errors.empty?
48
+ @data['errors'] = errors.to_a
49
+ end
50
+
51
+ # Return the generated object
52
+ def to_h
53
+ @data
54
+ end
55
+
56
+ # Generate the JSON string result
57
+ def to_s
58
+ GraphQL.config.encode_with_active_support? \
59
+ ? ::ActiveSupport::JSON.encode(@data) \
60
+ : ::JSON.generate(@data)
61
+ end
62
+
63
+ private
64
+
65
+ # Start a new part of the collector. When set +as_array+, the result
66
+ # of the stack will be an array.
67
+ def start_stack(as_array = false, plain_array = false)
68
+ @stack << @data
69
+ @stack << [] if as_array && !plain_array
70
+ @data = as_array && plain_array ? [] : {}
71
+ end
72
+
73
+ # Finalize a stack and set the result on the given +key+.
74
+ def end_stack(key, as_array = false, plain_array = false)
75
+ result = as_array && !plain_array ? @stack.pop : @data
76
+
77
+ @data = @stack.pop
78
+ add(key, result)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,73 @@
1
+ module Rails # :nodoc:
2
+ module GraphQL # :nodoc:
3
+ module Collectors # :nodoc:
4
+ # This collector helps building a indented string
5
+ class IdentedCollector
6
+ def initialize(initial = 0, size = 2, auto_eol: true)
7
+ @size = size
8
+ @val = [[initial, '']]
9
+ @auto_eol = auto_eol
10
+ end
11
+
12
+ def indented(start = nil, finish = nil, auto_eol = @auto_eol)
13
+ self << start unless start.nil?
14
+
15
+ indent
16
+ yield
17
+
18
+ @val.last.pop while @val.last.last.blank?
19
+ unindent
20
+
21
+ @val.pop(2) if blank?(-2)
22
+
23
+ self << finish unless finish.nil?
24
+ eol if auto_eol
25
+ self
26
+ end
27
+
28
+ def value
29
+ @val.map do |(ident, *content)|
30
+ next if content.size.eql?(1) && content.first.blank?
31
+ ident = (' ' * ident)
32
+ ident + content.join("\n#{ident}")
33
+ end.compact.join("\n")
34
+ end
35
+
36
+ def puts(str)
37
+ @val.last.last << str
38
+ eol
39
+ end
40
+
41
+ def <<(str)
42
+ @val.last.last << str
43
+ self
44
+ end
45
+
46
+ def eol
47
+ @val.last << ''
48
+ self
49
+ end
50
+
51
+ def indent
52
+ return @val.last[0] += @size if blank?
53
+ @val << [last_ident + @size, '']
54
+ self
55
+ end
56
+
57
+ def unindent
58
+ return @val.last[0] -= @size if blank?
59
+ @val << [last_ident - @size, '']
60
+ self
61
+ end
62
+
63
+ def last_ident
64
+ @val.last.first
65
+ end
66
+
67
+ def blank?(pos = -1)
68
+ @val[pos].size.eql?(2) && @val[pos].last.empty?
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails # :nodoc:
4
+ module GraphQL # :nodoc:
5
+ module Collectors # :nodoc:
6
+ # This collector helps building a JSON response using the string approach,
7
+ # which has better performance, since all the encoding is performed up
8
+ # front. The drawback is that it can't return an hash.
9
+ class JsonCollector
10
+ def initialize(request)
11
+ @request = request
12
+
13
+ @current_value = String.new
14
+ @stack_value = []
15
+
16
+ @current_array = false
17
+ @stack_array = []
18
+
19
+ @current_plain_array = false
20
+ @stack_plain_array = []
21
+ end
22
+
23
+ # Shortcut for starting and ending a stack while execute a block.
24
+ def with_stack(key, array: false, plain: false)
25
+ return unless block_given?
26
+ start_stack(array, plain)
27
+ yield
28
+ end_stack(key, array, plain)
29
+ rescue
30
+ pop_size = array && !plain ? 2 : 1
31
+ @current_value = @stack_value.pop(pop_size).first
32
+ @current_array = @stack_array.pop(pop_size).first
33
+ raise
34
+ end
35
+
36
+ # Append to the responsa data all the errors that happened during the
37
+ # request process.
38
+ def append_errors(errors)
39
+ return if errors.empty?
40
+ add('errors', errors.to_json)
41
+ end
42
+
43
+ # Add the given +value+ to the given +key+. Ensure to encode the value
44
+ # before calling this function.
45
+ def add(key, value)
46
+ (@current_value << ',') unless @current_value.blank?
47
+
48
+ if @current_array
49
+ @current_value << value
50
+ else
51
+ @current_value << '"'
52
+ @current_value << key.to_s
53
+ @current_value << '":'
54
+ @current_value << value.to_s
55
+ end
56
+ end
57
+
58
+ # Same as +add+ but this always encode the +value+ beforehand.
59
+ def safe_add(key, value)
60
+ add(key, value.nil? ? 'null' : value.to_json)
61
+ end
62
+
63
+ # Serialize is a helper to call the correct method on types before add
64
+ def serialize(klass, key, value)
65
+ add(key, klass.to_json(value))
66
+ end
67
+
68
+ # Mark the start of a new element on the array.
69
+ def next
70
+ return unless @stack_array.last === :complex
71
+ (@stack_value.last << ',') unless @stack_value.last.blank?
72
+ @stack_value.last << to_s
73
+ @current_value = String.new
74
+ end
75
+
76
+ # Get the current result
77
+ def to_s
78
+ @current_array ? "[#{@current_value}]" : "{#{@current_value}}"
79
+ end
80
+
81
+ private
82
+
83
+ # Start a new part of the collector. When set +as_array+, the result
84
+ # of the stack will be encolsed by +[]+.
85
+ def start_stack(as_array = false, plain_array = false)
86
+ @stack_value << @current_value
87
+ @stack_array << @current_array
88
+
89
+ if as_array && !plain_array
90
+ @stack_value << String.new
91
+ @stack_array << :complex
92
+ as_array = false
93
+ end
94
+
95
+ @current_value = String.new
96
+ @current_array = as_array
97
+ end
98
+
99
+ # Finalize a stack and set the result on the given +key+.
100
+ def end_stack(key, as_array = false, plain_array = false)
101
+ if as_array && !plain_array
102
+ @current_value = @stack_value.pop
103
+ @current_array = @stack_array.pop
104
+ end
105
+
106
+ result = to_s
107
+ @current_value = @stack_value.pop
108
+ @current_array = @stack_array.pop
109
+ add(key, result)
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails # :nodoc:
4
+ module GraphQL # :nodoc:
5
+ configure do |config|
6
+ # This exposes the clean path from where a GraphQL request was started
7
+ config.verbose_logs = true
8
+
9
+ # A list of ActiveRecord adapters and their specific internal naming used
10
+ # to compound the accessors for direct query serialization
11
+ config.ar_adapters = {
12
+ 'Mysql2' => :mysql,
13
+ 'PostgreSQL' => :pg,
14
+ 'SQLite' => :sqlite,
15
+ }
16
+
17
+ # For all the input object type defined, auto add the following prefix to
18
+ # their name, so we don't have to define classes like +PointInputInput+.
19
+ config.auto_suffix_input_objects = 'Input'
20
+
21
+ # For performance purposes, this gem implements a
22
+ # {JsonCollector}[rdoc-ref:Rails::GraphQL::Collectors::JsonCollector].
23
+ # If you prefer to use the normal hash to string serialization, you can
24
+ # disable this option.
25
+ config.enable_string_collector = true
26
+
27
+ # Specifies if the results of operations should be encoded with
28
+ # +ActiveSupport::JSON#encode+ instead of the default +JSON#generate+.
29
+ # See also https://github.com/rails/rails/blob/master/activesupport/lib/active_support/json/encoding.rb
30
+ config.encode_with_active_support = false
31
+
32
+ # Enable the ability of a callback to dynamically inject argumnets to the
33
+ # calling method.
34
+ config.callback_inject_arguments = true
35
+
36
+ # Enable the ability of a callback to dynamically inject named argumnets
37
+ # to the calling method.
38
+ config.callback_inject_named_arguments = true
39
+
40
+ # A list of execution strategies. Each application can add their own by
41
+ # simply append a class name, preferable as string, in this list.
42
+ config.request_strategies = [
43
+ 'Rails::GraphQL::Request::Strategy::MultiQueryStrategy',
44
+ 'Rails::GraphQL::Request::Strategy::SequencedStrategy',
45
+ ]
46
+
47
+ # TODO: To be implemented
48
+ # enable_i18n_descriptions
49
+ # enable_auto_descriptions
50
+ # allow_query_serialization
51
+ # source_generate_dependencies
52
+ end
53
+
54
+ # This is the logger for all the operations for GraphQL
55
+ def self.logger
56
+ config.logger ||= ActiveSupport::TaggedLogging.new(
57
+ ActiveSupport::Logger.new(STDOUT),
58
+ )
59
+ end
60
+ end
61
+ end