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.
- checksums.yaml +4 -4
- data/ext/console.rb +18 -0
- data/ext/extconf.h +3 -0
- data/ext/extconf.rb +1 -54
- data/ext/gql_parser.c +646 -0
- data/ext/shared.c +482 -0
- data/ext/shared.h +177 -0
- data/lib/gql_parser.so +0 -0
- data/lib/rails/graphql/adapters/mysql_adapter.rb +59 -0
- data/lib/rails/graphql/adapters/pg_adapter.rb +25 -22
- data/lib/rails/graphql/adapters/sqlite_adapter.rb +17 -14
- data/lib/rails/graphql/alternative/field_set.rb +36 -0
- data/lib/rails/graphql/alternative/mutation.rb +17 -0
- data/lib/rails/graphql/alternative/query.rb +93 -0
- data/lib/rails/graphql/alternative/subscription.rb +17 -0
- data/lib/rails/graphql/alternative.rb +20 -0
- data/lib/rails/graphql/argument.rb +21 -24
- data/lib/rails/graphql/callback.rb +24 -9
- data/lib/rails/graphql/collectors/hash_collector.rb +14 -6
- data/lib/rails/graphql/collectors/idented_collector.rb +10 -7
- data/lib/rails/graphql/collectors/json_collector.rb +22 -17
- data/lib/rails/graphql/collectors.rb +4 -4
- data/lib/rails/graphql/config.rb +130 -15
- data/lib/rails/graphql/directive/cached_directive.rb +33 -0
- data/lib/rails/graphql/directive/deprecated_directive.rb +10 -10
- data/lib/rails/graphql/directive/include_directive.rb +5 -4
- data/lib/rails/graphql/directive/skip_directive.rb +5 -4
- data/lib/rails/graphql/directive.rb +118 -63
- data/lib/rails/graphql/errors.rb +33 -4
- data/lib/rails/graphql/event.rb +16 -5
- data/lib/rails/graphql/field/authorized_field.rb +19 -3
- data/lib/rails/graphql/field/input_field.rb +11 -10
- data/lib/rails/graphql/field/mutation_field.rb +42 -7
- data/lib/rails/graphql/field/output_field.rb +102 -13
- data/lib/rails/graphql/field/proxied_field.rb +31 -22
- data/lib/rails/graphql/field/resolved_field.rb +26 -24
- data/lib/rails/graphql/field/scoped_config.rb +10 -4
- data/lib/rails/graphql/field/subscription_field.rb +140 -0
- data/lib/rails/graphql/field/typed_field.rb +43 -22
- data/lib/rails/graphql/field.rb +70 -56
- data/lib/rails/graphql/global_id.rb +85 -0
- data/lib/rails/graphql/helpers/attribute_delegator.rb +5 -5
- data/lib/rails/graphql/helpers/inherited_collection/array.rb +50 -0
- data/lib/rails/graphql/helpers/inherited_collection/base.rb +43 -0
- data/lib/rails/graphql/helpers/inherited_collection/hash.rb +87 -0
- data/lib/rails/graphql/helpers/inherited_collection.rb +25 -76
- data/lib/rails/graphql/helpers/instantiable.rb +15 -0
- data/lib/rails/graphql/helpers/leaf_from_ar.rb +7 -7
- data/lib/rails/graphql/helpers/registerable.rb +44 -62
- data/lib/rails/graphql/helpers/unregisterable.rb +16 -0
- data/lib/rails/graphql/helpers/with_arguments.rb +31 -27
- data/lib/rails/graphql/helpers/with_assignment.rb +6 -6
- data/lib/rails/graphql/helpers/with_callbacks.rb +25 -8
- data/lib/rails/graphql/helpers/with_description.rb +71 -0
- data/lib/rails/graphql/helpers/with_directives.rb +54 -30
- data/lib/rails/graphql/helpers/with_events.rb +21 -23
- data/lib/rails/graphql/helpers/with_fields.rb +76 -22
- data/lib/rails/graphql/helpers/with_global_id.rb +22 -0
- data/lib/rails/graphql/helpers/with_name.rb +43 -0
- data/lib/rails/graphql/helpers/with_namespace.rb +7 -4
- data/lib/rails/graphql/helpers/with_owner.rb +8 -7
- data/lib/rails/graphql/helpers/with_schema_fields.rb +137 -55
- data/lib/rails/graphql/helpers/with_validator.rb +9 -9
- data/lib/rails/graphql/helpers.rb +10 -3
- data/lib/rails/graphql/introspection.rb +43 -36
- data/lib/rails/graphql/railtie.rb +88 -33
- data/lib/rails/graphql/railties/base_generator.rb +3 -9
- data/lib/rails/graphql/railties/channel.rb +157 -0
- data/lib/rails/graphql/railties/controller.rb +62 -17
- data/lib/rails/graphql/railties/controller_runtime.rb +5 -5
- data/lib/rails/graphql/railties/log_subscriber.rb +81 -14
- data/lib/rails/graphql/request/arguments.rb +24 -49
- data/lib/rails/graphql/request/backtrace.rb +191 -0
- data/lib/rails/graphql/request/component/field.rb +86 -65
- data/lib/rails/graphql/request/component/fragment.rb +72 -24
- data/lib/rails/graphql/request/component/operation/subscription.rb +164 -4
- data/lib/rails/graphql/request/component/operation.rb +63 -31
- data/lib/rails/graphql/request/component/spread.rb +68 -25
- data/lib/rails/graphql/request/component/typename.rb +27 -12
- data/lib/rails/graphql/request/component.rb +75 -36
- data/lib/rails/graphql/request/context.rb +18 -8
- data/lib/rails/graphql/request/errors.rb +16 -6
- data/lib/rails/graphql/request/event.rb +19 -8
- data/lib/rails/graphql/request/helpers/directives.rb +68 -27
- data/lib/rails/graphql/request/helpers/selection_set.rb +51 -25
- data/lib/rails/graphql/request/helpers/value_writers.rb +18 -16
- data/lib/rails/graphql/request/prepared_data.rb +98 -0
- data/lib/rails/graphql/request/steps/authorizable.rb +24 -14
- data/lib/rails/graphql/request/steps/organizable.rb +110 -48
- data/lib/rails/graphql/request/steps/{prepareable.rb → preparable.rb} +20 -7
- data/lib/rails/graphql/request/steps/{resolveable.rb → resolvable.rb} +15 -6
- data/lib/rails/graphql/request/strategy/cached_strategy.rb +64 -0
- data/lib/rails/graphql/request/strategy/dynamic_instance.rb +6 -6
- data/lib/rails/graphql/request/strategy/multi_query_strategy.rb +6 -13
- data/lib/rails/graphql/request/strategy/sequenced_strategy.rb +9 -9
- data/lib/rails/graphql/request/strategy.rb +131 -75
- data/lib/rails/graphql/request/subscription.rb +80 -0
- data/lib/rails/graphql/request.rb +305 -86
- data/lib/rails/graphql/schema.rb +240 -48
- data/lib/rails/graphql/shortcuts.rb +22 -3
- data/lib/rails/graphql/source/active_record/builders.rb +49 -35
- data/lib/rails/graphql/source/active_record_source.rb +70 -54
- data/lib/rails/graphql/source/base.rb +111 -0
- data/lib/rails/graphql/source/builder.rb +128 -0
- data/lib/rails/graphql/source/scoped_arguments.rb +31 -19
- data/lib/rails/graphql/source.rb +89 -213
- data/lib/rails/graphql/subscription/provider/action_cable.rb +112 -0
- data/lib/rails/graphql/subscription/provider/base.rb +191 -0
- data/lib/rails/graphql/subscription/provider.rb +18 -0
- data/lib/rails/graphql/subscription/store/base.rb +145 -0
- data/lib/rails/graphql/subscription/store/memory.rb +127 -0
- data/lib/rails/graphql/subscription/store.rb +19 -0
- data/lib/rails/graphql/subscription.rb +17 -0
- data/lib/rails/graphql/to_gql.rb +29 -32
- data/lib/rails/graphql/type/enum/directive_location_enum.rb +11 -11
- data/lib/rails/graphql/type/enum/type_kind_enum.rb +3 -3
- data/lib/rails/graphql/type/enum.rb +34 -48
- data/lib/rails/graphql/type/input.rb +74 -23
- data/lib/rails/graphql/type/interface.rb +16 -26
- data/lib/rails/graphql/type/object/directive_object.rb +4 -4
- data/lib/rails/graphql/type/object/enum_value_object.rb +3 -3
- data/lib/rails/graphql/type/object/field_object.rb +24 -6
- data/lib/rails/graphql/type/object/input_value_object.rb +3 -3
- data/lib/rails/graphql/type/object/schema_object.rb +5 -8
- data/lib/rails/graphql/type/object/type_object.rb +29 -19
- data/lib/rails/graphql/type/object.rb +26 -23
- data/lib/rails/graphql/type/scalar/any_scalar.rb +30 -0
- data/lib/rails/graphql/type/scalar/bigint_scalar.rb +5 -5
- data/lib/rails/graphql/type/scalar/binary_scalar.rb +3 -3
- data/lib/rails/graphql/type/scalar/boolean_scalar.rb +8 -8
- data/lib/rails/graphql/type/scalar/date_scalar.rb +3 -3
- data/lib/rails/graphql/type/scalar/date_time_scalar.rb +3 -3
- data/lib/rails/graphql/type/scalar/decimal_scalar.rb +3 -3
- data/lib/rails/graphql/type/scalar/float_scalar.rb +5 -5
- data/lib/rails/graphql/type/scalar/id_scalar.rb +6 -5
- data/lib/rails/graphql/type/scalar/int_scalar.rb +6 -5
- data/lib/rails/graphql/type/scalar/json_scalar.rb +39 -0
- data/lib/rails/graphql/type/scalar/string_scalar.rb +18 -4
- data/lib/rails/graphql/type/scalar/time_scalar.rb +5 -5
- data/lib/rails/graphql/type/scalar.rb +25 -22
- data/lib/rails/graphql/type/union.rb +14 -16
- data/lib/rails/graphql/type.rb +34 -25
- data/lib/rails/graphql/type_map.rb +256 -164
- data/lib/rails/graphql/uri.rb +166 -0
- data/lib/rails/graphql/version.rb +15 -3
- data/lib/rails/graphql.rake +3 -0
- data/lib/rails/graphql.rb +85 -52
- data/lib/rails-graphql.rb +1 -1
- data/test/assets/en.yml +29 -0
- data/test/assets/introspection-mem.txt +1 -1
- data/test/assets/mem.gql +18 -45
- data/test/assets/mysql.gql +392 -0
- data/test/assets/sqlite.gql +21 -12
- data/test/assets/translate.gql +335 -0
- data/test/config.rb +18 -8
- data/test/graphql/schema_test.rb +12 -19
- data/test/graphql/source_test.rb +8 -75
- data/test/graphql/type/enum_test.rb +207 -203
- data/test/graphql/type/input_test.rb +14 -9
- data/test/graphql/type/interface_test.rb +4 -4
- data/test/graphql/type/scalar/any_scalar_test.rb +38 -0
- data/test/graphql/type/scalar/boolean_scalar_test.rb +6 -3
- data/test/graphql/type/scalar/json_scalar_test.rb +23 -0
- data/test/graphql/type_map_test.rb +51 -66
- data/test/graphql/type_test.rb +0 -19
- data/test/graphql_test.rb +1 -1
- data/test/integration/{authorization/authorization_test.rb → authorization_test.rb} +40 -14
- data/test/integration/config.rb +36 -3
- data/test/integration/customization_test.rb +39 -0
- data/test/integration/global_id_test.rb +99 -0
- data/test/integration/memory/star_wars_introspection_test.rb +24 -16
- data/test/integration/memory/star_wars_query_test.rb +54 -3
- data/test/integration/memory/star_wars_validation_test.rb +1 -1
- data/test/integration/mysql/star_wars_introspection_test.rb +25 -0
- data/test/integration/persisted_query_test.rb +87 -0
- data/test/integration/resolver_precedence_test.rb +154 -0
- data/test/integration/schemas/memory.rb +22 -7
- data/test/integration/schemas/mysql.rb +62 -0
- data/test/integration/schemas/sqlite.rb +21 -12
- data/test/integration/sqlite/star_wars_global_id_test.rb +83 -0
- data/test/integration/sqlite/star_wars_introspection_test.rb +10 -0
- data/test/integration/sqlite/star_wars_query_test.rb +14 -1
- data/test/integration/translate_test.rb +61 -0
- data/test/test_ext.rb +16 -13
- metadata +108 -157
- data/ext/depend +0 -3
- data/ext/graphqlparser/Ast.cpp +0 -346
- data/ext/graphqlparser/Ast.h +0 -1214
- data/ext/graphqlparser/AstNode.h +0 -36
- data/ext/graphqlparser/AstVisitor.h +0 -137
- data/ext/graphqlparser/GraphQLParser.cpp +0 -76
- data/ext/graphqlparser/GraphQLParser.h +0 -55
- data/ext/graphqlparser/JsonVisitor.cpp +0 -161
- data/ext/graphqlparser/JsonVisitor.cpp.inc +0 -456
- data/ext/graphqlparser/JsonVisitor.h +0 -121
- data/ext/graphqlparser/JsonVisitor.h.inc +0 -110
- data/ext/graphqlparser/VERSION +0 -1
- data/ext/graphqlparser/c/GraphQLAst.cpp +0 -324
- data/ext/graphqlparser/c/GraphQLAst.h +0 -180
- data/ext/graphqlparser/c/GraphQLAstForEachConcreteType.h +0 -44
- data/ext/graphqlparser/c/GraphQLAstNode.cpp +0 -25
- data/ext/graphqlparser/c/GraphQLAstNode.h +0 -33
- data/ext/graphqlparser/c/GraphQLAstToJSON.cpp +0 -21
- data/ext/graphqlparser/c/GraphQLAstToJSON.h +0 -24
- data/ext/graphqlparser/c/GraphQLAstVisitor.cpp +0 -55
- data/ext/graphqlparser/c/GraphQLAstVisitor.h +0 -53
- data/ext/graphqlparser/c/GraphQLParser.cpp +0 -35
- data/ext/graphqlparser/c/GraphQLParser.h +0 -54
- data/ext/graphqlparser/dump_json_ast.cpp +0 -48
- data/ext/graphqlparser/lexer.lpp +0 -324
- data/ext/graphqlparser/parser.ypp +0 -693
- data/ext/graphqlparser/parsergen/lexer.cpp +0 -2633
- data/ext/graphqlparser/parsergen/lexer.h +0 -528
- data/ext/graphqlparser/parsergen/location.hh +0 -189
- data/ext/graphqlparser/parsergen/parser.tab.cpp +0 -3300
- data/ext/graphqlparser/parsergen/parser.tab.hpp +0 -646
- data/ext/graphqlparser/parsergen/position.hh +0 -179
- data/ext/graphqlparser/parsergen/stack.hh +0 -156
- data/ext/graphqlparser/syntaxdefs.h +0 -19
- data/ext/libgraphqlparser/AstNode.h +0 -36
- data/ext/libgraphqlparser/CMakeLists.txt +0 -148
- data/ext/libgraphqlparser/CONTRIBUTING.md +0 -23
- data/ext/libgraphqlparser/GraphQLParser.cpp +0 -76
- data/ext/libgraphqlparser/GraphQLParser.h +0 -55
- data/ext/libgraphqlparser/JsonVisitor.cpp +0 -161
- data/ext/libgraphqlparser/JsonVisitor.h +0 -121
- data/ext/libgraphqlparser/LICENSE +0 -22
- data/ext/libgraphqlparser/README.clang-tidy +0 -7
- data/ext/libgraphqlparser/README.md +0 -84
- data/ext/libgraphqlparser/ast/ast.ast +0 -203
- data/ext/libgraphqlparser/ast/ast.py +0 -61
- data/ext/libgraphqlparser/ast/c.py +0 -100
- data/ext/libgraphqlparser/ast/c.pyc +0 -0
- data/ext/libgraphqlparser/ast/c_impl.py +0 -61
- data/ext/libgraphqlparser/ast/c_impl.pyc +0 -0
- data/ext/libgraphqlparser/ast/c_visitor_impl.py +0 -39
- data/ext/libgraphqlparser/ast/c_visitor_impl.pyc +0 -0
- data/ext/libgraphqlparser/ast/casing.py +0 -26
- data/ext/libgraphqlparser/ast/casing.pyc +0 -0
- data/ext/libgraphqlparser/ast/cxx.py +0 -197
- data/ext/libgraphqlparser/ast/cxx.pyc +0 -0
- data/ext/libgraphqlparser/ast/cxx_impl.py +0 -61
- data/ext/libgraphqlparser/ast/cxx_impl.pyc +0 -0
- data/ext/libgraphqlparser/ast/cxx_json_visitor_header.py +0 -42
- data/ext/libgraphqlparser/ast/cxx_json_visitor_header.pyc +0 -0
- data/ext/libgraphqlparser/ast/cxx_json_visitor_impl.py +0 -80
- data/ext/libgraphqlparser/ast/cxx_json_visitor_impl.pyc +0 -0
- data/ext/libgraphqlparser/ast/cxx_visitor.py +0 -64
- data/ext/libgraphqlparser/ast/cxx_visitor.pyc +0 -0
- data/ext/libgraphqlparser/ast/js.py +0 -65
- data/ext/libgraphqlparser/ast/license.py +0 -10
- data/ext/libgraphqlparser/ast/license.pyc +0 -0
- data/ext/libgraphqlparser/c/GraphQLAstNode.cpp +0 -25
- data/ext/libgraphqlparser/c/GraphQLAstNode.h +0 -33
- data/ext/libgraphqlparser/c/GraphQLAstToJSON.cpp +0 -21
- data/ext/libgraphqlparser/c/GraphQLAstToJSON.h +0 -24
- data/ext/libgraphqlparser/c/GraphQLAstVisitor.cpp +0 -55
- data/ext/libgraphqlparser/c/GraphQLAstVisitor.h +0 -53
- data/ext/libgraphqlparser/c/GraphQLParser.cpp +0 -35
- data/ext/libgraphqlparser/c/GraphQLParser.h +0 -54
- data/ext/libgraphqlparser/clang-tidy-all.sh +0 -3
- data/ext/libgraphqlparser/cmake/version.cmake +0 -16
- data/ext/libgraphqlparser/dump_json_ast.cpp +0 -48
- data/ext/libgraphqlparser/go/README.md +0 -20
- data/ext/libgraphqlparser/go/callbacks.go +0 -18
- data/ext/libgraphqlparser/go/gotest.go +0 -64
- data/ext/libgraphqlparser/lexer.lpp +0 -324
- data/ext/libgraphqlparser/libgraphqlparser.pc.in +0 -11
- data/ext/libgraphqlparser/parser.ypp +0 -693
- data/ext/libgraphqlparser/parsergen/lexer.cpp +0 -2633
- data/ext/libgraphqlparser/parsergen/lexer.h +0 -528
- data/ext/libgraphqlparser/parsergen/location.hh +0 -189
- data/ext/libgraphqlparser/parsergen/parser.tab.cpp +0 -3300
- data/ext/libgraphqlparser/parsergen/parser.tab.hpp +0 -646
- data/ext/libgraphqlparser/parsergen/position.hh +0 -179
- data/ext/libgraphqlparser/parsergen/stack.hh +0 -156
- data/ext/libgraphqlparser/python/CMakeLists.txt +0 -14
- data/ext/libgraphqlparser/python/README.md +0 -5
- data/ext/libgraphqlparser/python/example.py +0 -31
- data/ext/libgraphqlparser/syntaxdefs.h +0 -19
- data/ext/libgraphqlparser/test/BuildCAPI.c +0 -5
- data/ext/libgraphqlparser/test/CMakeLists.txt +0 -25
- data/ext/libgraphqlparser/test/JsonVisitorTests.cpp +0 -28
- data/ext/libgraphqlparser/test/ParserTests.cpp +0 -352
- data/ext/libgraphqlparser/test/kitchen-sink.graphql +0 -59
- data/ext/libgraphqlparser/test/kitchen-sink.json +0 -1
- data/ext/libgraphqlparser/test/schema-kitchen-sink.graphql +0 -78
- data/ext/libgraphqlparser/test/schema-kitchen-sink.json +0 -1
- data/ext/libgraphqlparser/test/valgrind.supp +0 -33
- data/ext/version.cpp +0 -21
- data/lib/graphqlparser.so +0 -0
- data/lib/rails/graphql/native/functions.rb +0 -38
- data/lib/rails/graphql/native/location.rb +0 -41
- data/lib/rails/graphql/native/pointers.rb +0 -23
- data/lib/rails/graphql/native/visitor.rb +0 -349
- data/lib/rails/graphql/native.rb +0 -56
- data/test/integration/schemas/authorization.rb +0 -12
@@ -1,35 +1,75 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Rails
|
4
|
-
module GraphQL
|
3
|
+
module Rails
|
4
|
+
module GraphQL
|
5
5
|
# = GraphQL Output Field
|
6
6
|
#
|
7
7
|
# Most of the fields in a GraphQL operation are output fields or similar or
|
8
8
|
# proxies of it. They can express both leaf and branch data. They can also
|
9
9
|
# be the entry point of a GraphQL request.
|
10
|
+
#
|
11
|
+
# ==== Options
|
12
|
+
#
|
13
|
+
# * <tt>:method_name</tt> - The name of the method used to fetch the field data
|
14
|
+
# (defaults to nil).
|
15
|
+
# * <tt>:deprecated</tt> - A shortcut to adding a deprecated directive to the field
|
16
|
+
# (defaults to nil).
|
10
17
|
class Field::OutputField < Field
|
18
|
+
# Do not change this order because it can affect how events work. Callback
|
19
|
+
# must always come after events
|
11
20
|
include Helpers::WithArguments
|
12
|
-
include Helpers::WithValidator
|
13
21
|
include Helpers::WithEvents
|
14
22
|
include Helpers::WithCallbacks
|
15
23
|
|
24
|
+
include Helpers::WithGlobalID
|
25
|
+
include Helpers::WithValidator
|
26
|
+
|
16
27
|
include Field::AuthorizedField
|
17
28
|
include Field::ResolvedField
|
18
29
|
include Field::TypedField
|
19
30
|
|
20
31
|
module Proxied # :nodoc: all
|
21
|
-
def initialize(*args, **xargs, &block)
|
22
|
-
@method_name = xargs.delete(:method_name) if xargs.key?(:method_name)
|
23
|
-
super(*args, **xargs, &block)
|
24
|
-
end
|
25
|
-
|
26
32
|
def all_arguments
|
27
|
-
field.
|
33
|
+
inherited = field.all_arguments
|
34
|
+
return inherited unless defined?(@arguments)
|
35
|
+
inherited.blank? ? super : inherited + super
|
28
36
|
end
|
29
37
|
|
30
38
|
def has_argument?(name)
|
31
39
|
super || field.has_argument?(name)
|
32
40
|
end
|
41
|
+
|
42
|
+
def arguments?
|
43
|
+
super || field.arguments?
|
44
|
+
end
|
45
|
+
|
46
|
+
def all_events
|
47
|
+
if (inherited = super).nil?
|
48
|
+
field.all_events
|
49
|
+
elsif (proxied = field.all_events).nil?
|
50
|
+
inherited
|
51
|
+
else
|
52
|
+
Helpers.merge_hash_array(proxied, inherited)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def events?
|
57
|
+
super || field.events?
|
58
|
+
end
|
59
|
+
|
60
|
+
def all_listeners
|
61
|
+
if (inherited = super).nil?
|
62
|
+
field.all_listeners
|
63
|
+
elsif (proxied = field.all_listeners).nil?
|
64
|
+
inherited
|
65
|
+
else
|
66
|
+
proxied + inherited
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def listeners?
|
71
|
+
super || field.listeners?
|
72
|
+
end
|
33
73
|
end
|
34
74
|
|
35
75
|
redefine_singleton_method(:output_type?) { true }
|
@@ -37,9 +77,10 @@ module Rails # :nodoc:
|
|
37
77
|
|
38
78
|
def initialize(*args, method_name: nil, deprecated: false, **xargs, &block)
|
39
79
|
@method_name = method_name.to_s.underscore.to_sym unless method_name.nil?
|
80
|
+
@broadcastable = xargs.delete(:broadcastable) if xargs.key?(:broadcastable)
|
40
81
|
|
41
82
|
if deprecated.present?
|
42
|
-
xargs[:directives] = Array.wrap(xargs[:directives])
|
83
|
+
xargs[:directives] = ::Array.wrap(xargs[:directives])
|
43
84
|
xargs[:directives] << Directive::DeprecatedDirective.new(
|
44
85
|
reason: (deprecated.is_a?(String) ? deprecated : nil),
|
45
86
|
)
|
@@ -48,12 +89,23 @@ module Rails # :nodoc:
|
|
48
89
|
super(*args, **xargs, &block)
|
49
90
|
end
|
50
91
|
|
92
|
+
# Accept changes to the method name through the +apply_changes+
|
93
|
+
def apply_changes(**xargs, &block)
|
94
|
+
@method_name = xargs.delete(:method_name) if xargs.key?(:method_name)
|
95
|
+
super
|
96
|
+
end
|
97
|
+
|
98
|
+
# By default, output fields that belongs to a schema is a query field
|
99
|
+
def schema_type
|
100
|
+
:query
|
101
|
+
end
|
102
|
+
|
51
103
|
# Check if the arguments are also equivalent
|
52
104
|
def =~(other)
|
53
105
|
super && match_arguments?(other)
|
54
106
|
end
|
55
107
|
|
56
|
-
# Checks if a given
|
108
|
+
# Checks if a given raw value is valid for this field
|
57
109
|
def valid_output?(value, deep: true)
|
58
110
|
return false unless super
|
59
111
|
return null? if value.nil?
|
@@ -74,11 +126,43 @@ module Rails # :nodoc:
|
|
74
126
|
def validate!(*)
|
75
127
|
super if defined? super
|
76
128
|
|
77
|
-
raise ArgumentError,
|
129
|
+
raise ArgumentError, (+<<~MSG).squish unless type_klass.output_type?
|
78
130
|
The "#{type_klass.gql_name}" is not a valid output type.
|
79
131
|
MSG
|
80
132
|
end
|
81
133
|
|
134
|
+
def all_events
|
135
|
+
if !defined?(@events) || !(local = @events).present?
|
136
|
+
super
|
137
|
+
elsif (inherited = super).nil?
|
138
|
+
local
|
139
|
+
else
|
140
|
+
Helpers.merge_hash_array(inherited, local)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def events?
|
145
|
+
super || defined?(@events) && @events.present?
|
146
|
+
end
|
147
|
+
|
148
|
+
def all_listeners
|
149
|
+
if !defined?(@listeners) || !(local = @listeners).present?
|
150
|
+
super
|
151
|
+
elsif (inherited = super).nil?
|
152
|
+
local
|
153
|
+
else
|
154
|
+
inherited + local
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def listeners?
|
159
|
+
super || defined?(@listeners) && @listeners.present?
|
160
|
+
end
|
161
|
+
|
162
|
+
def broadcastable?
|
163
|
+
defined?(@broadcastable) && @broadcastable
|
164
|
+
end
|
165
|
+
|
82
166
|
protected
|
83
167
|
|
84
168
|
# Check if the given +value+ is a valid array as output
|
@@ -91,7 +175,12 @@ module Rails # :nodoc:
|
|
91
175
|
end
|
92
176
|
end
|
93
177
|
|
94
|
-
|
178
|
+
# Properly display the owner section when the field is owned by a Schema
|
179
|
+
def inspect_owner
|
180
|
+
owner.is_a?(Helpers::WithSchemaFields) ? +"#{owner.name}[:#{schema_type}]" : super
|
181
|
+
end
|
182
|
+
|
183
|
+
def proxied
|
95
184
|
super if defined? super
|
96
185
|
extend Field::OutputField::Proxied
|
97
186
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Rails
|
4
|
-
module GraphQL
|
3
|
+
module Rails
|
4
|
+
module GraphQL
|
5
5
|
# = GraphQL Proxied Field
|
6
6
|
#
|
7
7
|
# Proxied fields are a soft way to copy a real field. The good part is that
|
@@ -26,7 +26,7 @@ module Rails # :nodoc:
|
|
26
26
|
module Field::ProxiedField
|
27
27
|
delegate_missing_to :field
|
28
28
|
delegate :leaf_type?, :array?, :internal?, :valid_input?, :valid_output?,
|
29
|
-
:to_json, :as_json, :deserialize, :valid?, to: :field
|
29
|
+
:to_json, :as_json, :deserialize, :valid?, :proxied_owner, to: :field
|
30
30
|
|
31
31
|
Field.proxyable_methods %w[name gql_name method_name resolver description
|
32
32
|
null? nullable? enabled?], klass: self
|
@@ -43,15 +43,22 @@ module Rails # :nodoc:
|
|
43
43
|
true
|
44
44
|
end
|
45
45
|
|
46
|
+
# Make sure to check the original field as well
|
47
|
+
# TODO: Maybe not use the +==+ method, but so far so good
|
48
|
+
def ==(other)
|
49
|
+
super || field == other
|
50
|
+
end
|
51
|
+
|
46
52
|
# Allow chaging most of the general kind-independent initialize settings
|
47
53
|
def apply_changes(**xargs, &block)
|
48
54
|
if (deprecated = xargs[:deprecated])
|
49
|
-
xargs[:directives] = Array.wrap(xargs[:directives])
|
55
|
+
xargs[:directives] = ::Array.wrap(xargs[:directives])
|
50
56
|
xargs[:directives] << Directive::DeprecatedDirective.new(
|
51
57
|
reason: (deprecated.is_a?(String) ? deprecated : nil),
|
52
58
|
)
|
53
59
|
end
|
54
60
|
|
61
|
+
# TODO: Replace by a proper method to build and set @directives
|
55
62
|
@directives = GraphQL.directives_to_set(xargs[:directives], source: self) \
|
56
63
|
if xargs.key?(:directives)
|
57
64
|
|
@@ -63,11 +70,6 @@ module Rails # :nodoc:
|
|
63
70
|
super
|
64
71
|
end
|
65
72
|
|
66
|
-
# Return the original owner from +field+
|
67
|
-
def proxied_owner
|
68
|
-
field.owner
|
69
|
-
end
|
70
|
-
|
71
73
|
# Override this to include proxied owners
|
72
74
|
def all_owners
|
73
75
|
super + proxied_owner.all_owners
|
@@ -78,34 +80,41 @@ module Rails # :nodoc:
|
|
78
80
|
@field
|
79
81
|
end
|
80
82
|
|
81
|
-
|
83
|
+
# Just ensure that when the field is proxied to an interface it does not
|
84
|
+
# allow disabling
|
85
|
+
def disable!
|
82
86
|
super unless non_interface_proxy!('disable')
|
83
87
|
end
|
84
88
|
|
85
|
-
|
89
|
+
# Just ensure that when the field is proxied to an interface it does not
|
90
|
+
# allow enabling
|
91
|
+
def enable!
|
86
92
|
super unless non_interface_proxy!('enable')
|
87
93
|
end
|
88
94
|
|
89
|
-
|
90
|
-
|
95
|
+
# Prepend the proxy directives and then the source directives
|
96
|
+
def all_directives
|
97
|
+
inherited = field.all_directives
|
98
|
+
return inherited unless defined?(@directives)
|
99
|
+
inherited.present? ? inherited + super : super
|
100
|
+
end
|
101
|
+
|
102
|
+
# Check if the field has directives locally or in the proxied field
|
103
|
+
def directives?
|
104
|
+
super || field.directives?
|
91
105
|
end
|
92
106
|
|
93
|
-
# It is important to ensure that the proxied field is also valid
|
94
|
-
# proxied owner is registered, then it is safe to assume that it is valid
|
107
|
+
# It is important to ensure that the proxied field is also valid
|
95
108
|
def validate!(*)
|
96
109
|
super if defined? super
|
97
|
-
field.validate!
|
98
|
-
proxied_owner,
|
99
|
-
namespaces: namespaces,
|
100
|
-
exclusive: true,
|
101
|
-
)
|
110
|
+
field.validate!
|
102
111
|
end
|
103
112
|
|
104
113
|
protected
|
105
114
|
|
106
115
|
alias field proxied_field
|
107
116
|
|
108
|
-
def normalize_name(value)
|
117
|
+
def normalize_name(value)
|
109
118
|
super unless value.blank? || non_interface_proxy!('rename')
|
110
119
|
end
|
111
120
|
|
@@ -124,7 +133,7 @@ module Rails # :nodoc:
|
|
124
133
|
|
125
134
|
# Display the source of the proxy for inspection
|
126
135
|
def inspect_source
|
127
|
-
"@source=#{
|
136
|
+
+"@source=#{field.owner.name}[:#{field.name}] [proxied]"
|
128
137
|
end
|
129
138
|
|
130
139
|
# This is trigerred when the field is proxied
|
@@ -1,23 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Rails
|
4
|
-
module GraphQL
|
3
|
+
module Rails
|
4
|
+
module GraphQL
|
5
5
|
# This provides ways for fields to be resolved manually, by adding callbacks
|
6
6
|
# and additional configurations in order to resolve a field value during a
|
7
7
|
# request
|
8
8
|
module Field::ResolvedField
|
9
9
|
module Proxied # :nodoc: all
|
10
|
-
def all_listeners
|
11
|
-
field.all_listeners + super
|
12
|
-
end
|
13
|
-
|
14
|
-
def all_events
|
15
|
-
events = defined?(@events) ? @events : {}
|
16
|
-
Helpers.merge_hash_array(field.all_events, events).transform_values do |arr|
|
17
|
-
arr.sort_by { |cb| cb.try(:target).is_a?(GraphQL::Field) ? 0 : 1 }
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
10
|
def resolver
|
22
11
|
super || field.resolver
|
23
12
|
end
|
@@ -65,26 +54,39 @@ module Rails # :nodoc:
|
|
65
54
|
|
66
55
|
# Store this result for performance purposes
|
67
56
|
@dynamic_resolver = dynamic_resolver?
|
68
|
-
return unless defined?
|
57
|
+
return unless defined?(@events)
|
69
58
|
|
70
|
-
|
71
|
-
|
72
|
-
|
59
|
+
# TODO: Change how events are validated. Relying on the +source_location
|
60
|
+
# uses inspect, which is not a good approach
|
61
|
+
|
62
|
+
# invalid = @events.each_pair.each_with_object({}) do |(key, events), hash|
|
63
|
+
# events.each do |event|
|
64
|
+
# _, method_name = event.source_location
|
65
|
+
# next if method_name.nil? || callable?(method_name)
|
66
|
+
|
67
|
+
# (hash[key] ||= []).push(method_name)
|
68
|
+
# end
|
69
|
+
# end
|
70
|
+
|
71
|
+
# return if invalid.empty?
|
73
72
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
73
|
+
# invalid = invalid.map { |key, list| (+"#{key} => [#{list.join(', ')}]") }
|
74
|
+
# raise ArgumentError, (+<<~MSG).squish if invalid.present?
|
75
|
+
# The "#{owner.name}" class does not define the following methods needed
|
76
|
+
# for performing callbacks: #{invalid.join(', ')}.
|
77
|
+
# MSG
|
78
78
|
end
|
79
79
|
|
80
80
|
protected
|
81
81
|
|
82
|
-
#
|
82
|
+
# Check if the method is defined and does not belong to a method defined
|
83
|
+
# by the gem itself
|
83
84
|
def callable?(method_name)
|
84
|
-
owner.is_a?(Class) && owner.
|
85
|
+
owner.is_a?(Class) && owner.public_method_defined?(method_name) &&
|
86
|
+
!owner.public_instance_method(method_name).owner.try(:abstract?)
|
85
87
|
end
|
86
88
|
|
87
|
-
def proxied
|
89
|
+
def proxied
|
88
90
|
super if defined? super
|
89
91
|
extend Field::ResolvedField::Proxied
|
90
92
|
end
|
@@ -1,22 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Rails
|
4
|
-
module GraphQL
|
3
|
+
module Rails
|
4
|
+
module GraphQL
|
5
5
|
# Helper class to be used while configuring a field using a block. An
|
6
6
|
# instance of this class works as proxy for changes to the actual field.
|
7
|
-
Field::ScopedConfig
|
7
|
+
class Field::ScopedConfig < Struct.new(:field, :receiver)
|
8
8
|
delegate :argument, :ref_argument, :id_argument, :use, :internal?, :disabled?,
|
9
9
|
:enabled?, :disable!, :enable!, :authorize, to: :field
|
10
10
|
|
11
11
|
delegate_missing_to :receiver
|
12
12
|
|
13
|
+
def rename!(name)
|
14
|
+
field.instance_variable_set(:@gql_name, name.to_s)
|
15
|
+
end
|
16
|
+
|
13
17
|
def method_name(value)
|
14
18
|
field.instance_variable_set(:@method_name, value.to_sym)
|
15
19
|
end
|
16
20
|
|
17
21
|
def desc(value)
|
18
|
-
field.
|
22
|
+
field.description = value
|
19
23
|
end
|
24
|
+
|
25
|
+
alias description desc
|
20
26
|
end
|
21
27
|
end
|
22
28
|
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rails
|
4
|
+
module GraphQL
|
5
|
+
# = GraphQL Subscription Field
|
6
|
+
#
|
7
|
+
# TODO: Finish and add description
|
8
|
+
class Field::SubscriptionField < Field::OutputField
|
9
|
+
redefine_singleton_method(:subscription?) { true }
|
10
|
+
event_types(:subscribed, append: true)
|
11
|
+
|
12
|
+
attr_reader :prepare_context
|
13
|
+
|
14
|
+
module Proxied # :nodoc: all
|
15
|
+
def full_scope
|
16
|
+
field.full_scope + super
|
17
|
+
end
|
18
|
+
|
19
|
+
def prepare_context
|
20
|
+
super || field.prepare_context
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Change the schema type of the field
|
25
|
+
def schema_type
|
26
|
+
:subscription
|
27
|
+
end
|
28
|
+
|
29
|
+
# A kind of alias to the subscribe event available
|
30
|
+
def subscribed(*args, **xargs, &block)
|
31
|
+
on(:subscribed, *args, **xargs, &block)
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
# Set the parts of the scope of the subscription
|
36
|
+
def scope(*parts)
|
37
|
+
(defined?(@scope) ? (@scope += parts) : (@scope = parts)).freeze
|
38
|
+
end
|
39
|
+
|
40
|
+
# Get the full scope of the field
|
41
|
+
def full_scope
|
42
|
+
return EMPTY_ARRAY unless defined?(@scope)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Checks if the scope is correctly defined
|
46
|
+
def validate!(*)
|
47
|
+
super if defined? super
|
48
|
+
return unless defined?(@scope)
|
49
|
+
|
50
|
+
invalid = @scope.reject { |item| item.is_a?(Symbol) || item.is_a?(Proc) }
|
51
|
+
raise ArgumentError, (+<<~MSG).squish if invalid.any?
|
52
|
+
The "#{type_klass.gql_name}" has invalid values set for its scope: #{invalid.inspect}.
|
53
|
+
MSG
|
54
|
+
end
|
55
|
+
|
56
|
+
# A shortcut for trigger when everything is related to the provided object
|
57
|
+
# TODO: Maybe add support for object as an array of things
|
58
|
+
# TODO: Add support for +data_for+. The only problem right now is that
|
59
|
+
# providers run asynchronously, so passing data is a bit more complicated
|
60
|
+
# and maybe dangerous (size speaking)
|
61
|
+
def trigger_for(object, **xargs)
|
62
|
+
match_valid_object!(object)
|
63
|
+
xargs[:args] ||= extract_args_from(object)
|
64
|
+
trigger(**xargs)
|
65
|
+
end
|
66
|
+
|
67
|
+
# A shortcut for unsubscribe when everything is related to the provided
|
68
|
+
# object
|
69
|
+
# TODO: Maybe add support for object as an array of things
|
70
|
+
def unsubscribe_from(object, **xargs)
|
71
|
+
match_valid_object!(object)
|
72
|
+
xargs[:args] ||= extract_args_from(object)
|
73
|
+
unsubscribe(**xargs)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Trigger an update to the subscription
|
77
|
+
def trigger(args: nil, scope: nil)
|
78
|
+
provider = owner.subscription_provider
|
79
|
+
provider.search_and_update(field: self, args: args, scope: scope)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Force matching subscriptions to be removed
|
83
|
+
def unsubscribe(args: nil, scope: nil)
|
84
|
+
provider = owner.subscription_provider
|
85
|
+
provider.search_and_remove(field: self, args: args, scope: scope)
|
86
|
+
end
|
87
|
+
|
88
|
+
protected
|
89
|
+
|
90
|
+
# Match any argument with properties from the given +object+ so it
|
91
|
+
# produces all the possibilities of an update
|
92
|
+
def extract_args_from(object)
|
93
|
+
return unless arguments?
|
94
|
+
|
95
|
+
# Prepare all the possibilities
|
96
|
+
keys = []
|
97
|
+
hash_like = object.respond_to?(:[])
|
98
|
+
possibilities = all_arguments.each_value.with_object([]) do |arg, list|
|
99
|
+
keys << arg.name
|
100
|
+
list << []
|
101
|
+
|
102
|
+
value =
|
103
|
+
if object.respond_to?(arg.name)
|
104
|
+
object.public_send(arg.name)
|
105
|
+
elsif hash_like && (object.key?(arg.name) || object.key?(arg.name.to_s))
|
106
|
+
object[arg.name] || arg.name[arg.name.to_s]
|
107
|
+
end
|
108
|
+
|
109
|
+
list.last << value unless value.nil?
|
110
|
+
list.last << nil if arg.null?
|
111
|
+
end
|
112
|
+
|
113
|
+
# Now turn them into actual possible args
|
114
|
+
possibilities.reduce(:product).flatten.each_slice(keys.size).map do |items|
|
115
|
+
keys.zip(items).to_h
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Check if the provided +object+ is a match for the type that this field
|
120
|
+
# is associated with
|
121
|
+
def match_valid_object!(object)
|
122
|
+
raise ::ArgumentError, (+<<~MSG).squish unless type_klass&.object?
|
123
|
+
Cannot trigger with an object when the field is not associated to
|
124
|
+
an object-like result.
|
125
|
+
MSG
|
126
|
+
|
127
|
+
assignable = !object.is_a?(Module) && type_klass.valid_member?(object)
|
128
|
+
raise ::ArgumentError, (+<<~MSG).squish unless assignable
|
129
|
+
The provided object "#{object.inspect}" is not a valid member of
|
130
|
+
#{type_klass.inspect} for the :#{name} field.
|
131
|
+
MSG
|
132
|
+
end
|
133
|
+
|
134
|
+
def proxied
|
135
|
+
super if defined? super
|
136
|
+
extend Field::SubscriptionField::Proxied
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Rails
|
4
|
-
module GraphQL
|
3
|
+
module Rails
|
4
|
+
module GraphQL
|
5
5
|
# This is a helper module that basically works with fields that have an
|
6
6
|
# assigned type value
|
7
7
|
module Field::TypedField
|
@@ -14,13 +14,7 @@ module Rails # :nodoc:
|
|
14
14
|
delegate :input_type?, :output_type?, :leaf_type?, :kind, to: :type_klass
|
15
15
|
|
16
16
|
def initialize(name, type, *args, **xargs, &block)
|
17
|
-
|
18
|
-
@type_klass = type
|
19
|
-
@type = type.to_sym
|
20
|
-
else
|
21
|
-
@type = type.to_s.underscore.to_sym
|
22
|
-
end
|
23
|
-
|
17
|
+
assign_type(type)
|
24
18
|
super(name, *args, **xargs, &block)
|
25
19
|
end
|
26
20
|
|
@@ -36,7 +30,7 @@ module Rails # :nodoc:
|
|
36
30
|
end
|
37
31
|
|
38
32
|
# Sometimes the owner does not designate this, but it is safe to assume it
|
39
|
-
# will be associated to the object
|
33
|
+
# will be associated to the object valid types
|
40
34
|
def valid_field_types
|
41
35
|
owner.try(:valid_field_types) || Type::Object.valid_field_types
|
42
36
|
end
|
@@ -57,27 +51,42 @@ module Rails # :nodoc:
|
|
57
51
|
|
58
52
|
# Add the listeners from the associated type
|
59
53
|
def all_listeners
|
60
|
-
|
54
|
+
inherited = super
|
55
|
+
return inherited unless type_klass.listeners?
|
56
|
+
inherited.present? ? inherited + type_klass.all_listeners : type_klass.all_listeners
|
57
|
+
end
|
58
|
+
|
59
|
+
# Make sure to check the associated type
|
60
|
+
def listeners?
|
61
|
+
super || type_klass.listeners?
|
61
62
|
end
|
62
63
|
|
63
64
|
# Add the events from the associated type
|
64
65
|
def all_events
|
65
|
-
|
66
|
+
inherited = super
|
67
|
+
return inherited unless type_klass.events?
|
68
|
+
return type_klass.all_events if inherited.blank?
|
69
|
+
Helpers.merge_hash_array(inherited, type_klass.all_events)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Make sure to check the associated type
|
73
|
+
def events?
|
74
|
+
super || type_klass.events?
|
66
75
|
end
|
67
76
|
|
68
77
|
# Checks if the type of the field is valid
|
69
78
|
def validate!(*)
|
70
79
|
super if defined? super
|
71
80
|
|
72
|
-
raise ArgumentError,
|
73
|
-
Unable to find the "#{type.inspect}"
|
81
|
+
raise ArgumentError, (+<<~MSG).squish unless type_klass.is_a?(Module)
|
82
|
+
Unable to find the "#{type.inspect}" data type on GraphQL context.
|
74
83
|
MSG
|
75
84
|
|
76
85
|
valid_type = valid_field_types.empty? || valid_field_types.any? do |base_type|
|
77
86
|
type_klass < base_type
|
78
87
|
end
|
79
88
|
|
80
|
-
raise ArgumentError,
|
89
|
+
raise ArgumentError, (+<<~MSG).squish unless valid_type
|
81
90
|
The "#{type_klass.base_type}" is not accepted in this context.
|
82
91
|
MSG
|
83
92
|
end
|
@@ -86,16 +95,28 @@ module Rails # :nodoc:
|
|
86
95
|
|
87
96
|
# Little helper that shows the type of the field
|
88
97
|
def inspect_type
|
89
|
-
result = ': '
|
90
|
-
result
|
91
|
-
result
|
92
|
-
result
|
93
|
-
result
|
94
|
-
result
|
98
|
+
result = +': '
|
99
|
+
result << '[' if array?
|
100
|
+
result << type_klass.gql_name
|
101
|
+
result << '!' if array? && !nullable?
|
102
|
+
result << ']' if array?
|
103
|
+
result << '!' unless null?
|
95
104
|
result
|
96
105
|
end
|
97
106
|
|
98
|
-
|
107
|
+
# A little hidden helper to support forcing reassignment of type, which
|
108
|
+
# should only be done with caution
|
109
|
+
def assign_type(type)
|
110
|
+
if type.is_a?(Module) && type < GraphQL::Type
|
111
|
+
@type_klass = type
|
112
|
+
@type = type.to_sym
|
113
|
+
else
|
114
|
+
@type_klass = nil
|
115
|
+
@type = type
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def proxied
|
99
120
|
super if defined? super
|
100
121
|
extend Field::TypedField::Proxied
|
101
122
|
end
|