graphql 1.10.1 → 1.13.0
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 +18 -2
- data/lib/generators/graphql/install_generator.rb +36 -6
- data/lib/generators/graphql/loader_generator.rb +1 -0
- data/lib/generators/graphql/mutation_generator.rb +2 -1
- data/lib/generators/graphql/object_generator.rb +54 -9
- data/lib/generators/graphql/relay.rb +63 -0
- data/lib/generators/graphql/relay_generator.rb +21 -0
- data/lib/generators/graphql/templates/base_argument.erb +2 -0
- 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/base_enum.erb +2 -0
- data/lib/generators/graphql/templates/base_field.erb +2 -0
- data/lib/generators/graphql/templates/base_input_object.erb +2 -0
- data/lib/generators/graphql/templates/base_interface.erb +2 -0
- data/lib/generators/graphql/templates/base_mutation.erb +2 -0
- data/lib/generators/graphql/templates/base_object.erb +2 -0
- data/lib/generators/graphql/templates/base_scalar.erb +2 -0
- data/lib/generators/graphql/templates/base_union.erb +2 -0
- data/lib/generators/graphql/templates/enum.erb +2 -0
- data/lib/generators/graphql/templates/graphql_controller.erb +16 -12
- data/lib/generators/graphql/templates/interface.erb +2 -0
- data/lib/generators/graphql/templates/loader.erb +2 -0
- data/lib/generators/graphql/templates/mutation.erb +2 -0
- data/lib/generators/graphql/templates/mutation_type.erb +2 -0
- data/lib/generators/graphql/templates/node_type.erb +9 -0
- data/lib/generators/graphql/templates/object.erb +3 -1
- data/lib/generators/graphql/templates/query_type.erb +3 -3
- data/lib/generators/graphql/templates/scalar.erb +2 -0
- data/lib/generators/graphql/templates/schema.erb +21 -33
- data/lib/generators/graphql/templates/union.erb +3 -1
- data/lib/generators/graphql/type_generator.rb +1 -1
- data/lib/graphql/analysis/analyze_query.rb +7 -0
- data/lib/graphql/analysis/ast/field_usage.rb +24 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +126 -109
- data/lib/graphql/analysis/ast/visitor.rb +13 -5
- data/lib/graphql/analysis/ast.rb +11 -2
- data/lib/graphql/argument.rb +3 -3
- 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 -9
- data/lib/graphql/backtrace.rb +28 -19
- data/lib/graphql/backwards_compatibility.rb +2 -1
- data/lib/graphql/base_type.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +2 -2
- 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/define/assign_global_id_field.rb +2 -2
- data/lib/graphql/define/defined_object_proxy.rb +1 -1
- data/lib/graphql/define/instance_definable.rb +34 -4
- 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.rb +4 -4
- data/lib/graphql/enum_type.rb +7 -1
- data/lib/graphql/execution/errors.rb +110 -7
- data/lib/graphql/execution/execute.rb +8 -1
- data/lib/graphql/execution/instrumentation.rb +1 -1
- data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
- data/lib/graphql/execution/interpreter/arguments.rb +88 -0
- data/lib/graphql/execution/interpreter/arguments_cache.rb +103 -0
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
- data/lib/graphql/execution/interpreter/resolve.rb +37 -25
- data/lib/graphql/execution/interpreter/runtime.rb +685 -421
- data/lib/graphql/execution/interpreter.rb +42 -13
- data/lib/graphql/execution/lazy.rb +5 -1
- data/lib/graphql/execution/lookahead.rb +25 -110
- data/lib/graphql/execution/multiplex.rb +37 -25
- data/lib/graphql/field.rb +5 -1
- data/lib/graphql/function.rb +4 -0
- data/lib/graphql/input_object_type.rb +6 -0
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +18 -2
- data/lib/graphql/interface_type.rb +7 -0
- data/lib/graphql/internal_representation/document.rb +2 -2
- data/lib/graphql/internal_representation/rewrite.rb +1 -1
- data/lib/graphql/internal_representation/scope.rb +2 -2
- data/lib/graphql/internal_representation/visit.rb +2 -2
- data/lib/graphql/introspection/directive_type.rb +8 -4
- 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 +9 -5
- data/lib/graphql/introspection/input_value_type.rb +15 -3
- data/lib/graphql/introspection/introspection_query.rb +6 -92
- data/lib/graphql/introspection/schema_type.rb +4 -4
- data/lib/graphql/introspection/type_type.rb +16 -12
- data/lib/graphql/introspection.rb +96 -0
- data/lib/graphql/invalid_null_error.rb +18 -0
- data/lib/graphql/language/block_string.rb +20 -5
- data/lib/graphql/language/cache.rb +37 -0
- data/lib/graphql/language/document_from_schema_definition.rb +73 -25
- data/lib/graphql/language/lexer.rb +4 -3
- data/lib/graphql/language/lexer.rl +3 -3
- data/lib/graphql/language/nodes.rb +51 -89
- data/lib/graphql/language/parser.rb +552 -530
- data/lib/graphql/language/parser.y +114 -99
- data/lib/graphql/language/printer.rb +7 -2
- data/lib/graphql/language/sanitized_printer.rb +222 -0
- data/lib/graphql/language/token.rb +0 -4
- data/lib/graphql/language/visitor.rb +2 -2
- data/lib/graphql/language.rb +2 -0
- data/lib/graphql/name_validator.rb +2 -7
- data/lib/graphql/object_type.rb +44 -35
- data/lib/graphql/pagination/active_record_relation_connection.rb +14 -1
- data/lib/graphql/pagination/array_connection.rb +2 -2
- data/lib/graphql/pagination/connection.rb +75 -20
- data/lib/graphql/pagination/connections.rb +83 -31
- data/lib/graphql/pagination/relation_connection.rb +34 -14
- data/lib/graphql/parse_error.rb +0 -1
- data/lib/graphql/query/arguments.rb +4 -3
- data/lib/graphql/query/arguments_cache.rb +1 -2
- data/lib/graphql/query/context.rb +42 -7
- data/lib/graphql/query/executor.rb +0 -1
- data/lib/graphql/query/fingerprint.rb +26 -0
- data/lib/graphql/query/input_validation_result.rb +23 -6
- data/lib/graphql/query/literal_input.rb +1 -1
- data/lib/graphql/query/null_context.rb +24 -8
- 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 +5 -2
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/query/variables.rb +14 -4
- data/lib/graphql/query.rb +68 -13
- data/lib/graphql/railtie.rb +9 -1
- data/lib/graphql/rake_task.rb +12 -9
- data/lib/graphql/relay/array_connection.rb +10 -12
- data/lib/graphql/relay/base_connection.rb +26 -13
- data/lib/graphql/relay/connection_instrumentation.rb +4 -4
- data/lib/graphql/relay/connection_type.rb +1 -1
- data/lib/graphql/relay/edges_instrumentation.rb +0 -1
- data/lib/graphql/relay/mutation.rb +1 -0
- data/lib/graphql/relay/node.rb +3 -0
- data/lib/graphql/relay/range_add.rb +23 -9
- data/lib/graphql/relay/relation_connection.rb +8 -10
- 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 +16 -1
- data/lib/graphql/schema/addition.rb +247 -0
- data/lib/graphql/schema/argument.rb +210 -12
- data/lib/graphql/schema/base_64_encoder.rb +2 -0
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +3 -1
- data/lib/graphql/schema/build_from_definition.rb +213 -86
- data/lib/graphql/schema/default_type_error.rb +2 -0
- data/lib/graphql/schema/directive/deprecated.rb +1 -1
- 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 +78 -2
- data/lib/graphql/schema/enum.rb +80 -9
- data/lib/graphql/schema/enum_value.rb +17 -6
- data/lib/graphql/schema/field/connection_extension.rb +46 -30
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +285 -133
- 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 +97 -89
- data/lib/graphql/schema/interface.rb +24 -19
- data/lib/graphql/schema/late_bound_type.rb +2 -2
- data/lib/graphql/schema/list.rb +7 -1
- data/lib/graphql/schema/loader.rb +137 -103
- data/lib/graphql/schema/member/accepts_definition.rb +8 -1
- data/lib/graphql/schema/member/base_dsl_methods.rb +15 -19
- data/lib/graphql/schema/member/build_type.rb +14 -7
- data/lib/graphql/schema/member/has_arguments.rb +205 -12
- data/lib/graphql/schema/member/has_ast_node.rb +4 -1
- 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 +95 -30
- data/lib/graphql/schema/member/has_interfaces.rb +90 -0
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -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 +3 -3
- data/lib/graphql/schema/member.rb +6 -0
- data/lib/graphql/schema/middleware_chain.rb +1 -1
- data/lib/graphql/schema/mutation.rb +4 -0
- data/lib/graphql/schema/non_null.rb +5 -0
- data/lib/graphql/schema/object.rb +47 -46
- data/lib/graphql/schema/possible_types.rb +9 -4
- data/lib/graphql/schema/printer.rb +16 -34
- data/lib/graphql/schema/relay_classic_mutation.rb +32 -4
- data/lib/graphql/schema/resolver/has_payload_type.rb +34 -4
- data/lib/graphql/schema/resolver.rb +123 -63
- data/lib/graphql/schema/scalar.rb +11 -1
- data/lib/graphql/schema/subscription.rb +57 -21
- data/lib/graphql/schema/timeout.rb +29 -15
- data/lib/graphql/schema/timeout_middleware.rb +3 -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 +41 -1
- data/lib/graphql/schema/unique_within_type.rb +1 -2
- data/lib/graphql/schema/validation.rb +12 -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 +68 -0
- data/lib/graphql/schema/validator.rb +174 -0
- data/lib/graphql/schema/warden.rb +153 -28
- data/lib/graphql/schema.rb +364 -330
- data/lib/graphql/static_validation/all_rules.rb +1 -0
- data/lib/graphql/static_validation/base_visitor.rb +8 -5
- 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 +51 -26
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +44 -87
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +28 -22
- 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/fields_will_merge.rb +79 -43
- 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/required_arguments_are_present.rb +1 -1
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +6 -7
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +9 -10
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +8 -8
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +4 -2
- data/lib/graphql/static_validation/validation_context.rb +9 -3
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +42 -8
- data/lib/graphql/static_validation.rb +1 -0
- data/lib/graphql/string_encoding_error.rb +13 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +118 -19
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +21 -0
- data/lib/graphql/subscriptions/event.rb +81 -30
- data/lib/graphql/subscriptions/instrumentation.rb +0 -1
- data/lib/graphql/subscriptions/serialize.rb +33 -6
- data/lib/graphql/subscriptions/subscription_root.rb +15 -4
- data/lib/graphql/subscriptions.rb +88 -45
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +2 -1
- data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +15 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +1 -12
- data/lib/graphql/tracing/platform_tracing.rb +43 -17
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
- data/lib/graphql/tracing/scout_tracing.rb +11 -0
- data/lib/graphql/tracing/skylight_tracing.rb +1 -1
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing.rb +9 -33
- 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 +3 -3
- data/lib/graphql/types/iso_8601_date_time.rb +25 -10
- data/lib/graphql/types/relay/base_connection.rb +6 -90
- data/lib/graphql/types/relay/base_edge.rb +2 -34
- data/lib/graphql/types/relay/connection_behaviors.rb +156 -0
- data/lib/graphql/types/relay/default_relay.rb +27 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +53 -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 +2 -20
- data/lib/graphql/types/relay/nodes_field.rb +2 -20
- 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 +2 -2
- data/lib/graphql/union_type.rb +2 -0
- 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 +65 -31
- data/readme.md +3 -6
- metadata +77 -112
- data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
- data/lib/graphql/literal_validation_error.rb +0 -6
- 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
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GraphQL
|
2
3
|
class Schema
|
3
4
|
module FindInheritedValue
|
@@ -20,7 +21,9 @@ module GraphQL
|
|
20
21
|
if self.is_a?(Class)
|
21
22
|
superclass.respond_to?(method_name, true) ? superclass.send(method_name) : default_value
|
22
23
|
else
|
23
|
-
|
24
|
+
ancestors_except_self = ancestors
|
25
|
+
ancestors_except_self.delete(self)
|
26
|
+
ancestors_except_self.each do |ancestor|
|
24
27
|
if ancestor.respond_to?(method_name, true)
|
25
28
|
return ancestor.send(method_name)
|
26
29
|
end
|
@@ -38,7 +38,7 @@ module GraphQL
|
|
38
38
|
|
39
39
|
find_in_directive(directive, path: path)
|
40
40
|
else
|
41
|
-
type = schema.get_type(type_or_directive)
|
41
|
+
type = schema.get_type(type_or_directive) # rubocop:disable Development/ContextIsPassedCop -- build-time
|
42
42
|
|
43
43
|
if type.nil?
|
44
44
|
raise MemberNotFoundError, "Could not find type `#{type_or_directive}` in schema."
|
@@ -56,7 +56,7 @@ module GraphQL
|
|
56
56
|
|
57
57
|
def find_in_directive(directive, path:)
|
58
58
|
argument_name = path.shift
|
59
|
-
argument = directive.
|
59
|
+
argument = directive.get_argument(argument_name) # rubocop:disable Development/ContextIsPassedCop -- build-time
|
60
60
|
|
61
61
|
if argument.nil?
|
62
62
|
raise MemberNotFoundError, "Could not find argument `#{argument_name}` on directive #{directive}."
|
@@ -102,7 +102,7 @@ module GraphQL
|
|
102
102
|
|
103
103
|
def find_in_field(field, path:)
|
104
104
|
argument_name = path.shift
|
105
|
-
argument = field.
|
105
|
+
argument = field.get_argument(argument_name) # rubocop:disable Development/ContextIsPassedCop -- build-time
|
106
106
|
|
107
107
|
if argument.nil?
|
108
108
|
raise MemberNotFoundError, "Could not find argument `#{argument_name}` on field `#{field.name}`."
|
@@ -119,7 +119,7 @@ module GraphQL
|
|
119
119
|
|
120
120
|
def find_in_input_object(input_object, path:)
|
121
121
|
field_name = path.shift
|
122
|
-
input_field = input_object.
|
122
|
+
input_field = input_object.get_argument(field_name) # rubocop:disable Development/ContextIsPassedCop -- build-time
|
123
123
|
|
124
124
|
if input_field.nil?
|
125
125
|
raise MemberNotFoundError, "Could not find input field `#{field_name}` on input object type `#{input_object.graphql_name}`."
|
@@ -136,7 +136,7 @@ module GraphQL
|
|
136
136
|
|
137
137
|
def find_in_enum_type(enum_type, path:)
|
138
138
|
value_name = path.shift
|
139
|
-
enum_value = enum_type.
|
139
|
+
enum_value = enum_type.enum_values.find { |v| v.graphql_name == value_name } # rubocop:disable Development/ContextIsPassedCop -- build-time, not runtime
|
140
140
|
|
141
141
|
if enum_value.nil?
|
142
142
|
raise MemberNotFoundError, "Could not find enum value `#{value_name}` on enum type `#{enum_type.graphql_name}`."
|
@@ -5,54 +5,61 @@ module GraphQL
|
|
5
5
|
extend GraphQL::Schema::Member::AcceptsDefinition
|
6
6
|
extend Forwardable
|
7
7
|
extend GraphQL::Schema::Member::HasArguments
|
8
|
+
extend GraphQL::Schema::Member::HasArguments::ArgumentObjectLoader
|
8
9
|
extend GraphQL::Schema::Member::ValidatesInput
|
10
|
+
extend GraphQL::Schema::Member::HasValidators
|
9
11
|
|
10
12
|
include GraphQL::Dig
|
11
13
|
|
12
|
-
|
14
|
+
# @return [GraphQL::Query::Context] The context for this query
|
15
|
+
attr_reader :context
|
16
|
+
# @return [GraphQL::Query::Arguments, GraphQL::Execution::Interpereter::Arguments] The underlying arguments instance
|
17
|
+
attr_reader :arguments
|
18
|
+
|
19
|
+
# Ruby-like hash behaviors, read-only
|
20
|
+
def_delegators :@ruby_style_hash, :keys, :values, :each, :map, :any?, :empty?
|
21
|
+
|
22
|
+
def initialize(arguments = nil, ruby_kwargs: nil, context:, defaults_used:)
|
13
23
|
@context = context
|
14
24
|
if ruby_kwargs
|
15
25
|
@ruby_style_hash = ruby_kwargs
|
26
|
+
@arguments = arguments
|
16
27
|
else
|
17
|
-
@arguments = self.class.arguments_class.new(
|
28
|
+
@arguments = self.class.arguments_class.new(arguments, context: context, defaults_used: defaults_used)
|
18
29
|
# Symbolized, underscored hash:
|
19
30
|
@ruby_style_hash = @arguments.to_kwargs
|
20
31
|
end
|
21
32
|
# Apply prepares, not great to have it duplicated here.
|
22
|
-
|
23
|
-
self.class.arguments.
|
24
|
-
@arguments_by_keyword[arg_defn.keyword] = arg_defn
|
33
|
+
maybe_lazies = []
|
34
|
+
self.class.arguments(context).each_value do |arg_defn|
|
25
35
|
ruby_kwargs_key = arg_defn.keyword
|
26
|
-
loads = arg_defn.loads
|
27
36
|
|
28
|
-
if @ruby_style_hash.key?(ruby_kwargs_key)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
37
|
+
if @ruby_style_hash.key?(ruby_kwargs_key)
|
38
|
+
loads = arg_defn.loads
|
39
|
+
# Resolvers do this loading themselves;
|
40
|
+
# With the interpreter, it's done during `coerce_arguments`
|
41
|
+
if loads && !arg_defn.from_resolver? && !context.interpreter?
|
42
|
+
value = @ruby_style_hash[ruby_kwargs_key]
|
43
|
+
loaded_value = arg_defn.load_and_authorize_value(self, value, context)
|
44
|
+
maybe_lazies << context.schema.after_lazy(loaded_value) do |loaded_value|
|
45
|
+
overwrite_argument(ruby_kwargs_key, loaded_value)
|
46
|
+
end
|
34
47
|
end
|
35
|
-
end
|
36
48
|
|
37
|
-
|
38
|
-
|
49
|
+
# Weirdly, procs are applied during coercion, but not methods.
|
50
|
+
# Probably because these methods require a `self`.
|
51
|
+
if arg_defn.prepare.is_a?(Symbol) || context.nil? || !context.interpreter?
|
52
|
+
prepared_value = arg_defn.prepare_value(self, @ruby_style_hash[ruby_kwargs_key])
|
53
|
+
overwrite_argument(ruby_kwargs_key, prepared_value)
|
54
|
+
end
|
39
55
|
end
|
40
56
|
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# @return [GraphQL::Query::Context] The context for this query
|
44
|
-
attr_reader :context
|
45
|
-
|
46
|
-
# @return [GraphQL::Query::Arguments] The underlying arguments instance
|
47
|
-
attr_reader :arguments
|
48
57
|
|
49
|
-
|
50
|
-
|
58
|
+
@maybe_lazies = maybe_lazies
|
59
|
+
end
|
51
60
|
|
52
61
|
def to_h
|
53
|
-
@ruby_style_hash
|
54
|
-
h.merge(key => unwrap_value(value))
|
55
|
-
end
|
62
|
+
unwrap_value(@ruby_style_hash)
|
56
63
|
end
|
57
64
|
|
58
65
|
def to_hash
|
@@ -60,7 +67,16 @@ module GraphQL
|
|
60
67
|
end
|
61
68
|
|
62
69
|
def prepare
|
63
|
-
|
70
|
+
if @context
|
71
|
+
@context.schema.after_any_lazies(@maybe_lazies) do
|
72
|
+
object = @context[:current_object]
|
73
|
+
# Pass this object's class with `as` so that messages are rendered correctly from inherited validators
|
74
|
+
Schema::Validator.validate!(self.class.validators, object, @context, @ruby_style_hash, as: self.class)
|
75
|
+
self
|
76
|
+
end
|
77
|
+
else
|
78
|
+
self
|
79
|
+
end
|
64
80
|
end
|
65
81
|
|
66
82
|
def unwrap_value(value)
|
@@ -68,8 +84,8 @@ module GraphQL
|
|
68
84
|
when Array
|
69
85
|
value.map { |item| unwrap_value(item) }
|
70
86
|
when Hash
|
71
|
-
value.
|
72
|
-
h.merge(key => unwrap_value(value))
|
87
|
+
value.reduce({}) do |h, (key, value)|
|
88
|
+
h.merge!(key => unwrap_value(value))
|
73
89
|
end
|
74
90
|
when InputObject
|
75
91
|
value.to_h
|
@@ -108,9 +124,12 @@ module GraphQL
|
|
108
124
|
argument_defn = super(*args, **kwargs, &block)
|
109
125
|
# Add a method access
|
110
126
|
method_name = argument_defn.keyword
|
111
|
-
|
112
|
-
|
113
|
-
|
127
|
+
class_eval <<-RUBY, __FILE__, __LINE__
|
128
|
+
def #{method_name}
|
129
|
+
self[#{method_name.inspect}]
|
130
|
+
end
|
131
|
+
RUBY
|
132
|
+
argument_defn
|
114
133
|
end
|
115
134
|
|
116
135
|
def to_graphql
|
@@ -120,8 +139,8 @@ module GraphQL
|
|
120
139
|
type_defn.metadata[:type_class] = self
|
121
140
|
type_defn.mutation = mutation
|
122
141
|
type_defn.ast_node = ast_node
|
123
|
-
|
124
|
-
type_defn.arguments[arg.graphql_definition.name] = arg.graphql_definition
|
142
|
+
all_argument_definitions.each do |arg|
|
143
|
+
type_defn.arguments[arg.graphql_definition.name] = arg.graphql_definition # rubocop:disable Development/ContextIsPassedCop -- legacy-related
|
125
144
|
end
|
126
145
|
# Make a reference to a classic-style Arguments class
|
127
146
|
self.arguments_class = GraphQL::Query::Arguments.construct_arguments_class(type_defn)
|
@@ -137,7 +156,6 @@ module GraphQL
|
|
137
156
|
# @api private
|
138
157
|
INVALID_OBJECT_MESSAGE = "Expected %{object} to be a key-value object responding to `to_h` or `to_unsafe_h`."
|
139
158
|
|
140
|
-
|
141
159
|
def validate_non_null_input(input, ctx)
|
142
160
|
result = GraphQL::Query::InputValidationResult.new
|
143
161
|
|
@@ -148,36 +166,33 @@ module GraphQL
|
|
148
166
|
return result
|
149
167
|
end
|
150
168
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
input.to_h
|
156
|
-
rescue
|
157
|
-
begin
|
158
|
-
# Handle ActionController::Parameters:
|
159
|
-
input.to_unsafe_h
|
160
|
-
rescue
|
161
|
-
# We're not sure it'll act like a hash, so reject it:
|
162
|
-
result.add_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
|
163
|
-
return result
|
164
|
-
end
|
169
|
+
if !(input.respond_to?(:to_h) || input.respond_to?(:to_unsafe_h))
|
170
|
+
# We're not sure it'll act like a hash, so reject it:
|
171
|
+
result.add_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
|
172
|
+
return result
|
165
173
|
end
|
166
174
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
if visible_arguments_map[name].nil?
|
172
|
-
result.add_problem("Argument is not defined on #{self.graphql_name}", [name])
|
175
|
+
# Inject missing required arguments
|
176
|
+
missing_required_inputs = self.arguments(ctx).reduce({}) do |m, (argument_name, argument)|
|
177
|
+
if !input.key?(argument_name) && argument.type.non_null? && warden.get_argument(self, argument_name)
|
178
|
+
m[argument_name] = nil
|
173
179
|
end
|
180
|
+
|
181
|
+
m
|
174
182
|
end
|
175
183
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
184
|
+
|
185
|
+
[input, missing_required_inputs].each do |args_to_validate|
|
186
|
+
args_to_validate.each do |argument_name, value|
|
187
|
+
argument = warden.get_argument(self, argument_name)
|
188
|
+
# Items in the input that are unexpected
|
189
|
+
unless argument
|
190
|
+
result.add_problem("Field is not defined on #{self.graphql_name}", [argument_name])
|
191
|
+
next
|
192
|
+
end
|
193
|
+
# Items in the input that are expected, but have invalid values
|
194
|
+
argument_result = argument.type.validate_input(value, ctx)
|
195
|
+
result.merge_result!(argument_name, argument_result) unless argument_result.valid?
|
181
196
|
end
|
182
197
|
end
|
183
198
|
|
@@ -188,45 +203,28 @@ module GraphQL
|
|
188
203
|
if value.nil?
|
189
204
|
return nil
|
190
205
|
end
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
# Accept either string or symbol
|
198
|
-
field_value = if value.key?(name)
|
199
|
-
has_value = true
|
200
|
-
value[name]
|
201
|
-
elsif value.key?(arg_key)
|
202
|
-
has_value = true
|
203
|
-
value[arg_key]
|
204
|
-
elsif argument_defn.default_value?
|
205
|
-
has_value = true
|
206
|
-
argument_defn.default_value
|
206
|
+
|
207
|
+
arguments = coerce_arguments(nil, value, ctx)
|
208
|
+
|
209
|
+
ctx.schema.after_lazy(arguments) do |resolved_arguments|
|
210
|
+
if resolved_arguments.is_a?(GraphQL::Error)
|
211
|
+
raise resolved_arguments
|
207
212
|
else
|
208
|
-
nil
|
209
|
-
|
210
|
-
# Only continue if some value was found for this argument
|
211
|
-
if has_value
|
212
|
-
coerced_value = argument_defn.type.coerce_input(field_value, ctx)
|
213
|
-
prepared_value = argument_defn.prepare_value(nil, coerced_value, context: ctx)
|
214
|
-
input_values[arg_key] = prepared_value
|
213
|
+
input_obj_instance = self.new(resolved_arguments, ruby_kwargs: resolved_arguments.keyword_arguments, context: ctx, defaults_used: nil)
|
214
|
+
input_obj_instance.prepare
|
215
215
|
end
|
216
216
|
end
|
217
|
-
|
218
|
-
input_values
|
219
217
|
end
|
220
218
|
|
221
219
|
# It's funny to think of a _result_ of an input object.
|
222
220
|
# This is used for rendering the default value in introspection responses.
|
223
221
|
def coerce_result(value, ctx)
|
224
|
-
# Allow the application to provide values as :
|
225
|
-
value = value.reduce({}) { |memo, (k, v)| memo[k.to_s] = v; memo }
|
222
|
+
# Allow the application to provide values as :snake_symbols, and convert them to the camelStrings
|
223
|
+
value = value.reduce({}) { |memo, (k, v)| memo[Member::BuildType.camelize(k.to_s)] = v; memo }
|
226
224
|
|
227
225
|
result = {}
|
228
226
|
|
229
|
-
arguments.each do |input_key, input_field_defn|
|
227
|
+
arguments(ctx).each do |input_key, input_field_defn|
|
230
228
|
input_value = value[input_key]
|
231
229
|
if value.key?(input_key)
|
232
230
|
result[input_key] = if input_value.nil?
|
@@ -240,6 +238,16 @@ module GraphQL
|
|
240
238
|
result
|
241
239
|
end
|
242
240
|
end
|
241
|
+
|
242
|
+
private
|
243
|
+
|
244
|
+
def overwrite_argument(key, value)
|
245
|
+
# Argument keywords come in frozen from the interpreter, dup them before modifying them.
|
246
|
+
if @ruby_style_hash.frozen?
|
247
|
+
@ruby_style_hash = @ruby_style_hash.dup
|
248
|
+
end
|
249
|
+
@ruby_style_hash[key] = value
|
250
|
+
end
|
243
251
|
end
|
244
252
|
end
|
245
253
|
end
|
@@ -14,6 +14,9 @@ module GraphQL
|
|
14
14
|
include GraphQL::Schema::Member::RelayShortcuts
|
15
15
|
include GraphQL::Schema::Member::Scoped
|
16
16
|
include GraphQL::Schema::Member::HasAstNode
|
17
|
+
include GraphQL::Schema::Member::HasUnresolvedTypeError
|
18
|
+
include GraphQL::Schema::Member::HasDirectives
|
19
|
+
include GraphQL::Schema::Member::HasInterfaces
|
17
20
|
|
18
21
|
# Methods defined in this block will be:
|
19
22
|
# - Added as class methods to this interface
|
@@ -29,7 +32,7 @@ module GraphQL
|
|
29
32
|
|
30
33
|
# The interface is accessible if any of its possible types are accessible
|
31
34
|
def accessible?(context)
|
32
|
-
context.schema.possible_types(self).each do |type|
|
35
|
+
context.schema.possible_types(self, context).each do |type|
|
33
36
|
if context.schema.accessible?(type, context)
|
34
37
|
return true
|
35
38
|
end
|
@@ -37,6 +40,14 @@ module GraphQL
|
|
37
40
|
false
|
38
41
|
end
|
39
42
|
|
43
|
+
def type_membership_class(membership_class = nil)
|
44
|
+
if membership_class
|
45
|
+
@type_membership_class = membership_class
|
46
|
+
else
|
47
|
+
@type_membership_class || find_inherited_value(:type_membership_class, GraphQL::Schema::TypeMembership)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
40
51
|
# Here's the tricky part. Make sure behavior keeps making its way down the inheritance chain.
|
41
52
|
def included(child_class)
|
42
53
|
if !child_class.is_a?(Class)
|
@@ -46,9 +57,11 @@ module GraphQL
|
|
46
57
|
# We need this before we can call `own_interfaces`
|
47
58
|
child_class.extend(Schema::Interface::DefinitionMethods)
|
48
59
|
|
49
|
-
child_class.
|
50
|
-
child_class.
|
51
|
-
|
60
|
+
child_class.type_membership_class(self.type_membership_class)
|
61
|
+
child_class.ancestors.reverse_each do |ancestor|
|
62
|
+
if ancestor.const_defined?(:DefinitionMethods)
|
63
|
+
child_class.extend(ancestor::DefinitionMethods)
|
64
|
+
end
|
52
65
|
end
|
53
66
|
|
54
67
|
# Use an instance variable to tell whether it's been included previously or not;
|
@@ -62,12 +75,13 @@ module GraphQL
|
|
62
75
|
end
|
63
76
|
child_class.introspection(introspection)
|
64
77
|
child_class.description(description)
|
65
|
-
|
66
|
-
|
78
|
+
# If interfaces are mixed into each other, only define this class once
|
79
|
+
if !child_class.const_defined?(:UnresolvedTypeError, false)
|
80
|
+
add_unresolved_type_error(child_class)
|
67
81
|
end
|
68
82
|
elsif child_class < GraphQL::Schema::Object
|
69
83
|
# This is being included into an object type, make sure it's using `implements(...)`
|
70
|
-
backtrace_line = caller(0, 10).find { |line| line.include?("schema/
|
84
|
+
backtrace_line = caller(0, 10).find { |line| line.include?("schema/member/has_interfaces.rb") && line.include?("in `implements'")}
|
71
85
|
if !backtrace_line
|
72
86
|
raise "Attach interfaces using `implements(#{self})`, not `include(#{self})`"
|
73
87
|
end
|
@@ -91,10 +105,11 @@ module GraphQL
|
|
91
105
|
type_defn.name = graphql_name
|
92
106
|
type_defn.description = description
|
93
107
|
type_defn.orphan_types = orphan_types
|
108
|
+
type_defn.type_membership_class = self.type_membership_class
|
94
109
|
type_defn.ast_node = ast_node
|
95
|
-
fields.each do |field_name, field_inst|
|
110
|
+
fields.each do |field_name, field_inst| # rubocop:disable Development/ContextIsPassedCop -- legacy-related
|
96
111
|
field_defn = field_inst.graphql_definition
|
97
|
-
type_defn.fields[field_defn.name] = field_defn
|
112
|
+
type_defn.fields[field_defn.name] = field_defn # rubocop:disable Development/ContextIsPassedCop -- legacy-related
|
98
113
|
end
|
99
114
|
type_defn.metadata[:type_class] = self
|
100
115
|
if respond_to?(:resolve_type)
|
@@ -106,16 +121,6 @@ module GraphQL
|
|
106
121
|
def kind
|
107
122
|
GraphQL::TypeKinds::INTERFACE
|
108
123
|
end
|
109
|
-
|
110
|
-
protected
|
111
|
-
|
112
|
-
def own_interfaces
|
113
|
-
@own_interfaces ||= []
|
114
|
-
end
|
115
|
-
|
116
|
-
def interfaces
|
117
|
-
own_interfaces + (own_interfaces.map { |i| i.own_interfaces }).flatten
|
118
|
-
end
|
119
124
|
end
|
120
125
|
|
121
126
|
# Extend this _after_ `DefinitionMethods` is defined, so it will be used
|
@@ -16,11 +16,11 @@ module GraphQL
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def to_non_null_type
|
19
|
-
GraphQL::NonNullType.new(of_type: self)
|
19
|
+
@to_non_null_type ||= GraphQL::NonNullType.new(of_type: self)
|
20
20
|
end
|
21
21
|
|
22
22
|
def to_list_type
|
23
|
-
GraphQL::ListType.new(of_type: self)
|
23
|
+
@to_list_type ||= GraphQL::ListType.new(of_type: self)
|
24
24
|
end
|
25
25
|
|
26
26
|
def inspect
|
data/lib/graphql/schema/list.rb
CHANGED
@@ -31,6 +31,11 @@ module GraphQL
|
|
31
31
|
nil
|
32
32
|
end
|
33
33
|
|
34
|
+
# Also for implementing introspection
|
35
|
+
def description
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
34
39
|
def coerce_result(value, ctx)
|
35
40
|
value.map { |i| i.nil? ? nil : of_type.coerce_result(i, ctx) }
|
36
41
|
end
|
@@ -39,7 +44,8 @@ module GraphQL
|
|
39
44
|
if value.nil?
|
40
45
|
nil
|
41
46
|
else
|
42
|
-
ensure_array(value).map { |item| item.nil? ? item : of_type.coerce_input(item, ctx) }
|
47
|
+
coerced = ensure_array(value).map { |item| item.nil? ? item : of_type.coerce_input(item, ctx) }
|
48
|
+
ctx.schema.after_any_lazies(coerced, &:itself)
|
43
49
|
end
|
44
50
|
end
|
45
51
|
|