graphql 1.11.6 → 1.13.19
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.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/generators/graphql/core.rb +3 -8
- data/lib/generators/graphql/enum_generator.rb +4 -10
- data/lib/generators/graphql/field_extractor.rb +31 -0
- data/lib/generators/graphql/input_generator.rb +50 -0
- data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
- data/lib/generators/graphql/install_generator.rb +17 -7
- data/lib/generators/graphql/interface_generator.rb +7 -7
- data/lib/generators/graphql/loader_generator.rb +1 -0
- data/lib/generators/graphql/mutation_create_generator.rb +22 -0
- data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
- data/lib/generators/graphql/mutation_generator.rb +6 -30
- data/lib/generators/graphql/mutation_update_generator.rb +22 -0
- data/lib/generators/graphql/object_generator.rb +12 -38
- data/lib/generators/graphql/orm_mutations_base.rb +40 -0
- data/lib/generators/graphql/relay.rb +63 -0
- data/lib/generators/graphql/relay_generator.rb +21 -0
- data/lib/generators/graphql/scalar_generator.rb +4 -2
- data/lib/generators/graphql/templates/base_connection.erb +8 -0
- data/lib/generators/graphql/templates/base_edge.erb +8 -0
- data/lib/generators/graphql/templates/enum.erb +5 -1
- data/lib/generators/graphql/templates/graphql_controller.erb +2 -2
- data/lib/generators/graphql/templates/input.erb +9 -0
- data/lib/generators/graphql/templates/interface.erb +4 -2
- data/lib/generators/graphql/templates/mutation.erb +1 -1
- data/lib/generators/graphql/templates/mutation_create.erb +20 -0
- data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
- data/lib/generators/graphql/templates/mutation_update.erb +21 -0
- data/lib/generators/graphql/templates/node_type.erb +9 -0
- data/lib/generators/graphql/templates/object.erb +5 -3
- data/lib/generators/graphql/templates/query_type.erb +1 -3
- data/lib/generators/graphql/templates/scalar.erb +3 -1
- data/lib/generators/graphql/templates/schema.erb +19 -34
- data/lib/generators/graphql/templates/union.erb +4 -2
- data/lib/generators/graphql/type_generator.rb +47 -10
- data/lib/generators/graphql/union_generator.rb +5 -5
- data/lib/graphql/analysis/analyze_query.rb +7 -0
- data/lib/graphql/analysis/ast/field_usage.rb +28 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +10 -14
- data/lib/graphql/analysis/ast/visitor.rb +14 -5
- data/lib/graphql/analysis/ast.rb +11 -2
- data/lib/graphql/argument.rb +1 -1
- data/lib/graphql/backtrace/inspect_result.rb +0 -1
- data/lib/graphql/backtrace/legacy_tracer.rb +56 -0
- data/lib/graphql/backtrace/table.rb +34 -3
- data/lib/graphql/backtrace/traced_error.rb +0 -1
- data/lib/graphql/backtrace/tracer.rb +40 -10
- data/lib/graphql/backtrace.rb +28 -19
- data/lib/graphql/backwards_compatibility.rb +2 -1
- data/lib/graphql/base_type.rb +6 -4
- data/lib/graphql/boolean_type.rb +1 -1
- data/lib/graphql/compatibility/execution_specification.rb +1 -0
- data/lib/graphql/compatibility/lazy_execution_specification.rb +2 -0
- data/lib/graphql/compatibility/query_parser_specification.rb +2 -0
- data/lib/graphql/compatibility/schema_parser_specification.rb +2 -0
- data/lib/graphql/dataloader/null_dataloader.rb +22 -0
- data/lib/graphql/dataloader/request.rb +19 -0
- data/lib/graphql/dataloader/request_all.rb +19 -0
- data/lib/graphql/dataloader/source.rb +155 -0
- data/lib/graphql/dataloader.rb +308 -0
- data/lib/graphql/date_encoding_error.rb +16 -0
- data/lib/graphql/define/assign_global_id_field.rb +1 -1
- data/lib/graphql/define/instance_definable.rb +48 -3
- data/lib/graphql/define/type_definer.rb +5 -5
- data/lib/graphql/deprecated_dsl.rb +18 -5
- data/lib/graphql/deprecation.rb +9 -0
- data/lib/graphql/directive/deprecated_directive.rb +1 -1
- data/lib/graphql/directive/include_directive.rb +1 -1
- data/lib/graphql/directive/skip_directive.rb +1 -1
- data/lib/graphql/directive.rb +1 -5
- data/lib/graphql/enum_type.rb +9 -3
- data/lib/graphql/execution/errors.rb +110 -7
- data/lib/graphql/execution/execute.rb +8 -1
- data/lib/graphql/execution/interpreter/arguments.rb +57 -5
- data/lib/graphql/execution/interpreter/arguments_cache.rb +49 -15
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +0 -7
- data/lib/graphql/execution/interpreter/resolve.rb +37 -25
- data/lib/graphql/execution/interpreter/runtime.rb +670 -294
- data/lib/graphql/execution/interpreter.rb +16 -16
- data/lib/graphql/execution/lazy.rb +5 -1
- data/lib/graphql/execution/lookahead.rb +2 -2
- data/lib/graphql/execution/multiplex.rb +39 -23
- data/lib/graphql/field.rb +1 -1
- data/lib/graphql/float_type.rb +1 -1
- data/lib/graphql/function.rb +4 -0
- data/lib/graphql/id_type.rb +1 -1
- data/lib/graphql/input_object_type.rb +3 -1
- data/lib/graphql/int_type.rb +1 -1
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +18 -2
- data/lib/graphql/interface_type.rb +4 -2
- data/lib/graphql/internal_representation/document.rb +2 -2
- data/lib/graphql/internal_representation/rewrite.rb +1 -1
- data/lib/graphql/introspection/directive_location_enum.rb +2 -2
- data/lib/graphql/introspection/directive_type.rb +11 -5
- data/lib/graphql/introspection/entry_points.rb +2 -2
- data/lib/graphql/introspection/enum_value_type.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +3 -3
- data/lib/graphql/introspection/input_value_type.rb +10 -4
- data/lib/graphql/introspection/schema_type.rb +10 -5
- data/lib/graphql/introspection/type_type.rb +18 -12
- data/lib/graphql/introspection.rb +5 -2
- data/lib/graphql/invalid_null_error.rb +1 -1
- data/lib/graphql/language/block_string.rb +2 -6
- data/lib/graphql/language/cache.rb +37 -0
- data/lib/graphql/language/document_from_schema_definition.rb +60 -26
- data/lib/graphql/language/lexer.rb +50 -28
- data/lib/graphql/language/lexer.rl +2 -4
- data/lib/graphql/language/nodes.rb +14 -4
- data/lib/graphql/language/parser.rb +856 -825
- data/lib/graphql/language/parser.y +28 -11
- data/lib/graphql/language/printer.rb +10 -1
- data/lib/graphql/language/sanitized_printer.rb +5 -5
- data/lib/graphql/language/token.rb +0 -4
- data/lib/graphql/language.rb +1 -0
- data/lib/graphql/name_validator.rb +0 -4
- data/lib/graphql/object_type.rb +4 -4
- data/lib/graphql/pagination/active_record_relation_connection.rb +47 -3
- data/lib/graphql/pagination/connection.rb +19 -1
- data/lib/graphql/pagination/connections.rb +45 -30
- data/lib/graphql/pagination/relation_connection.rb +69 -28
- data/lib/graphql/parse_error.rb +0 -1
- data/lib/graphql/query/arguments.rb +2 -2
- data/lib/graphql/query/arguments_cache.rb +1 -2
- data/lib/graphql/query/context.rb +22 -4
- data/lib/graphql/query/executor.rb +0 -1
- data/lib/graphql/query/input_validation_result.rb +9 -0
- data/lib/graphql/query/literal_input.rb +1 -1
- data/lib/graphql/query/null_context.rb +21 -9
- data/lib/graphql/query/serial_execution/field_resolution.rb +1 -1
- data/lib/graphql/query/serial_execution.rb +1 -0
- data/lib/graphql/query/validation_pipeline.rb +3 -4
- data/lib/graphql/query/variable_validation_error.rb +3 -3
- data/lib/graphql/query/variables.rb +35 -4
- data/lib/graphql/query.rb +20 -8
- data/lib/graphql/railtie.rb +9 -1
- data/lib/graphql/rake_task.rb +3 -0
- data/lib/graphql/relay/array_connection.rb +2 -2
- data/lib/graphql/relay/base_connection.rb +7 -0
- data/lib/graphql/relay/connection_instrumentation.rb +4 -4
- data/lib/graphql/relay/connection_type.rb +16 -3
- data/lib/graphql/relay/edges_instrumentation.rb +0 -1
- data/lib/graphql/relay/global_id_resolve.rb +1 -2
- data/lib/graphql/relay/mutation.rb +2 -1
- data/lib/graphql/relay/node.rb +3 -0
- data/lib/graphql/relay/page_info.rb +1 -1
- data/lib/graphql/relay/range_add.rb +14 -5
- data/lib/graphql/relay/type_extensions.rb +2 -0
- data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
- data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
- data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
- data/lib/graphql/rubocop.rb +4 -0
- data/lib/graphql/scalar_type.rb +3 -1
- data/lib/graphql/schema/addition.rb +247 -0
- data/lib/graphql/schema/argument.rb +177 -21
- data/lib/graphql/schema/build_from_definition.rb +150 -55
- data/lib/graphql/schema/default_type_error.rb +2 -0
- data/lib/graphql/schema/directive/feature.rb +1 -1
- data/lib/graphql/schema/directive/flagged.rb +57 -0
- data/lib/graphql/schema/directive/include.rb +1 -1
- data/lib/graphql/schema/directive/skip.rb +1 -1
- data/lib/graphql/schema/directive/transform.rb +14 -2
- data/lib/graphql/schema/directive.rb +103 -4
- data/lib/graphql/schema/enum.rb +72 -11
- data/lib/graphql/schema/enum_value.rb +18 -6
- data/lib/graphql/schema/field/connection_extension.rb +4 -2
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +332 -111
- data/lib/graphql/schema/field_extension.rb +89 -2
- data/lib/graphql/schema/find_inherited_value.rb +4 -1
- data/lib/graphql/schema/finder.rb +5 -5
- data/lib/graphql/schema/input_object.rb +79 -55
- data/lib/graphql/schema/interface.rb +12 -20
- data/lib/graphql/schema/introspection_system.rb +1 -1
- data/lib/graphql/schema/list.rb +21 -4
- data/lib/graphql/schema/loader.rb +11 -0
- data/lib/graphql/schema/member/accepts_definition.rb +15 -3
- data/lib/graphql/schema/member/base_dsl_methods.rb +5 -16
- data/lib/graphql/schema/member/build_type.rb +4 -7
- data/lib/graphql/schema/member/cached_graphql_definition.rb +29 -2
- data/lib/graphql/schema/member/has_arguments.rb +166 -74
- data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
- data/lib/graphql/schema/member/has_directives.rb +98 -0
- data/lib/graphql/schema/member/has_fields.rb +77 -22
- data/lib/graphql/schema/member/has_interfaces.rb +100 -0
- data/lib/graphql/schema/member/has_validators.rb +31 -0
- data/lib/graphql/schema/member/instrumentation.rb +0 -1
- data/lib/graphql/schema/member/type_system_helpers.rb +1 -1
- data/lib/graphql/schema/member/validates_input.rb +2 -2
- data/lib/graphql/schema/member.rb +5 -0
- data/lib/graphql/schema/middleware_chain.rb +1 -1
- data/lib/graphql/schema/non_null.rb +9 -3
- data/lib/graphql/schema/object.rb +40 -80
- data/lib/graphql/schema/printer.rb +16 -20
- data/lib/graphql/schema/relay_classic_mutation.rb +38 -4
- data/lib/graphql/schema/resolver/has_payload_type.rb +29 -2
- data/lib/graphql/schema/resolver.rb +110 -64
- data/lib/graphql/schema/scalar.rb +18 -2
- data/lib/graphql/schema/subscription.rb +55 -9
- data/lib/graphql/schema/timeout_middleware.rb +3 -1
- data/lib/graphql/schema/traversal.rb +1 -1
- data/lib/graphql/schema/type_expression.rb +1 -1
- data/lib/graphql/schema/type_membership.rb +18 -4
- data/lib/graphql/schema/union.rb +8 -1
- data/lib/graphql/schema/validation.rb +4 -2
- data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
- data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
- data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
- data/lib/graphql/schema/validator/format_validator.rb +48 -0
- data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
- data/lib/graphql/schema/validator/length_validator.rb +59 -0
- data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
- data/lib/graphql/schema/validator/required_validator.rb +82 -0
- data/lib/graphql/schema/validator.rb +171 -0
- data/lib/graphql/schema/warden.rb +126 -53
- data/lib/graphql/schema.rb +262 -281
- data/lib/graphql/static_validation/all_rules.rb +2 -0
- data/lib/graphql/static_validation/base_visitor.rb +9 -6
- data/lib/graphql/static_validation/definition_dependencies.rb +0 -1
- data/lib/graphql/static_validation/error.rb +3 -1
- data/lib/graphql/static_validation/literal_validator.rb +1 -1
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +4 -2
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +6 -2
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -2
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +90 -47
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
- data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
- data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
- data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -2
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +5 -5
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +14 -8
- data/lib/graphql/static_validation/validation_context.rb +12 -2
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +41 -10
- data/lib/graphql/static_validation.rb +1 -0
- data/lib/graphql/string_encoding_error.rb +13 -3
- data/lib/graphql/string_type.rb +1 -1
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +39 -8
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +0 -3
- data/lib/graphql/subscriptions/event.rb +68 -32
- data/lib/graphql/subscriptions/instrumentation.rb +0 -1
- data/lib/graphql/subscriptions/serialize.rb +34 -5
- data/lib/graphql/subscriptions/subscription_root.rb +1 -1
- data/lib/graphql/subscriptions.rb +34 -39
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -21
- data/lib/graphql/tracing/appoptics_tracing.rb +3 -1
- data/lib/graphql/tracing/appsignal_tracing.rb +15 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +24 -2
- data/lib/graphql/tracing/notifications_tracing.rb +59 -0
- data/lib/graphql/tracing/platform_tracing.rb +24 -12
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
- data/lib/graphql/tracing/skylight_tracing.rb +1 -1
- data/lib/graphql/tracing.rb +2 -2
- data/lib/graphql/types/big_int.rb +5 -1
- data/lib/graphql/types/int.rb +10 -3
- data/lib/graphql/types/iso_8601_date.rb +13 -5
- data/lib/graphql/types/iso_8601_date_time.rb +8 -1
- data/lib/graphql/types/relay/base_connection.rb +6 -91
- data/lib/graphql/types/relay/base_edge.rb +2 -34
- data/lib/graphql/types/relay/connection_behaviors.rb +174 -0
- data/lib/graphql/types/relay/default_relay.rb +31 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +64 -0
- data/lib/graphql/types/relay/has_node_field.rb +41 -0
- data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
- data/lib/graphql/types/relay/node.rb +2 -4
- data/lib/graphql/types/relay/node_behaviors.rb +15 -0
- data/lib/graphql/types/relay/node_field.rb +3 -22
- data/lib/graphql/types/relay/nodes_field.rb +16 -18
- data/lib/graphql/types/relay/page_info.rb +2 -14
- data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
- data/lib/graphql/types/relay.rb +11 -3
- data/lib/graphql/types/string.rb +8 -2
- data/lib/graphql/unauthorized_error.rb +1 -1
- data/lib/graphql/union_type.rb +3 -1
- data/lib/graphql/upgrader/member.rb +1 -0
- data/lib/graphql/upgrader/schema.rb +1 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +68 -37
- data/readme.md +3 -6
- metadata +83 -113
- data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
- data/lib/graphql/types/relay/base_field.rb +0 -22
- data/lib/graphql/types/relay/base_interface.rb +0 -29
- data/lib/graphql/types/relay/base_object.rb +0 -26
- /data/lib/generators/graphql/{templates → install/templates}/base_mutation.erb +0 -0
- /data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +0 -0
@@ -22,7 +22,7 @@ module GraphQL
|
|
22
22
|
#
|
23
23
|
class RelayClassicMutation < GraphQL::Schema::Mutation
|
24
24
|
# The payload should always include this field
|
25
|
-
field(:client_mutation_id, String, "A unique identifier for the client performing the mutation."
|
25
|
+
field(:client_mutation_id, String, "A unique identifier for the client performing the mutation.")
|
26
26
|
# Relay classic default:
|
27
27
|
null(true)
|
28
28
|
|
@@ -81,6 +81,31 @@ module GraphQL
|
|
81
81
|
end
|
82
82
|
|
83
83
|
class << self
|
84
|
+
|
85
|
+
# Also apply this argument to the input type:
|
86
|
+
def argument(*args, **kwargs, &block)
|
87
|
+
it = input_type # make sure any inherited arguments are already added to it
|
88
|
+
arg = super
|
89
|
+
|
90
|
+
# This definition might be overriding something inherited;
|
91
|
+
# if it is, remove the inherited definition so it's not confused at runtime as having multiple definitions
|
92
|
+
prev_args = it.own_arguments[arg.graphql_name]
|
93
|
+
case prev_args
|
94
|
+
when GraphQL::Schema::Argument
|
95
|
+
if prev_args.owner != self
|
96
|
+
it.own_arguments.delete(arg.graphql_name)
|
97
|
+
end
|
98
|
+
when Array
|
99
|
+
prev_args.reject! { |a| a.owner != self }
|
100
|
+
if prev_args.empty?
|
101
|
+
it.own_arguments.delete(arg.graphql_name)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it.add_argument(arg)
|
106
|
+
arg
|
107
|
+
end
|
108
|
+
|
84
109
|
# The base class for generated input object types
|
85
110
|
# @param new_class [Class] The base class to use for generating input object definitions
|
86
111
|
# @return [Class] The base class for this mutation's generated input object (default is {GraphQL::Schema::InputObject})
|
@@ -105,7 +130,7 @@ module GraphQL
|
|
105
130
|
sig = super
|
106
131
|
# Arguments were added at the root, but they should be nested
|
107
132
|
sig[:arguments].clear
|
108
|
-
sig[:arguments][:input] = { type: input_type, required: true }
|
133
|
+
sig[:arguments][:input] = { type: input_type, required: true, description: "Parameters for #{graphql_name}" }
|
109
134
|
sig
|
110
135
|
end
|
111
136
|
|
@@ -115,20 +140,29 @@ module GraphQL
|
|
115
140
|
# To customize how input objects are generated, override this method
|
116
141
|
# @return [Class] a subclass of {.input_object_class}
|
117
142
|
def generate_input_type
|
118
|
-
mutation_args =
|
143
|
+
mutation_args = all_argument_definitions
|
119
144
|
mutation_name = graphql_name
|
120
145
|
mutation_class = self
|
121
146
|
Class.new(input_object_class) do
|
122
147
|
graphql_name("#{mutation_name}Input")
|
123
148
|
description("Autogenerated input type of #{mutation_name}")
|
124
149
|
mutation(mutation_class)
|
125
|
-
|
150
|
+
# these might be inherited:
|
151
|
+
mutation_args.each do |arg|
|
126
152
|
add_argument(arg)
|
127
153
|
end
|
128
154
|
argument :client_mutation_id, String, "A unique identifier for the client performing the mutation.", required: false
|
129
155
|
end
|
130
156
|
end
|
131
157
|
end
|
158
|
+
|
159
|
+
private
|
160
|
+
|
161
|
+
def authorize_arguments(args, values)
|
162
|
+
# remove the `input` wrapper to match values
|
163
|
+
input_args = args["input"].type.unwrap.arguments(context)
|
164
|
+
super(input_args, values)
|
165
|
+
end
|
132
166
|
end
|
133
167
|
end
|
134
168
|
end
|
@@ -38,12 +38,39 @@ module GraphQL
|
|
38
38
|
# @return [Class]
|
39
39
|
def object_class(new_class = nil)
|
40
40
|
if new_class
|
41
|
+
if defined?(@payload_type)
|
42
|
+
raise "Can't configure `object_class(...)` after the payload type has already been initialized. Move this configuration higher up the class definition."
|
43
|
+
end
|
41
44
|
@object_class = new_class
|
42
45
|
else
|
43
46
|
@object_class || find_inherited_value(:object_class, GraphQL::Schema::Object)
|
44
47
|
end
|
45
48
|
end
|
46
49
|
|
50
|
+
NO_INTERFACES = [].freeze
|
51
|
+
|
52
|
+
def field(*args, **kwargs, &block)
|
53
|
+
pt = payload_type # make sure it's initialized with any inherited fields
|
54
|
+
field_defn = super
|
55
|
+
|
56
|
+
# Remove any inherited fields to avoid false conflicts at runtime
|
57
|
+
prev_fields = pt.own_fields[field_defn.graphql_name]
|
58
|
+
case prev_fields
|
59
|
+
when GraphQL::Schema::Field
|
60
|
+
if prev_fields.owner != self
|
61
|
+
pt.own_fields.delete(field_defn.graphql_name)
|
62
|
+
end
|
63
|
+
when Array
|
64
|
+
prev_fields.reject! { |f| f.owner != self }
|
65
|
+
if prev_fields.empty?
|
66
|
+
pt.own_fields.delete(field_defn.graphql_name)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
pt.add_field(field_defn, method_conflict_warning: false)
|
71
|
+
field_defn
|
72
|
+
end
|
73
|
+
|
47
74
|
private
|
48
75
|
|
49
76
|
# Build a subclass of {.object_class} based on `self`.
|
@@ -51,11 +78,11 @@ module GraphQL
|
|
51
78
|
# Override this hook to customize return type generation.
|
52
79
|
def generate_payload_type
|
53
80
|
resolver_name = graphql_name
|
54
|
-
resolver_fields =
|
81
|
+
resolver_fields = all_field_definitions
|
55
82
|
Class.new(object_class) do
|
56
83
|
graphql_name("#{resolver_name}Payload")
|
57
84
|
description("Autogenerated return type of #{resolver_name}")
|
58
|
-
resolver_fields.each do |
|
85
|
+
resolver_fields.each do |f|
|
59
86
|
# Reattach the already-defined field here
|
60
87
|
# (The field's `.owner` will still point to the mutation, not the object type, I think)
|
61
88
|
# Don't re-warn about a method conflict. Since this type is generated, it should be fixed in the resolver instead.
|
@@ -24,10 +24,11 @@ module GraphQL
|
|
24
24
|
# Really we only need description from here, but:
|
25
25
|
extend Schema::Member::BaseDSLMethods
|
26
26
|
extend GraphQL::Schema::Member::HasArguments
|
27
|
+
extend GraphQL::Schema::Member::HasValidators
|
27
28
|
include Schema::Member::HasPath
|
28
29
|
extend Schema::Member::HasPath
|
29
30
|
|
30
|
-
# @param object [Object]
|
31
|
+
# @param object [Object] The application object that this field is being resolved on
|
31
32
|
# @param context [GraphQL::Query::Context]
|
32
33
|
# @param field [GraphQL::Schema::Field]
|
33
34
|
def initialize(object:, context:, field:)
|
@@ -36,10 +37,9 @@ module GraphQL
|
|
36
37
|
@field = field
|
37
38
|
# Since this hash is constantly rebuilt, cache it for this call
|
38
39
|
@arguments_by_keyword = {}
|
39
|
-
self.class.arguments.each do |name, arg|
|
40
|
+
self.class.arguments(context).each do |name, arg|
|
40
41
|
@arguments_by_keyword[arg.keyword] = arg
|
41
42
|
end
|
42
|
-
@arguments_loads_as_type = self.class.arguments_loads_as_type
|
43
43
|
@prepared_arguments = nil
|
44
44
|
end
|
45
45
|
|
@@ -49,6 +49,11 @@ module GraphQL
|
|
49
49
|
# @return [GraphQL::Query::Context]
|
50
50
|
attr_reader :context
|
51
51
|
|
52
|
+
# @return [GraphQL::Dataloader]
|
53
|
+
def dataloader
|
54
|
+
context.dataloader
|
55
|
+
end
|
56
|
+
|
52
57
|
# @return [GraphQL::Schema::Field]
|
53
58
|
attr_reader :field
|
54
59
|
|
@@ -80,6 +85,7 @@ module GraphQL
|
|
80
85
|
load_arguments_val = load_arguments(args)
|
81
86
|
context.schema.after_lazy(load_arguments_val) do |loaded_args|
|
82
87
|
@prepared_arguments = loaded_args
|
88
|
+
Schema::Validator.validate!(self.class.validators, object, context, loaded_args, as: @field)
|
83
89
|
# Then call `authorized?`, which may raise or may return a lazy object
|
84
90
|
authorized_val = if loaded_args.any?
|
85
91
|
authorized?(**loaded_args)
|
@@ -103,7 +109,7 @@ module GraphQL
|
|
103
109
|
public_send(self.class.resolve_method)
|
104
110
|
end
|
105
111
|
else
|
106
|
-
|
112
|
+
raise GraphQL::UnauthorizedFieldError.new(context: context, object: object, type: field.owner, field: field)
|
107
113
|
end
|
108
114
|
end
|
109
115
|
end
|
@@ -139,7 +145,25 @@ module GraphQL
|
|
139
145
|
# @raise [GraphQL::UnauthorizedError] To signal an authorization failure
|
140
146
|
# @return [Boolean, early_return_data] If `false`, execution will stop (and `early_return_data` will be returned instead, if present.)
|
141
147
|
def authorized?(**inputs)
|
142
|
-
self.class
|
148
|
+
arg_owner = @field # || self.class
|
149
|
+
args = arg_owner.arguments(context)
|
150
|
+
authorize_arguments(args, inputs)
|
151
|
+
end
|
152
|
+
|
153
|
+
# Called when an object loaded by `loads:` fails the `.authorized?` check for its resolved GraphQL object type.
|
154
|
+
#
|
155
|
+
# By default, the error is re-raised and passed along to {{Schema.unauthorized_object}}.
|
156
|
+
#
|
157
|
+
# Any value returned here will be used _instead of_ of the loaded object.
|
158
|
+
# @param err [GraphQL::UnauthorizedError]
|
159
|
+
def unauthorized_object(err)
|
160
|
+
raise err
|
161
|
+
end
|
162
|
+
|
163
|
+
private
|
164
|
+
|
165
|
+
def authorize_arguments(args, inputs)
|
166
|
+
args.each_value do |argument|
|
143
167
|
arg_keyword = argument.keyword
|
144
168
|
if inputs.key?(arg_keyword) && !(arg_value = inputs[arg_keyword]).nil? && (arg_value != argument.default_value)
|
145
169
|
arg_auth, err = argument.authorized?(self, arg_value, context)
|
@@ -154,8 +178,6 @@ module GraphQL
|
|
154
178
|
end
|
155
179
|
end
|
156
180
|
|
157
|
-
private
|
158
|
-
|
159
181
|
def load_arguments(args)
|
160
182
|
prepared_args = {}
|
161
183
|
prepare_lazies = []
|
@@ -163,18 +185,14 @@ module GraphQL
|
|
163
185
|
args.each do |key, value|
|
164
186
|
arg_defn = @arguments_by_keyword[key]
|
165
187
|
if arg_defn
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
if context.schema.lazy?(prepped_value)
|
171
|
-
prepare_lazies << context.schema.after_lazy(prepped_value) do |finished_prepped_value|
|
172
|
-
prepared_args[key] = finished_prepped_value
|
173
|
-
end
|
188
|
+
prepped_value = prepared_args[key] = arg_defn.load_and_authorize_value(self, value, context)
|
189
|
+
if context.schema.lazy?(prepped_value)
|
190
|
+
prepare_lazies << context.schema.after_lazy(prepped_value) do |finished_prepped_value|
|
191
|
+
prepared_args[key] = finished_prepped_value
|
174
192
|
end
|
175
193
|
end
|
176
194
|
else
|
177
|
-
#
|
195
|
+
# these are `extras:`
|
178
196
|
prepared_args[key] = value
|
179
197
|
end
|
180
198
|
end
|
@@ -187,8 +205,8 @@ module GraphQL
|
|
187
205
|
end
|
188
206
|
end
|
189
207
|
|
190
|
-
def
|
191
|
-
|
208
|
+
def get_argument(name, context = GraphQL::Query::NullContext)
|
209
|
+
self.class.get_argument(name, context)
|
192
210
|
end
|
193
211
|
|
194
212
|
class << self
|
@@ -211,8 +229,10 @@ module GraphQL
|
|
211
229
|
own_extras + (superclass.respond_to?(:extras) ? superclass.extras : [])
|
212
230
|
end
|
213
231
|
|
214
|
-
#
|
215
|
-
#
|
232
|
+
# If `true` (default), then the return type for this resolver will be nullable.
|
233
|
+
# If `false`, then the return type is non-null.
|
234
|
+
#
|
235
|
+
# @see #type which sets the return type of this field and accepts a `null:` option
|
216
236
|
# @param allow_null [Boolean] Whether or not the response can be null
|
217
237
|
def null(allow_null = nil)
|
218
238
|
if !allow_null.nil?
|
@@ -269,19 +289,65 @@ module GraphQL
|
|
269
289
|
end
|
270
290
|
end
|
271
291
|
|
292
|
+
# Get or set the `max_page_size:` which will be configured for fields using this resolver
|
293
|
+
# (`nil` means "unlimited max page size".)
|
294
|
+
# @param max_page_size [Integer, nil] Set a new value
|
295
|
+
# @return [Integer, nil] The `max_page_size` assigned to fields that use this resolver
|
296
|
+
def max_page_size(new_max_page_size = :not_given)
|
297
|
+
if new_max_page_size != :not_given
|
298
|
+
@max_page_size = new_max_page_size
|
299
|
+
elsif defined?(@max_page_size)
|
300
|
+
@max_page_size
|
301
|
+
elsif superclass.respond_to?(:max_page_size)
|
302
|
+
superclass.max_page_size
|
303
|
+
else
|
304
|
+
nil
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
# @return [Boolean] `true` if this resolver or a superclass has an assigned `max_page_size`
|
309
|
+
def has_max_page_size?
|
310
|
+
defined?(@max_page_size) || (superclass.respond_to?(:has_max_page_size?) && superclass.has_max_page_size?)
|
311
|
+
end
|
312
|
+
|
272
313
|
def field_options
|
273
|
-
|
314
|
+
|
315
|
+
all_args = {}
|
316
|
+
all_argument_definitions.each do |arg|
|
317
|
+
if (prev_entry = all_args[arg.graphql_name])
|
318
|
+
if prev_entry.is_a?(Array)
|
319
|
+
prev_entry << arg
|
320
|
+
else
|
321
|
+
all_args[arg.graphql_name] = [prev_entry, arg]
|
322
|
+
end
|
323
|
+
else
|
324
|
+
all_args[arg.graphql_name] = arg
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
field_opts = {
|
274
329
|
type: type_expr,
|
275
330
|
description: description,
|
276
331
|
extras: extras,
|
277
332
|
resolver_method: :resolve_with_support,
|
278
333
|
resolver_class: self,
|
279
|
-
arguments:
|
334
|
+
arguments: all_args,
|
280
335
|
null: null,
|
281
336
|
complexity: complexity,
|
282
|
-
extensions: extensions,
|
283
337
|
broadcastable: broadcastable?,
|
284
338
|
}
|
339
|
+
|
340
|
+
# If there aren't any, then the returned array is `[].freeze`,
|
341
|
+
# but passing that along breaks some user code.
|
342
|
+
if (exts = extensions).any?
|
343
|
+
field_opts[:extensions] = exts
|
344
|
+
end
|
345
|
+
|
346
|
+
if has_max_page_size?
|
347
|
+
field_opts[:max_page_size] = max_page_size
|
348
|
+
end
|
349
|
+
|
350
|
+
field_opts
|
285
351
|
end
|
286
352
|
|
287
353
|
# A non-normalized type configuration, without `null` applied
|
@@ -293,63 +359,43 @@ module GraphQL
|
|
293
359
|
# also add some preparation hook methods which will be used for this argument
|
294
360
|
# @see {GraphQL::Schema::Argument#initialize} for the signature
|
295
361
|
def argument(*args, **kwargs, &block)
|
296
|
-
loads = kwargs[:loads]
|
297
362
|
# Use `from_resolver: true` to short-circuit the InputObject's own `loads:` implementation
|
298
363
|
# so that we can support `#load_{x}` methods below.
|
299
|
-
|
300
|
-
own_arguments_loads_as_type[arg_defn.keyword] = loads if loads
|
301
|
-
|
302
|
-
if loads && arg_defn.type.list?
|
303
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
304
|
-
def load_#{arg_defn.keyword}(values)
|
305
|
-
argument = @arguments_by_keyword[:#{arg_defn.keyword}]
|
306
|
-
lookup_as_type = @arguments_loads_as_type[:#{arg_defn.keyword}]
|
307
|
-
context.schema.after_lazy(values) do |values2|
|
308
|
-
GraphQL::Execution::Lazy.all(values2.map { |value| load_application_object(argument, lookup_as_type, value, context) })
|
309
|
-
end
|
310
|
-
end
|
311
|
-
RUBY
|
312
|
-
elsif loads
|
313
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
314
|
-
def load_#{arg_defn.keyword}(value)
|
315
|
-
argument = @arguments_by_keyword[:#{arg_defn.keyword}]
|
316
|
-
lookup_as_type = @arguments_loads_as_type[:#{arg_defn.keyword}]
|
317
|
-
load_application_object(argument, lookup_as_type, value, context)
|
318
|
-
end
|
319
|
-
RUBY
|
320
|
-
else
|
321
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
322
|
-
def load_#{arg_defn.keyword}(value)
|
323
|
-
value
|
324
|
-
end
|
325
|
-
RUBY
|
326
|
-
end
|
327
|
-
|
328
|
-
arg_defn
|
329
|
-
end
|
330
|
-
|
331
|
-
# @api private
|
332
|
-
def arguments_loads_as_type
|
333
|
-
inherited_lookups = superclass.respond_to?(:arguments_loads_as_type) ? superclass.arguments_loads_as_type : {}
|
334
|
-
inherited_lookups.merge(own_arguments_loads_as_type)
|
364
|
+
super(*args, from_resolver: true, **kwargs)
|
335
365
|
end
|
336
366
|
|
337
367
|
# Registers new extension
|
338
368
|
# @param extension [Class] Extension class
|
339
369
|
# @param options [Hash] Optional extension options
|
340
370
|
def extension(extension, **options)
|
341
|
-
|
371
|
+
@own_extensions ||= []
|
372
|
+
@own_extensions << {extension => options}
|
342
373
|
end
|
343
374
|
|
344
375
|
# @api private
|
345
376
|
def extensions
|
346
|
-
|
377
|
+
own_exts = @own_extensions
|
378
|
+
# Jump through some hoops to avoid creating arrays when we don't actually need them
|
379
|
+
if superclass.respond_to?(:extensions)
|
380
|
+
s_exts = superclass.extensions
|
381
|
+
if own_exts
|
382
|
+
if s_exts.any?
|
383
|
+
own_exts + s_exts
|
384
|
+
else
|
385
|
+
own_exts
|
386
|
+
end
|
387
|
+
else
|
388
|
+
s_exts
|
389
|
+
end
|
390
|
+
else
|
391
|
+
own_exts || EMPTY_ARRAY
|
392
|
+
end
|
347
393
|
end
|
348
394
|
|
349
395
|
private
|
350
396
|
|
351
|
-
def
|
352
|
-
@
|
397
|
+
def own_extensions
|
398
|
+
@own_extensions
|
353
399
|
end
|
354
400
|
end
|
355
401
|
end
|
@@ -14,6 +14,8 @@ module GraphQL
|
|
14
14
|
val
|
15
15
|
end
|
16
16
|
|
17
|
+
prepend Schema::Member::CachedGraphQLDefinition::DeprecatedToGraphQL
|
18
|
+
|
17
19
|
def to_graphql
|
18
20
|
type_defn = GraphQL::ScalarType.new
|
19
21
|
type_defn.name = graphql_name
|
@@ -30,6 +32,18 @@ module GraphQL
|
|
30
32
|
GraphQL::TypeKinds::SCALAR
|
31
33
|
end
|
32
34
|
|
35
|
+
def specified_by_url(new_url = nil)
|
36
|
+
if new_url
|
37
|
+
@specified_by_url = new_url
|
38
|
+
elsif defined?(@specified_by_url)
|
39
|
+
@specified_by_url
|
40
|
+
elsif superclass.respond_to?(:specified_by_url)
|
41
|
+
superclass.specified_by_url
|
42
|
+
else
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
33
47
|
def default_scalar(is_default = nil)
|
34
48
|
if !is_default.nil?
|
35
49
|
@default_scalar = is_default
|
@@ -41,10 +55,12 @@ module GraphQL
|
|
41
55
|
@default_scalar ||= false
|
42
56
|
end
|
43
57
|
|
44
|
-
def validate_non_null_input(value, ctx)
|
58
|
+
def validate_non_null_input(value, ctx, max_errors: nil)
|
45
59
|
result = Query::InputValidationResult.new
|
46
60
|
coerced_result = begin
|
47
|
-
|
61
|
+
ctx.query.with_error_handling do
|
62
|
+
coerce_input(value, ctx)
|
63
|
+
end
|
48
64
|
rescue GraphQL::CoercionError => err
|
49
65
|
err
|
50
66
|
end
|
@@ -14,7 +14,7 @@ module GraphQL
|
|
14
14
|
class Subscription < GraphQL::Schema::Resolver
|
15
15
|
extend GraphQL::Schema::Resolver::HasPayloadType
|
16
16
|
extend GraphQL::Schema::Member::HasFields
|
17
|
-
|
17
|
+
NO_UPDATE = :no_update
|
18
18
|
# The generated payload type is required; If there's no payload,
|
19
19
|
# propagate null.
|
20
20
|
null false
|
@@ -25,6 +25,22 @@ module GraphQL
|
|
25
25
|
@mode = context.query.subscription_update? ? :update : :subscribe
|
26
26
|
end
|
27
27
|
|
28
|
+
def resolve_with_support(**args)
|
29
|
+
result = nil
|
30
|
+
unsubscribed = true
|
31
|
+
catch :graphql_subscription_unsubscribed do
|
32
|
+
result = super
|
33
|
+
unsubscribed = false
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
if unsubscribed
|
38
|
+
context.skip
|
39
|
+
else
|
40
|
+
result
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
28
44
|
# Implement the {Resolve} API
|
29
45
|
def resolve(**args)
|
30
46
|
# Dispatch based on `@mode`, which will raise a `NoMethodError` if we ever
|
@@ -42,11 +58,9 @@ module GraphQL
|
|
42
58
|
end
|
43
59
|
end
|
44
60
|
|
45
|
-
#
|
61
|
+
# The default implementation returns nothing on subscribe.
|
46
62
|
# Override it to return an object or
|
47
|
-
# `:no_response` to return nothing.
|
48
|
-
#
|
49
|
-
# The default is `:no_response`.
|
63
|
+
# `:no_response` to (explicitly) return nothing.
|
50
64
|
def subscribe(args = {})
|
51
65
|
:no_response
|
52
66
|
end
|
@@ -54,15 +68,16 @@ module GraphQL
|
|
54
68
|
# Wrap the user-provided `#update` hook
|
55
69
|
def resolve_update(**args)
|
56
70
|
ret_val = args.any? ? update(**args) : update
|
57
|
-
if ret_val ==
|
58
|
-
|
71
|
+
if ret_val == NO_UPDATE
|
72
|
+
context.namespace(:subscriptions)[:no_update] = true
|
73
|
+
context.skip
|
59
74
|
else
|
60
75
|
ret_val
|
61
76
|
end
|
62
77
|
end
|
63
78
|
|
64
79
|
# The default implementation returns the root object.
|
65
|
-
# Override it to return
|
80
|
+
# Override it to return {NO_UPDATE} if you want to
|
66
81
|
# skip updates sometimes. Or override it to return a different object.
|
67
82
|
def update(args = {})
|
68
83
|
object
|
@@ -80,6 +95,7 @@ module GraphQL
|
|
80
95
|
|
81
96
|
# Call this to halt execution and remove this subscription from the system
|
82
97
|
def unsubscribe
|
98
|
+
context.namespace(:subscriptions)[:unsubscribed] = true
|
83
99
|
throw :graphql_subscription_unsubscribed
|
84
100
|
end
|
85
101
|
|
@@ -87,10 +103,12 @@ module GraphQL
|
|
87
103
|
# Call this method to provide a new subscription_scope; OR
|
88
104
|
# call it without an argument to get the subscription_scope
|
89
105
|
# @param new_scope [Symbol]
|
106
|
+
# @param optional [Boolean] If true, then don't require `scope:` to be provided to updates to this subscription.
|
90
107
|
# @return [Symbol]
|
91
|
-
def self.subscription_scope(new_scope = READING_SCOPE)
|
108
|
+
def self.subscription_scope(new_scope = READING_SCOPE, optional: false)
|
92
109
|
if new_scope != READING_SCOPE
|
93
110
|
@subscription_scope = new_scope
|
111
|
+
@subscription_scope_optional = optional
|
94
112
|
elsif defined?(@subscription_scope)
|
95
113
|
@subscription_scope
|
96
114
|
else
|
@@ -98,6 +116,34 @@ module GraphQL
|
|
98
116
|
end
|
99
117
|
end
|
100
118
|
|
119
|
+
def self.subscription_scope_optional?
|
120
|
+
if defined?(@subscription_scope_optional)
|
121
|
+
@subscription_scope_optional
|
122
|
+
else
|
123
|
+
find_inherited_value(:subscription_scope_optional, false)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# This is called during initial subscription to get a "name" for this subscription.
|
128
|
+
# Later, when `.trigger` is called, this will be called again to build another "name".
|
129
|
+
# Any subscribers with matching topic will begin the update flow.
|
130
|
+
#
|
131
|
+
# The default implementation creates a string using the field name, subscription scope, and argument keys and values.
|
132
|
+
# In that implementation, only `.trigger` calls with _exact matches_ result in updates to subscribers.
|
133
|
+
#
|
134
|
+
# To implement a filtered stream-type subscription flow, override this method to return a string with field name and subscription scope.
|
135
|
+
# Then, implement {#update} to compare its arguments to the current `object` and return {NO_UPDATE} when an
|
136
|
+
# update should be filtered out.
|
137
|
+
#
|
138
|
+
# @see {#update} for how to skip updates when an event comes with a matching topic.
|
139
|
+
# @param arguments [Hash<String => Object>] The arguments for this topic, in GraphQL-style (camelized strings)
|
140
|
+
# @param field [GraphQL::Schema::Field]
|
141
|
+
# @param scope [Object, nil] A value corresponding to `.trigger(... scope:)` (for updates) or the `subscription_scope` found in `context` (for initial subscriptions).
|
142
|
+
# @return [String] An identifier corresponding to a stream of updates
|
143
|
+
def self.topic_for(arguments:, field:, scope:)
|
144
|
+
Subscriptions::Serialize.dump_recursive([scope, field.graphql_name, arguments])
|
145
|
+
end
|
146
|
+
|
101
147
|
# Overriding Resolver#field_options to include subscription_scope
|
102
148
|
def self.field_options
|
103
149
|
super.merge(
|
@@ -23,12 +23,14 @@ module GraphQL
|
|
23
23
|
# Bugsnag.notify(timeout_error, {query_string: query_ctx.query.query_string})
|
24
24
|
# end
|
25
25
|
#
|
26
|
+
# @api deprecated
|
27
|
+
# @see Schema::Timeout
|
26
28
|
class TimeoutMiddleware
|
27
29
|
# @param max_seconds [Numeric] how many seconds the query should be allowed to resolve new fields
|
28
30
|
def initialize(max_seconds:, context_key: nil, &block)
|
29
31
|
@max_seconds = max_seconds
|
30
32
|
if context_key
|
31
|
-
warn("TimeoutMiddleware's `context_key` is ignored, timeout data is now stored in isolated storage")
|
33
|
+
GraphQL::Deprecation.warn("TimeoutMiddleware's `context_key` is ignored, timeout data is now stored in isolated storage")
|
32
34
|
end
|
33
35
|
@error_handler = block
|
34
36
|
end
|
@@ -173,7 +173,7 @@ Some late-bound types couldn't be resolved:
|
|
173
173
|
end
|
174
174
|
when Class
|
175
175
|
if member.respond_to?(:graphql_definition)
|
176
|
-
graphql_member = member.graphql_definition
|
176
|
+
graphql_member = member.graphql_definition(silence_deprecation_warning: true)
|
177
177
|
visit(schema, graphql_member, context_description)
|
178
178
|
else
|
179
179
|
raise GraphQL::Schema::InvalidTypeError.new("Unexpected traversal member: #{member} (#{member.class.name})")
|
@@ -11,7 +11,7 @@ module GraphQL
|
|
11
11
|
def self.build_type(type_owner, ast_node)
|
12
12
|
case ast_node
|
13
13
|
when GraphQL::Language::Nodes::TypeName
|
14
|
-
type_owner.get_type(ast_node.name)
|
14
|
+
type_owner.get_type(ast_node.name) # rubocop:disable Development/ContextIsPassedCop -- this is a `context` or `warden`, it's already query-aware
|
15
15
|
when GraphQL::Language::Nodes::NonNullType
|
16
16
|
ast_inner_type = ast_node.of_type
|
17
17
|
inner_type = build_type(type_owner, ast_inner_type)
|
@@ -4,8 +4,6 @@ module GraphQL
|
|
4
4
|
class Schema
|
5
5
|
# This class joins an object type to an abstract type (interface or union) of which
|
6
6
|
# it is a member.
|
7
|
-
#
|
8
|
-
# TODO: Not yet implemented for interfaces.
|
9
7
|
class TypeMembership
|
10
8
|
# @return [Class<GraphQL::Schema::Object>]
|
11
9
|
attr_accessor :object_type
|
@@ -26,9 +24,25 @@ module GraphQL
|
|
26
24
|
end
|
27
25
|
|
28
26
|
# @return [Boolean] if false, {#object_type} will be treated as _not_ a member of {#abstract_type}
|
29
|
-
def visible?(
|
30
|
-
|
27
|
+
def visible?(ctx)
|
28
|
+
warden = Warden.from_context(ctx)
|
29
|
+
(@object_type.respond_to?(:visible?) ? warden.visible_type?(@object_type, ctx) : true) &&
|
30
|
+
(@abstract_type.respond_to?(:visible?) ? warden.visible_type?(@abstract_type, ctx) : true)
|
31
31
|
end
|
32
|
+
|
33
|
+
def graphql_name
|
34
|
+
"#{@object_type.graphql_name}.#{@abstract_type.kind.interface? ? "implements" : "belongsTo" }.#{@abstract_type.graphql_name}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def path
|
38
|
+
graphql_name
|
39
|
+
end
|
40
|
+
|
41
|
+
def inspect
|
42
|
+
"#<#{self.class} #{@object_type.inspect} => #{@abstract_type.inspect}>"
|
43
|
+
end
|
44
|
+
|
45
|
+
alias :type_class :itself
|
32
46
|
end
|
33
47
|
end
|
34
48
|
end
|
data/lib/graphql/schema/union.rb
CHANGED
@@ -19,8 +19,9 @@ module GraphQL
|
|
19
19
|
end
|
20
20
|
else
|
21
21
|
visible_types = []
|
22
|
+
warden = Warden.from_context(context)
|
22
23
|
type_memberships.each do |type_membership|
|
23
|
-
if
|
24
|
+
if warden.visible_type_membership?(type_membership, context)
|
24
25
|
visible_types << type_membership.object_type
|
25
26
|
end
|
26
27
|
end
|
@@ -28,6 +29,12 @@ module GraphQL
|
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
32
|
+
def all_possible_types
|
33
|
+
type_memberships.map(&:object_type)
|
34
|
+
end
|
35
|
+
|
36
|
+
prepend GraphQL::Schema::Member::CachedGraphQLDefinition::DeprecatedToGraphQL
|
37
|
+
|
31
38
|
def to_graphql
|
32
39
|
type_defn = GraphQL::UnionType.new
|
33
40
|
type_defn.name = graphql_name
|