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,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 Directive
|
6
6
|
#
|
7
7
|
# This is the base object for directives definition.
|
@@ -22,24 +22,31 @@ module Rails # :nodoc:
|
|
22
22
|
# add :old_value, directives: DeprecatedDirective(reason: 'not used anymore')
|
23
23
|
class Directive
|
24
24
|
extend ActiveSupport::Autoload
|
25
|
-
extend Helpers::InheritedCollection
|
26
25
|
extend Helpers::WithEvents
|
27
26
|
extend Helpers::WithCallbacks
|
28
27
|
extend Helpers::WithArguments
|
28
|
+
extend Helpers::WithGlobalID
|
29
29
|
extend Helpers::Registerable
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
EXECUTION_LOCATIONS = %i[
|
32
|
+
query mutation subscription field fragment_definition fragment_spread inline_fragment
|
33
|
+
].to_set.freeze
|
33
34
|
|
34
|
-
|
35
|
-
|
35
|
+
DEFINITION_LOCATIONS = %i[
|
36
|
+
schema scalar object field_definition argument_definition interface union
|
37
|
+
enum enum_value input_object input_field_definition
|
38
|
+
].to_set.freeze
|
39
|
+
|
40
|
+
VALID_LOCATIONS = (EXECUTION_LOCATIONS + DEFINITION_LOCATIONS).freeze
|
36
41
|
|
37
42
|
class << self
|
38
|
-
def kind
|
43
|
+
def kind
|
39
44
|
:directive
|
40
45
|
end
|
41
46
|
|
42
|
-
|
47
|
+
# Return the name of the object as a GraphQL name, ensure to use the
|
48
|
+
# first letter as lower case when being auto generated
|
49
|
+
def gql_name
|
43
50
|
return @gql_name if defined?(@gql_name)
|
44
51
|
@gql_name = super.camelize(:lower)
|
45
52
|
end
|
@@ -64,33 +71,40 @@ module Rails # :nodoc:
|
|
64
71
|
@locations = list.to_set
|
65
72
|
end
|
66
73
|
|
67
|
-
|
68
|
-
|
74
|
+
# Ensure to return the directive class
|
75
|
+
def gid_base_class
|
76
|
+
GraphQL::Directive
|
77
|
+
end
|
78
|
+
|
79
|
+
# A helper method that allows directives to be initialized while
|
80
|
+
# correctly parsing the arguments
|
81
|
+
def build(**xargs)
|
82
|
+
xargs = xargs.stringify_keys
|
83
|
+
result = all_arguments&.each&.each_with_object({}) do |(name, argument), hash|
|
84
|
+
hash[name] = argument.deserialize(xargs[argument.gql_name] || xargs[name.to_s])
|
85
|
+
end
|
86
|
+
|
87
|
+
new(**result)
|
88
|
+
end
|
69
89
|
|
70
|
-
|
90
|
+
# Return the directive, instantiate if it has params
|
91
|
+
def find_by_gid(gid)
|
92
|
+
options = { namespaces: gid.namespace, base_class: :Directive }
|
93
|
+
klass = GraphQL.type_map.fetch!(gid.name, **options)
|
94
|
+
gid.instantiate? ? klass.build(**gid.params) : klass
|
71
95
|
end
|
72
96
|
|
73
|
-
def inspect
|
74
|
-
return
|
97
|
+
def inspect
|
98
|
+
return super if eql?(GraphQL::Directive)
|
75
99
|
|
76
|
-
args =
|
100
|
+
args = all_arguments&.each_value&.map(&:inspect)
|
101
|
+
args = args.force if args.respond_to?(:force)
|
77
102
|
args = args.presence && "(#{args.join(', ')})"
|
78
|
-
"#<GraphQL::Directive @#{gql_name}#{args}>"
|
103
|
+
+"#<GraphQL::Directive @#{gql_name}#{args}>"
|
79
104
|
end
|
80
105
|
|
81
106
|
private
|
82
107
|
|
83
|
-
# Check if the given list the locations are valid
|
84
|
-
def validate_locations!(list)
|
85
|
-
list.flatten!
|
86
|
-
list.map! { |item| item.to_s.underscore.to_sym }
|
87
|
-
|
88
|
-
invalid = list - VALID_LOCATIONS
|
89
|
-
raise ArgumentError, <<~MSG.squish unless invalid.empty?
|
90
|
-
Invalid locations for @#{gql_name}: #{invalid.to_sentence}.
|
91
|
-
MSG
|
92
|
-
end
|
93
|
-
|
94
108
|
# Provide a nice way to use a directive without calling
|
95
109
|
# +Directive.new+, like the +DeprecatedDirective+ can be initialized
|
96
110
|
# using +GraphQL::DeprecatedDirective(*args)+
|
@@ -105,6 +119,29 @@ module Rails # :nodoc:
|
|
105
119
|
end
|
106
120
|
end
|
107
121
|
|
122
|
+
# A helper method that allows the +on+ and +for+ event filters to be
|
123
|
+
# used with things from both the TypeMap and the GraphQL shortcut
|
124
|
+
# classes
|
125
|
+
def sanitize_objects(setting)
|
126
|
+
GraphQL.enumerate(setting).map do |item|
|
127
|
+
next item unless item.is_a?(String) || item.is_a?(Symbol)
|
128
|
+
GraphQL.type_map.fetch(item, namespaces: namespaces) ||
|
129
|
+
::GraphQL.const_get(item)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Check if the given list the locations are valid
|
134
|
+
def validate_locations!(list)
|
135
|
+
invalid = list.flatten.lazy.reject do |item|
|
136
|
+
item = item.to_s.underscore.to_sym unless item.is_a?(Symbol)
|
137
|
+
VALID_LOCATIONS.include?(item)
|
138
|
+
end
|
139
|
+
|
140
|
+
raise ArgumentError, (+<<~MSG).squish if invalid.any?
|
141
|
+
Invalid locations for @#{gql_name}: #{invalid.force.to_sentence}.
|
142
|
+
MSG
|
143
|
+
end
|
144
|
+
|
108
145
|
# Allows checking value existence
|
109
146
|
def respond_to_missing?(method_name, *)
|
110
147
|
(const_defined?(method_name) rescue nil) || autoload?(method_name) || super
|
@@ -120,36 +157,24 @@ module Rails # :nodoc:
|
|
120
157
|
|
121
158
|
self.abstract = true
|
122
159
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
autoload :SkipDirective
|
127
|
-
end
|
160
|
+
autoload :DeprecatedDirective
|
161
|
+
autoload :IncludeDirective
|
162
|
+
autoload :SkipDirective
|
128
163
|
|
129
|
-
|
130
|
-
|
131
|
-
array_sanitizer = ->(setting) do
|
132
|
-
Array.wrap(setting)
|
133
|
-
end
|
164
|
+
autoload :CachedDirective
|
134
165
|
|
135
|
-
|
136
|
-
Array.wrap(setting).map! do |item|
|
137
|
-
next item unless item.is_a?(String) || item.is_a?(Symbol)
|
138
|
-
GraphQL.type_map.fetch(item, namespaces: namespaces) ||
|
139
|
-
::GraphQL.const_get(item)
|
140
|
-
end
|
141
|
-
end
|
166
|
+
delegate :locations, :gql_name, :gid_base_class, to: :class
|
142
167
|
|
143
|
-
event_filter(:for
|
144
|
-
options.any?(&event.source.method(:of_type?))
|
168
|
+
event_filter(:for) do |options, event|
|
169
|
+
sanitize_objects(options).any?(&event.source.method(:of_type?))
|
145
170
|
end
|
146
171
|
|
147
|
-
event_filter(:on
|
148
|
-
event.respond_to?(:on?) && options.any?(&event.method(:on?))
|
172
|
+
event_filter(:on) do |options, event|
|
173
|
+
event.respond_to?(:on?) && sanitize_objects(options).any?(&event.method(:on?))
|
149
174
|
end
|
150
175
|
|
151
|
-
event_filter(:during
|
152
|
-
event.key?(:phase) && options.include?(event[:phase])
|
176
|
+
event_filter(:during) do |options, event|
|
177
|
+
event.key?(:phase) && GraphQL.enumerate(options).include?(event[:phase])
|
153
178
|
end
|
154
179
|
|
155
180
|
attr_reader :args
|
@@ -160,17 +185,35 @@ module Rails # :nodoc:
|
|
160
185
|
end
|
161
186
|
|
162
187
|
# Once the directive is correctly prepared, we need to assign the owner
|
163
|
-
def
|
164
|
-
raise ArgumentError,
|
188
|
+
def assign_owner!(owner)
|
189
|
+
raise ArgumentError, (+<<~MSG).squish if defined?(@owner)
|
165
190
|
Owner already assigned for @#{gql_name} directive.
|
166
191
|
MSG
|
167
192
|
|
168
193
|
@owner = owner
|
169
194
|
end
|
170
195
|
|
196
|
+
# Correctly turn all the arguments into their +as_json+ version and return
|
197
|
+
# a hash of them
|
198
|
+
def args_as_json
|
199
|
+
all_arguments&.each&.with_object({}) do |(name, argument), hash|
|
200
|
+
hash[argument.gql_name] = argument.as_json(@args[name])
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# Correctly turn all the arguments into their +to_json+ version and return
|
205
|
+
# a hash of them
|
206
|
+
def args_to_json
|
207
|
+
all_arguments&.each&.with_object({}) do |(name, argument), hash|
|
208
|
+
hash[argument.gql_name] = argument.to_json(@args[name])
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
171
212
|
# When fetching all the events, embed the actual instance as the context
|
172
213
|
# of the callback
|
173
214
|
def all_events
|
215
|
+
return unless self.class.events?
|
216
|
+
|
174
217
|
@all_events ||= self.class.all_events.transform_values do |events|
|
175
218
|
events.map { |item| Callback.set_context(item, self) }
|
176
219
|
end
|
@@ -178,26 +221,38 @@ module Rails # :nodoc:
|
|
178
221
|
|
179
222
|
# Checks if all the arguments provided to the directive instance are valid
|
180
223
|
def validate!(*)
|
181
|
-
|
182
|
-
|
224
|
+
raise ArgumentError, (+<<~MSG).squish unless defined?(@owner)
|
225
|
+
The @#{gql_name} directive is unbounded.
|
226
|
+
MSG
|
183
227
|
|
184
|
-
invalid =
|
185
|
-
|
228
|
+
invalid = all_arguments&.reject { |name, arg| arg.valid?(@args[name]) }
|
229
|
+
return if invalid.blank?
|
230
|
+
|
231
|
+
invalid = invalid.each_key.map { |name| (+<<~MSG).squish }
|
232
|
+
invalid value "#{@args[name].inspect}" for #{name} argument
|
186
233
|
MSG
|
187
234
|
|
188
|
-
raise ArgumentError,
|
235
|
+
raise ArgumentError, (+<<~MSG).squish
|
189
236
|
Invalid usage of @#{gql_name} directive: #{invalid.to_sentence}.
|
190
237
|
MSG
|
191
238
|
end
|
192
239
|
|
193
|
-
def inspect
|
194
|
-
args = all_arguments
|
195
|
-
"#{arg.gql_name}: #{@args[name].inspect}" unless @args[name].nil?
|
196
|
-
end
|
240
|
+
def inspect
|
241
|
+
args = all_arguments&.map do |name, arg|
|
242
|
+
+"#{arg.gql_name}: #{@args[name].inspect}" unless @args[name].nil?
|
243
|
+
end&.compact
|
197
244
|
|
198
|
-
args = args.presence && "(#{args.join(', ')})"
|
199
|
-
|
245
|
+
args = args.presence && +"(#{args.join(', ')})"
|
246
|
+
unbound = ' # unbound' unless defined?(@owner)
|
247
|
+
+"@#{gql_name}#{args}#{unbound}"
|
200
248
|
end
|
249
|
+
|
250
|
+
%i[to_global_id to_gid to_gid_param].each do |method_name|
|
251
|
+
define_method(method_name) do
|
252
|
+
self.class.public_send(method_name, args_as_json&.compact || '')
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
201
256
|
end
|
202
257
|
end
|
203
258
|
end
|
data/lib/rails/graphql/errors.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Rails
|
4
|
-
module GraphQL
|
5
|
-
# Error class tha
|
3
|
+
module Rails
|
4
|
+
module GraphQL
|
5
|
+
# Error class tha wraps all the other error classes
|
6
6
|
StandardError = Class.new(::StandardError)
|
7
7
|
|
8
8
|
# Error class related to problems during the definition process
|
@@ -14,10 +14,13 @@ module Rails # :nodoc:
|
|
14
14
|
# Errors that can happen related to the arguments given to a method
|
15
15
|
ArgumentError = Class.new(DefinitionError)
|
16
16
|
|
17
|
+
# Errors that can happen when locking for definition objects, like fields
|
18
|
+
NotFoundError = Class.new(DefinitionError)
|
19
|
+
|
17
20
|
# Errors related to the name of the objects
|
18
21
|
NameError = Class.new(DefinitionError)
|
19
22
|
|
20
|
-
# Errors related to
|
23
|
+
# Errors related to duplicated objects
|
21
24
|
DuplicatedError = Class.new(NameError)
|
22
25
|
|
23
26
|
# Error class related to problems during the execution process
|
@@ -26,6 +29,9 @@ module Rails # :nodoc:
|
|
26
29
|
# Error related to the parsing process
|
27
30
|
ParseError = Class.new(ExecutionError)
|
28
31
|
|
32
|
+
# Error class related to parsing the arguments
|
33
|
+
ArgumentsError = Class.new(ParseError)
|
34
|
+
|
29
35
|
# Error class related to problems that happened during execution of fields
|
30
36
|
FieldError = Class.new(ExecutionError)
|
31
37
|
|
@@ -42,5 +48,28 @@ module Rails # :nodoc:
|
|
42
48
|
# Error class related to when a field is unauthorized and can not be used,
|
43
49
|
# similar to disabled fields
|
44
50
|
UnauthorizedFieldError = Class.new(FieldError)
|
51
|
+
|
52
|
+
# Error class related to problems that happened while subscribing to a field
|
53
|
+
SubscriptionError = Class.new(FieldError)
|
54
|
+
|
55
|
+
# Error class related to execution responses that don't require processing
|
56
|
+
StaticResponse = Class.new(Interrupt)
|
57
|
+
|
58
|
+
# Error class related to cached responses, which doesn't need processing
|
59
|
+
CachedResponse = Class.new(StaticResponse)
|
60
|
+
|
61
|
+
# Error class related to a persisted query that has't been persisted yet
|
62
|
+
PersistedQueryNotFound = Class.new(StaticResponse)
|
63
|
+
|
64
|
+
# A simple module and way to extend errors with extra information
|
65
|
+
ExtendedError = Module.new do
|
66
|
+
delegate_missing_to :@extension
|
67
|
+
|
68
|
+
def self.extend(error, extension)
|
69
|
+
error.instance_variable_set(:@extension, extension)
|
70
|
+
error.extend(self)
|
71
|
+
error
|
72
|
+
end
|
73
|
+
end
|
45
74
|
end
|
46
75
|
end
|
data/lib/rails/graphql/event.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Rails
|
4
|
-
module GraphQL
|
3
|
+
module Rails
|
4
|
+
module GraphQL
|
5
5
|
# = GraphQL Event
|
6
6
|
#
|
7
|
-
# This class is responsible for
|
7
|
+
# This class is responsible for triggering events. It also contains the
|
8
8
|
# +data+ that can be used on the event handlers.
|
9
9
|
class Event
|
10
10
|
attr_reader :source, :data, :name, :object, :last_result
|
@@ -40,6 +40,16 @@ module Rails # :nodoc:
|
|
40
40
|
@layers = []
|
41
41
|
end
|
42
42
|
|
43
|
+
# Check if the provided +other+ is equal to the source of the event. If
|
44
|
+
# other is a directive, then check if the source is using that directive
|
45
|
+
def same_source?(other)
|
46
|
+
if other.is_a?(Directive) || (other.is_a?(Module) && other < Directive)
|
47
|
+
source.using?(other)
|
48
|
+
else
|
49
|
+
source == other
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
43
53
|
# Return a given +name+ information from the event
|
44
54
|
def parameter(name)
|
45
55
|
respond_to?(name) ? public_send(name) : data[name]
|
@@ -75,6 +85,7 @@ module Rails # :nodoc:
|
|
75
85
|
def trigger_all(*objects)
|
76
86
|
catchable(:stack) do
|
77
87
|
iterator = @collect ? :map : :each
|
88
|
+
objects = objects.first if objects.size == 1 && objects.first.is_a?(Enumerable)
|
78
89
|
objects.flatten.send(iterator, &method(:trigger_object))
|
79
90
|
end
|
80
91
|
end
|
@@ -91,7 +102,7 @@ module Rails # :nodoc:
|
|
91
102
|
old_items, old_object, old_result, @object = @items, @object, @last_result, object
|
92
103
|
|
93
104
|
catchable(:object) do
|
94
|
-
events ||= object.all_events[name
|
105
|
+
events ||= object.all_events.try(:[], name)
|
95
106
|
stop if events.blank?
|
96
107
|
|
97
108
|
@items = @reverse ? events.reverse_each : events.each
|
@@ -138,7 +149,7 @@ module Rails # :nodoc:
|
|
138
149
|
@layers.unshift(layer)
|
139
150
|
catch(layer) { yield }
|
140
151
|
ensure
|
141
|
-
@layers.
|
152
|
+
@layers.shift
|
142
153
|
end
|
143
154
|
|
144
155
|
# Check for data based readers
|
@@ -1,11 +1,21 @@
|
|
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 authorized, giving a logical level for
|
6
6
|
# enabling or disabling access to a field. It has a similar structure to
|
7
7
|
# events, but has a different hierarchy of resolution
|
8
8
|
module Field::AuthorizedField
|
9
|
+
module Proxied # :nodoc: all
|
10
|
+
def authorizer
|
11
|
+
super || field.authorizer
|
12
|
+
end
|
13
|
+
|
14
|
+
def authorizable?
|
15
|
+
super || field.authorizable?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
9
19
|
# Just add the callbacks setup to the field
|
10
20
|
def self.included(other)
|
11
21
|
other.event_types(:authorize, append: true)
|
@@ -27,7 +37,13 @@ module Rails # :nodoc:
|
|
27
37
|
def authorizable?
|
28
38
|
defined?(@authorizer)
|
29
39
|
end
|
40
|
+
|
41
|
+
protected
|
42
|
+
|
43
|
+
def proxied
|
44
|
+
super if defined? super
|
45
|
+
extend Field::AuthorizedField::Proxied
|
46
|
+
end
|
30
47
|
end
|
31
48
|
end
|
32
49
|
end
|
33
|
-
#
|
@@ -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 Input Field
|
6
6
|
#
|
7
7
|
# An input field works the same way as an argument and they are pretty much
|
@@ -13,8 +13,6 @@ module Rails # :nodoc:
|
|
13
13
|
# ==== Options
|
14
14
|
#
|
15
15
|
# * <tt>:default</tt> - Sets a default value for the argument (defaults to nil).
|
16
|
-
# * <tt>:directives</tt> - The list of directives associated with the value
|
17
|
-
# (defaults to nil).
|
18
16
|
class Field::InputField < Field
|
19
17
|
include Field::TypedField
|
20
18
|
|
@@ -25,11 +23,14 @@ module Rails # :nodoc:
|
|
25
23
|
|
26
24
|
def initialize(*args, default: nil, **xargs, &block)
|
27
25
|
super(*args, **xargs, &block)
|
26
|
+
|
28
27
|
@default = default
|
28
|
+
@default = deserialize(@default) if @default.is_a?(::GQLParser::Token)
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
# Prevent input fields from being further configured using a block
|
32
|
+
def configure
|
33
|
+
raise ArgumentError, +'Input fields can\'t be further configured using blocks'
|
33
34
|
end
|
34
35
|
|
35
36
|
# Allow change the default value for the input
|
@@ -72,11 +73,11 @@ module Rails # :nodoc:
|
|
72
73
|
def validate!(*)
|
73
74
|
super if defined? super
|
74
75
|
|
75
|
-
raise ArgumentError,
|
76
|
+
raise ArgumentError, (+<<~MSG).squish unless type_klass.input_type?
|
76
77
|
The "#{type_klass.gql_name}" is not a valid input type.
|
77
78
|
MSG
|
78
79
|
|
79
|
-
raise ArgumentError,
|
80
|
+
raise ArgumentError, (+<<~MSG).squish unless default.nil? || valid_input?(default)
|
80
81
|
The given default value "#{default.inspect}" is not valid for this field.
|
81
82
|
MSG
|
82
83
|
end
|
@@ -85,7 +86,7 @@ module Rails # :nodoc:
|
|
85
86
|
|
86
87
|
# Check if the given +value+ is a valid array as input
|
87
88
|
def valid_input_array?(value, deep)
|
88
|
-
return false unless value.is_a?(Array)
|
89
|
+
return false unless value.is_a?(::Array)
|
89
90
|
|
90
91
|
value.all? do |val|
|
91
92
|
(val.nil? && nullable?) || (leaf_type? || !deep) ||
|
@@ -95,7 +96,7 @@ module Rails # :nodoc:
|
|
95
96
|
|
96
97
|
# Display the default value when it is present for inspection
|
97
98
|
def inspect_default_value
|
98
|
-
" = #{
|
99
|
+
+" = #{as_json.inspect}" if default_value?
|
99
100
|
end
|
100
101
|
end
|
101
102
|
end
|
@@ -1,11 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Rails
|
4
|
-
module GraphQL
|
5
|
-
# = GraphQL
|
3
|
+
module Rails
|
4
|
+
module GraphQL
|
5
|
+
# = GraphQL Mutation Field
|
6
6
|
#
|
7
7
|
# This is an extension of a normal output field, which just add extra
|
8
8
|
# validation and ensurance that the +perform+ step can be executed
|
9
|
+
#
|
10
|
+
# ==== Options
|
11
|
+
#
|
12
|
+
# * <tt>:call</tt> - The alternative method to call to actually perform the mutation.
|
13
|
+
# (defaults to nil).
|
9
14
|
class Field::MutationField < Field::OutputField
|
10
15
|
redefine_singleton_method(:mutation?) { true }
|
11
16
|
|
@@ -15,6 +20,34 @@ module Rails # :nodoc:
|
|
15
20
|
end
|
16
21
|
end
|
17
22
|
|
23
|
+
# Intercept the initializer to maybe set the +perform_method_name+
|
24
|
+
def initialize(*args, call: nil, **xargs, &block)
|
25
|
+
@perform_method_name = call.to_sym unless call.nil?
|
26
|
+
super(*args, **xargs, &block)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Accept changes to the perform method name through the +apply_changes+
|
30
|
+
def apply_changes(**xargs, &block)
|
31
|
+
@perform_method_name = xargs.delete(:call) if xargs.key?(:call)
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
# Allows overrides for the default bang method
|
36
|
+
def perform_method_name
|
37
|
+
if defined?(@perform_method_name)
|
38
|
+
@perform_method_name
|
39
|
+
elsif from_alternative?
|
40
|
+
:perform
|
41
|
+
else
|
42
|
+
:"#{method_name}!"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Change the schema type of the field
|
47
|
+
def schema_type
|
48
|
+
:mutation
|
49
|
+
end
|
50
|
+
|
18
51
|
# Add a block or a callable method that is executed before the resolver
|
19
52
|
# but after all the before resolve. It returns +self+ for chain purposes
|
20
53
|
def perform(*args, **xargs, &block)
|
@@ -25,8 +58,8 @@ module Rails # :nodoc:
|
|
25
58
|
# Get the performer that can be already defined or used through the
|
26
59
|
# +method_name+ if that is callable
|
27
60
|
def performer
|
28
|
-
@performer ||= callable?(
|
29
|
-
? Callback.new(self, :perform,
|
61
|
+
@performer ||= callable?(perform_method_name) \
|
62
|
+
? Callback.new(self, :perform, perform_method_name) \
|
30
63
|
: false
|
31
64
|
end
|
32
65
|
|
@@ -34,7 +67,9 @@ module Rails # :nodoc:
|
|
34
67
|
def validate!(*)
|
35
68
|
super if defined? super
|
36
69
|
|
37
|
-
|
70
|
+
binding.pry unless performer.present?
|
71
|
+
|
72
|
+
raise ValidationError, (+<<~MSG).squish unless performer.present?
|
38
73
|
The "#{gql_name}" mutation field must have a perform action through a given
|
39
74
|
block or a method named #{method_name} on #{owner.class.name}.
|
40
75
|
MSG
|
@@ -42,7 +77,7 @@ module Rails # :nodoc:
|
|
42
77
|
|
43
78
|
protected
|
44
79
|
|
45
|
-
def proxied
|
80
|
+
def proxied
|
46
81
|
super if defined? super
|
47
82
|
extend Field::MutationField::Proxied
|
48
83
|
end
|