graphql 2.0.31 → 2.6.1
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/lib/generators/graphql/detailed_trace_generator.rb +77 -0
- data/lib/generators/graphql/install/mutation_root_generator.rb +2 -2
- data/lib/generators/graphql/install/templates/base_mutation.erb +2 -0
- data/lib/generators/graphql/install/templates/mutation_type.erb +2 -0
- data/lib/generators/graphql/install_generator.rb +49 -0
- data/lib/generators/graphql/orm_mutations_base.rb +1 -1
- data/lib/generators/graphql/templates/base_argument.erb +2 -0
- data/lib/generators/graphql/templates/base_connection.erb +2 -0
- data/lib/generators/graphql/templates/base_edge.erb +2 -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_object.erb +2 -0
- data/lib/generators/graphql/templates/base_resolver.erb +8 -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/create_graphql_detailed_traces.erb +10 -0
- data/lib/generators/graphql/templates/graphql_controller.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/node_type.erb +2 -0
- data/lib/generators/graphql/templates/query_type.erb +2 -0
- data/lib/generators/graphql/templates/schema.erb +5 -0
- data/lib/generators/graphql/type_generator.rb +1 -1
- data/lib/graphql/analysis/analyzer.rb +90 -0
- data/lib/graphql/analysis/field_usage.rb +82 -0
- data/lib/graphql/analysis/max_query_complexity.rb +20 -0
- data/lib/graphql/analysis/max_query_depth.rb +20 -0
- data/lib/graphql/analysis/query_complexity.rb +263 -0
- data/lib/graphql/analysis/query_depth.rb +58 -0
- data/lib/graphql/analysis/visitor.rb +280 -0
- data/lib/graphql/analysis.rb +102 -1
- data/lib/graphql/autoload.rb +38 -0
- data/lib/graphql/backtrace/table.rb +118 -55
- data/lib/graphql/backtrace.rb +1 -19
- data/lib/graphql/coercion_error.rb +1 -9
- data/lib/graphql/current.rb +57 -0
- data/lib/graphql/dashboard/application_controller.rb +41 -0
- data/lib/graphql/dashboard/detailed_traces.rb +47 -0
- data/lib/graphql/dashboard/installable.rb +22 -0
- data/lib/graphql/dashboard/landings_controller.rb +9 -0
- data/lib/graphql/dashboard/limiters.rb +93 -0
- data/lib/graphql/dashboard/operation_store.rb +199 -0
- data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.css +6 -0
- data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.js +7 -0
- data/lib/graphql/dashboard/statics/charts.min.css +1 -0
- data/lib/graphql/dashboard/statics/dashboard.css +30 -0
- data/lib/graphql/dashboard/statics/dashboard.js +143 -0
- data/lib/graphql/dashboard/statics/header-icon.png +0 -0
- data/lib/graphql/dashboard/statics/icon.png +0 -0
- data/lib/graphql/dashboard/statics_controller.rb +31 -0
- data/lib/graphql/dashboard/subscriptions.rb +97 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/detailed_traces/traces/index.html.erb +45 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/landings/show.html.erb +18 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/limiters/limiters/show.html.erb +62 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/not_installed.html.erb +18 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/_form.html.erb +24 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/edit.html.erb +21 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/index.html.erb +69 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/new.html.erb +7 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/index.html.erb +39 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/show.html.erb +32 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/index.html.erb +81 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/show.html.erb +71 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/subscriptions/show.html.erb +41 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/index.html.erb +55 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/show.html.erb +40 -0
- data/lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb +108 -0
- data/lib/graphql/dashboard.rb +96 -0
- data/lib/graphql/dataloader/active_record_association_source.rb +84 -0
- data/lib/graphql/dataloader/active_record_source.rb +47 -0
- data/lib/graphql/dataloader/async_dataloader.rb +112 -0
- data/lib/graphql/dataloader/null_dataloader.rb +55 -10
- data/lib/graphql/dataloader/request.rb +5 -0
- data/lib/graphql/dataloader/source.rb +35 -12
- data/lib/graphql/dataloader.rb +224 -149
- data/lib/graphql/date_encoding_error.rb +1 -1
- data/lib/graphql/dig.rb +2 -1
- data/lib/graphql/duration_encoding_error.rb +16 -0
- data/lib/graphql/execution/field_resolve_step.rb +631 -0
- data/lib/graphql/execution/finalize.rb +217 -0
- data/lib/graphql/execution/input_values.rb +261 -0
- data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
- data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +6 -0
- data/lib/graphql/execution/interpreter/resolve.rb +23 -25
- data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +228 -0
- data/lib/graphql/execution/interpreter/runtime.rb +365 -435
- data/lib/graphql/execution/interpreter.rb +87 -163
- data/lib/graphql/execution/lazy.rb +1 -1
- data/lib/graphql/execution/load_argument_step.rb +64 -0
- data/lib/graphql/execution/lookahead.rb +105 -31
- data/lib/graphql/execution/multiplex.rb +7 -6
- data/lib/graphql/execution/next.rb +90 -0
- data/lib/graphql/execution/prepare_object_step.rb +128 -0
- data/lib/graphql/execution/runner.rb +410 -0
- data/lib/graphql/execution/selections_step.rb +91 -0
- data/lib/graphql/execution.rb +8 -4
- data/lib/graphql/execution_error.rb +17 -10
- data/lib/graphql/introspection/directive_location_enum.rb +1 -1
- data/lib/graphql/introspection/directive_type.rb +7 -3
- data/lib/graphql/introspection/dynamic_fields.rb +5 -1
- data/lib/graphql/introspection/entry_points.rb +20 -6
- data/lib/graphql/introspection/enum_value_type.rb +5 -5
- data/lib/graphql/introspection/field_type.rb +13 -5
- data/lib/graphql/introspection/input_value_type.rb +21 -13
- data/lib/graphql/introspection/schema_type.rb +8 -11
- data/lib/graphql/introspection/type_type.rb +64 -28
- data/lib/graphql/invalid_name_error.rb +1 -1
- data/lib/graphql/invalid_null_error.rb +26 -17
- data/lib/graphql/language/block_string.rb +34 -18
- data/lib/graphql/language/cache.rb +13 -0
- data/lib/graphql/language/comment.rb +18 -0
- data/lib/graphql/language/definition_slice.rb +1 -1
- data/lib/graphql/language/document_from_schema_definition.rb +90 -61
- data/lib/graphql/language/lexer.rb +323 -193
- data/lib/graphql/language/nodes.rb +139 -77
- data/lib/graphql/language/parser.rb +807 -1985
- data/lib/graphql/language/printer.rb +324 -151
- data/lib/graphql/language/sanitized_printer.rb +21 -23
- data/lib/graphql/language/static_visitor.rb +171 -0
- data/lib/graphql/language/visitor.rb +62 -119
- data/lib/graphql/language.rb +71 -1
- data/lib/graphql/load_application_object_failed_error.rb +5 -1
- data/lib/graphql/pagination/array_connection.rb +6 -6
- data/lib/graphql/pagination/connection.rb +30 -1
- data/lib/graphql/pagination/connections.rb +32 -0
- data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
- data/lib/graphql/query/context/scoped_context.rb +101 -0
- data/lib/graphql/query/context.rb +88 -144
- data/lib/graphql/query/null_context.rb +15 -18
- data/lib/graphql/query/partial.rb +194 -0
- data/lib/graphql/query/validation_pipeline.rb +4 -4
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/query/variables.rb +3 -3
- data/lib/graphql/query.rb +135 -81
- data/lib/graphql/railtie.rb +16 -6
- data/lib/graphql/rake_task.rb +3 -12
- data/lib/graphql/rubocop/graphql/base_cop.rb +1 -1
- data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
- data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
- data/lib/graphql/rubocop.rb +2 -0
- data/lib/graphql/runtime_error.rb +6 -0
- data/lib/graphql/schema/addition.rb +26 -13
- data/lib/graphql/schema/always_visible.rb +7 -2
- data/lib/graphql/schema/argument.rb +78 -14
- data/lib/graphql/schema/base_64_encoder.rb +3 -5
- data/lib/graphql/schema/build_from_definition.rb +140 -66
- data/lib/graphql/schema/directive/flagged.rb +4 -2
- data/lib/graphql/schema/directive/one_of.rb +12 -0
- data/lib/graphql/schema/directive/specified_by.rb +14 -0
- data/lib/graphql/schema/directive.rb +78 -12
- data/lib/graphql/schema/enum.rb +110 -27
- data/lib/graphql/schema/enum_value.rb +11 -3
- data/lib/graphql/schema/field/connection_extension.rb +4 -51
- data/lib/graphql/schema/field/scope_extension.rb +19 -7
- data/lib/graphql/schema/field.rb +245 -119
- data/lib/graphql/schema/field_extension.rb +12 -9
- data/lib/graphql/schema/has_single_input_argument.rb +160 -0
- data/lib/graphql/schema/input_object.rb +123 -65
- data/lib/graphql/schema/interface.rb +60 -16
- data/lib/graphql/schema/introspection_system.rb +8 -17
- data/lib/graphql/schema/late_bound_type.rb +4 -0
- data/lib/graphql/schema/list.rb +8 -4
- data/lib/graphql/schema/loader.rb +3 -4
- data/lib/graphql/schema/member/base_dsl_methods.rb +18 -12
- data/lib/graphql/schema/member/has_arguments.rb +132 -100
- data/lib/graphql/schema/member/has_authorization.rb +35 -0
- data/lib/graphql/schema/member/has_dataloader.rb +99 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +15 -0
- data/lib/graphql/schema/member/has_directives.rb +5 -5
- data/lib/graphql/schema/member/has_fields.rb +121 -17
- data/lib/graphql/schema/member/has_interfaces.rb +27 -13
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
- data/lib/graphql/schema/member/has_validators.rb +1 -1
- data/lib/graphql/schema/member/relay_shortcuts.rb +1 -1
- data/lib/graphql/schema/member/scoped.rb +19 -0
- data/lib/graphql/schema/member/type_system_helpers.rb +18 -5
- data/lib/graphql/schema/member/validates_input.rb +3 -3
- data/lib/graphql/schema/member.rb +6 -0
- data/lib/graphql/schema/mutation.rb +7 -0
- data/lib/graphql/schema/non_null.rb +1 -1
- data/lib/graphql/schema/object.rb +34 -8
- data/lib/graphql/schema/printer.rb +9 -7
- data/lib/graphql/schema/ractor_shareable.rb +79 -0
- data/lib/graphql/schema/relay_classic_mutation.rb +6 -129
- data/lib/graphql/schema/resolver.rb +128 -32
- data/lib/graphql/schema/scalar.rb +4 -9
- data/lib/graphql/schema/subscription.rb +63 -12
- data/lib/graphql/schema/timeout.rb +19 -2
- data/lib/graphql/schema/type_expression.rb +2 -2
- data/lib/graphql/schema/union.rb +2 -2
- data/lib/graphql/schema/unique_within_type.rb +1 -1
- data/lib/graphql/schema/validator/all_validator.rb +62 -0
- data/lib/graphql/schema/validator/required_validator.rb +92 -11
- data/lib/graphql/schema/validator.rb +3 -1
- data/lib/graphql/schema/visibility/migration.rb +188 -0
- data/lib/graphql/schema/visibility/profile.rb +464 -0
- data/lib/graphql/schema/visibility/visit.rb +190 -0
- data/lib/graphql/schema/visibility.rb +311 -0
- data/lib/graphql/schema/warden.rb +275 -103
- data/lib/graphql/schema/wrapper.rb +7 -1
- data/lib/graphql/schema.rb +954 -212
- data/lib/graphql/static_validation/all_rules.rb +3 -3
- data/lib/graphql/static_validation/base_visitor.rb +96 -71
- data/lib/graphql/static_validation/literal_validator.rb +6 -7
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +2 -2
- data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +18 -6
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +6 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +6 -3
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +14 -3
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +59 -15
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +391 -262
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +10 -2
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +6 -6
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +15 -2
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
- data/lib/graphql/static_validation/rules/not_single_subscription_error.rb +25 -0
- data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +28 -8
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +5 -5
- data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +26 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +7 -3
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
- data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +14 -2
- data/lib/graphql/static_validation/validation_context.rb +22 -6
- data/lib/graphql/static_validation/validator.rb +9 -1
- data/lib/graphql/static_validation.rb +0 -1
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +8 -5
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +45 -19
- data/lib/graphql/subscriptions/event.rb +22 -4
- data/lib/graphql/subscriptions/serialize.rb +3 -1
- data/lib/graphql/subscriptions.rb +56 -17
- data/lib/graphql/testing/helpers.rb +161 -0
- data/lib/graphql/testing/mock_action_cable.rb +111 -0
- data/lib/graphql/testing.rb +3 -0
- data/lib/graphql/tracing/active_support_notifications_trace.rb +14 -3
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +1 -1
- data/lib/graphql/tracing/appoptics_trace.rb +11 -3
- data/lib/graphql/tracing/appoptics_tracing.rb +9 -2
- data/lib/graphql/tracing/appsignal_trace.rb +32 -55
- data/lib/graphql/tracing/appsignal_tracing.rb +2 -0
- data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
- data/lib/graphql/tracing/data_dog_trace.rb +46 -158
- data/lib/graphql/tracing/data_dog_tracing.rb +2 -0
- data/lib/graphql/tracing/detailed_trace/active_record_backend.rb +74 -0
- data/lib/graphql/tracing/detailed_trace/memory_backend.rb +60 -0
- data/lib/graphql/tracing/detailed_trace/redis_backend.rb +72 -0
- data/lib/graphql/tracing/detailed_trace.rb +156 -0
- data/lib/graphql/tracing/legacy_hooks_trace.rb +75 -0
- data/lib/graphql/tracing/legacy_trace.rb +4 -61
- data/lib/graphql/tracing/monitor_trace.rb +283 -0
- data/lib/graphql/tracing/new_relic_trace.rb +47 -54
- data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
- data/lib/graphql/tracing/notifications_trace.rb +184 -34
- data/lib/graphql/tracing/notifications_tracing.rb +2 -0
- data/lib/graphql/tracing/null_trace.rb +9 -0
- data/lib/graphql/tracing/perfetto_trace/trace.proto +141 -0
- data/lib/graphql/tracing/perfetto_trace/trace_pb.rb +33 -0
- data/lib/graphql/tracing/perfetto_trace.rb +864 -0
- data/lib/graphql/tracing/platform_trace.rb +5 -0
- data/lib/graphql/tracing/platform_tracing.rb +3 -1
- data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +5 -1
- data/lib/graphql/tracing/prometheus_trace.rb +72 -68
- data/lib/graphql/tracing/prometheus_tracing.rb +2 -0
- data/lib/graphql/tracing/scout_trace.rb +32 -55
- data/lib/graphql/tracing/scout_tracing.rb +2 -0
- data/lib/graphql/tracing/sentry_trace.rb +82 -0
- data/lib/graphql/tracing/statsd_trace.rb +33 -41
- data/lib/graphql/tracing/statsd_tracing.rb +2 -0
- data/lib/graphql/tracing/trace.rb +118 -1
- data/lib/graphql/tracing.rb +31 -28
- data/lib/graphql/type_kinds.rb +2 -1
- data/lib/graphql/types/iso_8601_duration.rb +77 -0
- data/lib/graphql/types/relay/connection_behaviors.rb +45 -3
- data/lib/graphql/types/relay/edge_behaviors.rb +19 -1
- data/lib/graphql/types/relay/has_node_field.rb +13 -8
- data/lib/graphql/types/relay/has_nodes_field.rb +13 -8
- data/lib/graphql/types/relay/node_behaviors.rb +13 -2
- data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
- data/lib/graphql/types.rb +18 -10
- data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
- data/lib/graphql/unauthorized_error.rb +9 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +69 -54
- data/readme.md +12 -2
- metadata +236 -40
- data/lib/graphql/analysis/ast/analyzer.rb +0 -84
- data/lib/graphql/analysis/ast/field_usage.rb +0 -57
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -22
- data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
- data/lib/graphql/analysis/ast/query_complexity.rb +0 -230
- data/lib/graphql/analysis/ast/query_depth.rb +0 -55
- data/lib/graphql/analysis/ast/visitor.rb +0 -276
- data/lib/graphql/analysis/ast.rb +0 -81
- data/lib/graphql/backtrace/inspect_result.rb +0 -50
- data/lib/graphql/backtrace/trace.rb +0 -96
- data/lib/graphql/backtrace/tracer.rb +0 -80
- data/lib/graphql/deprecation.rb +0 -9
- data/lib/graphql/filter.rb +0 -59
- data/lib/graphql/language/parser.y +0 -560
- data/lib/graphql/language/token.rb +0 -34
- data/lib/graphql/schema/base_64_bp.rb +0 -26
- data/lib/graphql/schema/invalid_type_error.rb +0 -7
- data/lib/graphql/schema/null_mask.rb +0 -11
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +0 -17
- data/lib/graphql/static_validation/type_stack.rb +0 -216
- data/lib/graphql/subscriptions/instrumentation.rb +0 -28
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GraphQL
|
|
4
|
+
class Schema
|
|
5
|
+
module HasSingleInputArgument
|
|
6
|
+
def resolve_with_support(**inputs)
|
|
7
|
+
if inputs[:input].is_a?(InputObject)
|
|
8
|
+
input = inputs[:input].to_kwargs
|
|
9
|
+
else
|
|
10
|
+
input = inputs[:input]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
new_extras = field ? field.extras : []
|
|
14
|
+
all_extras = self.class.extras + new_extras
|
|
15
|
+
|
|
16
|
+
# Transfer these from the top-level hash to the
|
|
17
|
+
# shortcutted `input:` object
|
|
18
|
+
all_extras.each do |ext|
|
|
19
|
+
# It's possible that the `extra` was not passed along by this point,
|
|
20
|
+
# don't re-add it if it wasn't given here.
|
|
21
|
+
if inputs.key?(ext)
|
|
22
|
+
input[ext] = inputs[ext]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if input
|
|
27
|
+
# This is handled by Relay::Mutation::Resolve, a bit hacky, but here we are.
|
|
28
|
+
input_kwargs = input.to_h
|
|
29
|
+
else
|
|
30
|
+
# Relay Classic Mutations with no `argument`s
|
|
31
|
+
# don't require `input:`
|
|
32
|
+
input_kwargs = {}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
if !input_kwargs.empty?
|
|
36
|
+
super(**input_kwargs)
|
|
37
|
+
else
|
|
38
|
+
super()
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.included(base)
|
|
43
|
+
base.extend(ClassMethods)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
module ClassMethods
|
|
47
|
+
def dummy
|
|
48
|
+
@dummy ||= begin
|
|
49
|
+
d = Class.new(GraphQL::Schema::Resolver)
|
|
50
|
+
d.graphql_name "#{self.graphql_name}DummyResolver"
|
|
51
|
+
d.argument_class(self.argument_class)
|
|
52
|
+
# TODO make this lazier?
|
|
53
|
+
d.argument(:input, input_type, description: "Parameters for #{self.graphql_name}")
|
|
54
|
+
d
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def field_arguments(context = GraphQL::Query::NullContext.instance)
|
|
59
|
+
dummy.arguments(context)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def get_field_argument(name, context = GraphQL::Query::NullContext.instance)
|
|
63
|
+
dummy.get_argument(name, context)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def own_field_arguments
|
|
67
|
+
dummy.own_arguments
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def any_field_arguments?
|
|
71
|
+
dummy.any_arguments?
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def all_field_argument_definitions
|
|
75
|
+
dummy.all_argument_definitions
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Also apply this argument to the input type:
|
|
79
|
+
def argument(*args, own_argument: false, **kwargs, &block)
|
|
80
|
+
it = input_type # make sure any inherited arguments are already added to it
|
|
81
|
+
arg = super(*args, **kwargs, &block)
|
|
82
|
+
|
|
83
|
+
# This definition might be overriding something inherited;
|
|
84
|
+
# if it is, remove the inherited definition so it's not confused at runtime as having multiple definitions
|
|
85
|
+
prev_args = it.own_arguments[arg.graphql_name]
|
|
86
|
+
case prev_args
|
|
87
|
+
when GraphQL::Schema::Argument
|
|
88
|
+
if prev_args.owner != self
|
|
89
|
+
it.own_arguments.delete(arg.graphql_name)
|
|
90
|
+
end
|
|
91
|
+
when Array
|
|
92
|
+
prev_args.reject! { |a| a.owner != self }
|
|
93
|
+
if prev_args.empty?
|
|
94
|
+
it.own_arguments.delete(arg.graphql_name)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it.add_argument(arg)
|
|
99
|
+
arg
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# The base class for generated input object types
|
|
103
|
+
# @param new_class [Class] The base class to use for generating input object definitions
|
|
104
|
+
# @return [Class] The base class for this mutation's generated input object (default is {GraphQL::Schema::InputObject})
|
|
105
|
+
def input_object_class(new_class = nil)
|
|
106
|
+
if new_class
|
|
107
|
+
@input_object_class = new_class
|
|
108
|
+
end
|
|
109
|
+
@input_object_class || (superclass.respond_to?(:input_object_class) ? superclass.input_object_class : GraphQL::Schema::InputObject)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# @param new_input_type [Class, nil] If provided, it configures this mutation to accept `new_input_type` instead of generating an input type
|
|
113
|
+
# @return [Class] The generated {Schema::InputObject} class for this mutation's `input`
|
|
114
|
+
def input_type(new_input_type = nil)
|
|
115
|
+
if new_input_type
|
|
116
|
+
@input_type = new_input_type
|
|
117
|
+
end
|
|
118
|
+
@input_type ||= generate_input_type
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
private
|
|
122
|
+
|
|
123
|
+
# Generate the input type for the `input:` argument
|
|
124
|
+
# To customize how input objects are generated, override this method
|
|
125
|
+
# @return [Class] a subclass of {.input_object_class}
|
|
126
|
+
def generate_input_type
|
|
127
|
+
mutation_args = all_argument_definitions
|
|
128
|
+
mutation_class = self
|
|
129
|
+
Class.new(input_object_class) do
|
|
130
|
+
class << self
|
|
131
|
+
def default_graphql_name
|
|
132
|
+
"#{self.mutation.graphql_name}Input"
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def description(new_desc = nil)
|
|
136
|
+
super || "Autogenerated input type of #{self.mutation.graphql_name}"
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
# For compatibility, in case no arguments are defined:
|
|
140
|
+
has_no_arguments(true)
|
|
141
|
+
mutation(mutation_class)
|
|
142
|
+
# these might be inherited:
|
|
143
|
+
mutation_args.each do |arg|
|
|
144
|
+
add_argument(arg)
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
private
|
|
151
|
+
|
|
152
|
+
def authorize_arguments(args, values)
|
|
153
|
+
# remove the `input` wrapper to match values
|
|
154
|
+
input_type = args.find { |a| a.graphql_name == "input" }.type.unwrap
|
|
155
|
+
input_args = context.types.arguments(input_type)
|
|
156
|
+
super(input_args, values)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
@@ -10,6 +10,14 @@ module GraphQL
|
|
|
10
10
|
|
|
11
11
|
include GraphQL::Dig
|
|
12
12
|
|
|
13
|
+
# Raised when an InputObject doesn't have any arguments defined and hasn't explicitly opted out of this requirement
|
|
14
|
+
class ArgumentsAreRequiredError < GraphQL::Error
|
|
15
|
+
def initialize(input_object_type)
|
|
16
|
+
message = "Input Object types must have arguments, but #{input_object_type.graphql_name} doesn't have any. Define an argument for this type, remove it from your schema, or add `has_no_arguments(true)` to its definition."
|
|
17
|
+
super(message)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
13
21
|
# @return [GraphQL::Query::Context] The context for this query
|
|
14
22
|
attr_reader :context
|
|
15
23
|
# @return [GraphQL::Execution::Interpereter::Arguments] The underlying arguments instance
|
|
@@ -23,13 +31,14 @@ module GraphQL
|
|
|
23
31
|
@ruby_style_hash = ruby_kwargs
|
|
24
32
|
@arguments = arguments
|
|
25
33
|
# Apply prepares, not great to have it duplicated here.
|
|
26
|
-
self.class.arguments(context).each_value
|
|
34
|
+
arg_defns = context ? context.types.arguments(self.class) : self.class.arguments(context).each_value
|
|
35
|
+
arg_defns.each do |arg_defn|
|
|
27
36
|
ruby_kwargs_key = arg_defn.keyword
|
|
28
37
|
if @ruby_style_hash.key?(ruby_kwargs_key)
|
|
29
38
|
# Weirdly, procs are applied during coercion, but not methods.
|
|
30
39
|
# Probably because these methods require a `self`.
|
|
31
40
|
if arg_defn.prepare.is_a?(Symbol) || context.nil?
|
|
32
|
-
prepared_value = arg_defn.prepare_value(self, @ruby_style_hash[ruby_kwargs_key])
|
|
41
|
+
prepared_value = arg_defn.prepare_value(self, @ruby_style_hash[ruby_kwargs_key], context: context)
|
|
33
42
|
overwrite_argument(ruby_kwargs_key, prepared_value)
|
|
34
43
|
end
|
|
35
44
|
end
|
|
@@ -44,42 +53,18 @@ module GraphQL
|
|
|
44
53
|
to_h
|
|
45
54
|
end
|
|
46
55
|
|
|
47
|
-
def
|
|
48
|
-
if
|
|
49
|
-
|
|
50
|
-
# Pass this object's class with `as` so that messages are rendered correctly from inherited validators
|
|
51
|
-
Schema::Validator.validate!(self.class.validators, object, @context, @ruby_style_hash, as: self.class)
|
|
52
|
-
self
|
|
56
|
+
def deconstruct_keys(keys = nil)
|
|
57
|
+
if keys.nil?
|
|
58
|
+
@ruby_style_hash
|
|
53
59
|
else
|
|
54
|
-
|
|
60
|
+
new_h = {}
|
|
61
|
+
keys.each { |k| @ruby_style_hash.key?(k) && new_h[k] = @ruby_style_hash[k] }
|
|
62
|
+
new_h
|
|
55
63
|
end
|
|
56
64
|
end
|
|
57
65
|
|
|
58
|
-
def
|
|
59
|
-
|
|
60
|
-
if value.respond_to?(:key?)
|
|
61
|
-
arguments(ctx).each do |_name, input_obj_arg|
|
|
62
|
-
if value.key?(input_obj_arg.keyword) &&
|
|
63
|
-
!input_obj_arg.authorized?(obj, value[input_obj_arg.keyword], ctx)
|
|
64
|
-
return false
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
# It didn't early-return false:
|
|
69
|
-
true
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def self.one_of
|
|
73
|
-
if !one_of?
|
|
74
|
-
if all_argument_definitions.any? { |arg| arg.type.non_null? }
|
|
75
|
-
raise ArgumentError, "`one_of` may not be used with required arguments -- add `required: false` to argument definitions to use `one_of`"
|
|
76
|
-
end
|
|
77
|
-
directive(GraphQL::Schema::Directive::OneOf)
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def self.one_of?
|
|
82
|
-
directives.any? { |d| d.is_a?(GraphQL::Schema::Directive::OneOf) }
|
|
66
|
+
def prepare
|
|
67
|
+
self
|
|
83
68
|
end
|
|
84
69
|
|
|
85
70
|
def unwrap_value(value)
|
|
@@ -119,7 +104,42 @@ module GraphQL
|
|
|
119
104
|
@ruby_style_hash.dup
|
|
120
105
|
end
|
|
121
106
|
|
|
107
|
+
# @api private
|
|
108
|
+
def validate_for(context)
|
|
109
|
+
object = context[:current_object]
|
|
110
|
+
# Pass this object's class with `as` so that messages are rendered correctly from inherited validators
|
|
111
|
+
Schema::Validator.validate!(self.class.validators, object, context, @ruby_style_hash, as: self.class)
|
|
112
|
+
nil
|
|
113
|
+
end
|
|
114
|
+
|
|
122
115
|
class << self
|
|
116
|
+
def authorized?(obj, value, ctx)
|
|
117
|
+
# Authorize each argument (but this doesn't apply if `prepare` is implemented):
|
|
118
|
+
if value.respond_to?(:key?)
|
|
119
|
+
ctx.types.arguments(self).each do |input_obj_arg|
|
|
120
|
+
if value.key?(input_obj_arg.keyword) &&
|
|
121
|
+
!input_obj_arg.authorized?(obj, value[input_obj_arg.keyword], ctx)
|
|
122
|
+
return false
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
# It didn't early-return false:
|
|
127
|
+
true
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def one_of
|
|
131
|
+
if !one_of?
|
|
132
|
+
if all_argument_definitions.any? { |arg| arg.type.non_null? }
|
|
133
|
+
raise ArgumentError, "`one_of` may not be used with required arguments -- add `required: false` to argument definitions to use `one_of`"
|
|
134
|
+
end
|
|
135
|
+
directive(GraphQL::Schema::Directive::OneOf)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def one_of?
|
|
140
|
+
false # Re-defined when `OneOf` is added
|
|
141
|
+
end
|
|
142
|
+
|
|
123
143
|
def argument(*args, **kwargs, &block)
|
|
124
144
|
argument_defn = super(*args, **kwargs, &block)
|
|
125
145
|
if one_of?
|
|
@@ -131,12 +151,9 @@ module GraphQL
|
|
|
131
151
|
end
|
|
132
152
|
end
|
|
133
153
|
# Add a method access
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
self[#{method_name.inspect}]
|
|
138
|
-
end
|
|
139
|
-
RUBY
|
|
154
|
+
suppress_redefinition_warning do
|
|
155
|
+
define_accessor_method(argument_defn.keyword)
|
|
156
|
+
end
|
|
140
157
|
argument_defn
|
|
141
158
|
end
|
|
142
159
|
|
|
@@ -145,10 +162,10 @@ module GraphQL
|
|
|
145
162
|
end
|
|
146
163
|
|
|
147
164
|
# @api private
|
|
148
|
-
INVALID_OBJECT_MESSAGE = "Expected %{object} to be a key-value object
|
|
165
|
+
INVALID_OBJECT_MESSAGE = "Expected %{object} to be a key-value object."
|
|
149
166
|
|
|
150
167
|
def validate_non_null_input(input, ctx, max_errors: nil)
|
|
151
|
-
|
|
168
|
+
types = ctx.types
|
|
152
169
|
|
|
153
170
|
if input.is_a?(Array)
|
|
154
171
|
return GraphQL::Query::InputValidationResult.from_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
|
|
@@ -159,30 +176,37 @@ module GraphQL
|
|
|
159
176
|
return GraphQL::Query::InputValidationResult.from_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
|
|
160
177
|
end
|
|
161
178
|
|
|
162
|
-
# Inject missing required arguments
|
|
163
|
-
missing_required_inputs = self.arguments(ctx).reduce({}) do |m, (argument_name, argument)|
|
|
164
|
-
if !input.key?(argument_name) && argument.type.non_null? && warden.get_argument(self, argument_name)
|
|
165
|
-
m[argument_name] = nil
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
m
|
|
169
|
-
end
|
|
170
179
|
|
|
171
180
|
result = nil
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
input.each do |argument_name, value|
|
|
184
|
+
argument = types.argument(self, argument_name)
|
|
185
|
+
if argument.nil? && ctx.is_a?(Query::NullContext) && argument_name.is_a?(Symbol)
|
|
186
|
+
# Validating definition directive arguments which come in as Symbols
|
|
187
|
+
argument = types.arguments(self).find { |arg| arg.keyword == argument_name }
|
|
188
|
+
end
|
|
189
|
+
# Items in the input that are unexpected
|
|
190
|
+
if argument.nil?
|
|
191
|
+
result ||= Query::InputValidationResult.new
|
|
192
|
+
result.add_problem("Field is not defined on #{self.graphql_name}", [argument_name])
|
|
193
|
+
else
|
|
194
|
+
# Items in the input that are expected, but have invalid values
|
|
195
|
+
argument_result = argument.type.validate_input(value, ctx)
|
|
196
|
+
if !argument_result.valid?
|
|
182
197
|
result ||= Query::InputValidationResult.new
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
198
|
+
result.merge_result!(argument_name, argument_result)
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Check for missing non-null arguments
|
|
204
|
+
ctx.types.arguments(self).each do |argument|
|
|
205
|
+
if !input.key?(argument.graphql_name) && argument.type.non_null? && !argument.default_value?
|
|
206
|
+
result ||= Query::InputValidationResult.new
|
|
207
|
+
argument_result = argument.type.validate_input(nil, ctx)
|
|
208
|
+
if !argument_result.valid?
|
|
209
|
+
result.merge_result!(argument.graphql_name, argument_result)
|
|
186
210
|
end
|
|
187
211
|
end
|
|
188
212
|
end
|
|
@@ -215,8 +239,7 @@ module GraphQL
|
|
|
215
239
|
if resolved_arguments.is_a?(GraphQL::Error)
|
|
216
240
|
raise resolved_arguments
|
|
217
241
|
else
|
|
218
|
-
|
|
219
|
-
input_obj_instance.prepare
|
|
242
|
+
self.new(resolved_arguments, ruby_kwargs: resolved_arguments.keyword_arguments, context: ctx, defaults_used: nil)
|
|
220
243
|
end
|
|
221
244
|
end
|
|
222
245
|
end
|
|
@@ -242,6 +265,41 @@ module GraphQL
|
|
|
242
265
|
|
|
243
266
|
result
|
|
244
267
|
end
|
|
268
|
+
|
|
269
|
+
# @param new_has_no_arguments [Boolean] Call with `true` to make this InputObject type ignore the requirement to have any defined arguments.
|
|
270
|
+
# @return [void]
|
|
271
|
+
def has_no_arguments(new_has_no_arguments)
|
|
272
|
+
@has_no_arguments = new_has_no_arguments
|
|
273
|
+
nil
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# @return [Boolean] `true` if `has_no_arguments(true)` was configued
|
|
277
|
+
def has_no_arguments?
|
|
278
|
+
@has_no_arguments
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def arguments(context = GraphQL::Query::NullContext.instance, require_defined_arguments = true)
|
|
282
|
+
if require_defined_arguments && !has_no_arguments? && !any_arguments?
|
|
283
|
+
warn(GraphQL::Schema::InputObject::ArgumentsAreRequiredError.new(self).message + "\n\nThis will raise an error in a future GraphQL-Ruby version.")
|
|
284
|
+
end
|
|
285
|
+
super(context, false)
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
private
|
|
289
|
+
|
|
290
|
+
# Suppress redefinition warning for objectId arguments
|
|
291
|
+
def suppress_redefinition_warning
|
|
292
|
+
verbose = $VERBOSE
|
|
293
|
+
$VERBOSE = nil
|
|
294
|
+
yield
|
|
295
|
+
ensure
|
|
296
|
+
$VERBOSE = verbose
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def define_accessor_method(method_name)
|
|
300
|
+
define_method(method_name) { self[method_name] }
|
|
301
|
+
alias_method(method_name, method_name)
|
|
302
|
+
end
|
|
245
303
|
end
|
|
246
304
|
|
|
247
305
|
private
|
|
@@ -13,6 +13,7 @@ module GraphQL
|
|
|
13
13
|
include GraphQL::Schema::Member::Scoped
|
|
14
14
|
include GraphQL::Schema::Member::HasAstNode
|
|
15
15
|
include GraphQL::Schema::Member::HasUnresolvedTypeError
|
|
16
|
+
include GraphQL::Schema::Member::HasDataloader
|
|
16
17
|
include GraphQL::Schema::Member::HasDirectives
|
|
17
18
|
include GraphQL::Schema::Member::HasInterfaces
|
|
18
19
|
|
|
@@ -20,7 +21,36 @@ module GraphQL
|
|
|
20
21
|
# - Added as class methods to this interface
|
|
21
22
|
# - Added as class methods to all child interfaces
|
|
22
23
|
def definition_methods(&block)
|
|
23
|
-
|
|
24
|
+
# Use an instance variable to tell whether it's been included previously or not;
|
|
25
|
+
# You can't use constant detection because constants are brought into scope
|
|
26
|
+
# by `include`, which has already happened at this point.
|
|
27
|
+
if !defined?(@_definition_methods)
|
|
28
|
+
defn_methods_module = Module.new
|
|
29
|
+
@_definition_methods = defn_methods_module
|
|
30
|
+
const_set(:DefinitionMethods, defn_methods_module)
|
|
31
|
+
extend(self::DefinitionMethods)
|
|
32
|
+
end
|
|
33
|
+
self::DefinitionMethods.module_exec(&block)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Instance methods defined in this block will become class methods on objects that implement this interface.
|
|
37
|
+
# Use it to implement `resolve_each:`, `resolve_batch:`, and `resolve_static:` fields.
|
|
38
|
+
# @example
|
|
39
|
+
# field :thing, String, resolve_static: true
|
|
40
|
+
#
|
|
41
|
+
# resolver_methods do
|
|
42
|
+
# def thing
|
|
43
|
+
# Somehow.get.thing
|
|
44
|
+
# end
|
|
45
|
+
# end
|
|
46
|
+
def resolver_methods(&block)
|
|
47
|
+
if !defined?(@_resolver_methods)
|
|
48
|
+
resolver_methods_module = Module.new
|
|
49
|
+
@_resolver_methods = resolver_methods_module
|
|
50
|
+
const_set(:ResolverMethods, resolver_methods_module)
|
|
51
|
+
extend(self::ResolverMethods)
|
|
52
|
+
end
|
|
53
|
+
self::ResolverMethods.module_exec(&block)
|
|
24
54
|
end
|
|
25
55
|
|
|
26
56
|
# @see {Schema::Warden} hides interfaces without visible implementations
|
|
@@ -47,22 +77,14 @@ module GraphQL
|
|
|
47
77
|
|
|
48
78
|
child_class.type_membership_class(self.type_membership_class)
|
|
49
79
|
child_class.ancestors.reverse_each do |ancestor|
|
|
50
|
-
if ancestor.const_defined?(:DefinitionMethods)
|
|
80
|
+
if ancestor.const_defined?(:DefinitionMethods) && ancestor != child_class
|
|
51
81
|
child_class.extend(ancestor::DefinitionMethods)
|
|
52
82
|
end
|
|
53
83
|
end
|
|
54
84
|
|
|
55
|
-
# Use an instance variable to tell whether it's been included previously or not;
|
|
56
|
-
# You can't use constant detection because constants are brought into scope
|
|
57
|
-
# by `include`, which has already happened at this point.
|
|
58
|
-
if !child_class.instance_variable_defined?(:@_definition_methods)
|
|
59
|
-
defn_methods_module = Module.new
|
|
60
|
-
child_class.instance_variable_set(:@_definition_methods, defn_methods_module)
|
|
61
|
-
child_class.const_set(:DefinitionMethods, defn_methods_module)
|
|
62
|
-
child_class.extend(child_class::DefinitionMethods)
|
|
63
|
-
end
|
|
64
85
|
child_class.introspection(introspection)
|
|
65
86
|
child_class.description(description)
|
|
87
|
+
child_class.comment(nil)
|
|
66
88
|
# If interfaces are mixed into each other, only define this class once
|
|
67
89
|
if !child_class.const_defined?(:UnresolvedTypeError, false)
|
|
68
90
|
add_unresolved_type_error(child_class)
|
|
@@ -77,18 +99,40 @@ module GraphQL
|
|
|
77
99
|
if !backtrace_line
|
|
78
100
|
raise "Attach interfaces using `implements(#{self})`, not `include(#{self})`"
|
|
79
101
|
end
|
|
102
|
+
|
|
103
|
+
child_class.ancestors.reverse_each do |ancestor|
|
|
104
|
+
if ancestor.const_defined?(:ResolverMethods)
|
|
105
|
+
child_class.extend(ancestor::ResolverMethods)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
80
108
|
end
|
|
81
109
|
|
|
82
110
|
super
|
|
83
111
|
end
|
|
84
112
|
|
|
113
|
+
# Register other Interface or Object types as implementers of this Interface.
|
|
114
|
+
#
|
|
115
|
+
# When those Interfaces or Objects aren't used as the return values of fields,
|
|
116
|
+
# they may have to be registered using this method so that GraphQL-Ruby can find them.
|
|
117
|
+
# @param types [Class, Module]
|
|
118
|
+
# @return [Array<Module, Class>] Implementers of this interface, if they're registered
|
|
85
119
|
def orphan_types(*types)
|
|
86
|
-
if types.
|
|
87
|
-
@orphan_types
|
|
120
|
+
if !types.empty?
|
|
121
|
+
@orphan_types ||= []
|
|
122
|
+
@orphan_types.concat(types)
|
|
88
123
|
else
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
124
|
+
if defined?(@orphan_types)
|
|
125
|
+
all_orphan_types = @orphan_types.dup
|
|
126
|
+
if defined?(super)
|
|
127
|
+
all_orphan_types += super
|
|
128
|
+
all_orphan_types.uniq!
|
|
129
|
+
end
|
|
130
|
+
all_orphan_types
|
|
131
|
+
elsif defined?(super)
|
|
132
|
+
super
|
|
133
|
+
else
|
|
134
|
+
EmptyObjects::EMPTY_ARRAY
|
|
135
|
+
end
|
|
92
136
|
end
|
|
93
137
|
end
|
|
94
138
|
|
|
@@ -25,10 +25,10 @@ module GraphQL
|
|
|
25
25
|
load_constant(:DirectiveLocationEnum)
|
|
26
26
|
]
|
|
27
27
|
@types = {}
|
|
28
|
-
@possible_types = {}
|
|
28
|
+
@possible_types = {}.compare_by_identity
|
|
29
29
|
type_defns.each do |t|
|
|
30
30
|
@types[t.graphql_name] = t
|
|
31
|
-
@possible_types[t
|
|
31
|
+
@possible_types[t] = [t]
|
|
32
32
|
end
|
|
33
33
|
@entry_point_fields =
|
|
34
34
|
if schema.disable_introspection_entry_points?
|
|
@@ -39,7 +39,9 @@ module GraphQL
|
|
|
39
39
|
entry_point_fields.delete('__type') if schema.disable_type_introspection_entry_point?
|
|
40
40
|
entry_point_fields
|
|
41
41
|
end
|
|
42
|
+
@entry_point_fields.each { |k, v| v.dynamic_introspection = true }
|
|
42
43
|
@dynamic_fields = get_fields_from_class(class_sym: :DynamicFields)
|
|
44
|
+
@dynamic_fields.each { |k, v| v.dynamic_introspection = true }
|
|
43
45
|
end
|
|
44
46
|
|
|
45
47
|
def entry_points
|
|
@@ -67,7 +69,7 @@ module GraphQL
|
|
|
67
69
|
def resolve_late_bindings
|
|
68
70
|
@types.each do |name, t|
|
|
69
71
|
if t.kind.fields?
|
|
70
|
-
t.
|
|
72
|
+
t.all_field_definitions.each do |field_defn|
|
|
71
73
|
field_defn.type = resolve_late_binding(field_defn.type)
|
|
72
74
|
end
|
|
73
75
|
end
|
|
@@ -88,7 +90,8 @@ module GraphQL
|
|
|
88
90
|
def resolve_late_binding(late_bound_type)
|
|
89
91
|
case late_bound_type
|
|
90
92
|
when GraphQL::Schema::LateBoundType
|
|
91
|
-
|
|
93
|
+
type_name = late_bound_type.name
|
|
94
|
+
@types[type_name] || @schema.get_type(type_name)
|
|
92
95
|
when GraphQL::Schema::List
|
|
93
96
|
resolve_late_binding(late_bound_type.of_type).to_list_type
|
|
94
97
|
when GraphQL::Schema::NonNull
|
|
@@ -111,19 +114,7 @@ module GraphQL
|
|
|
111
114
|
|
|
112
115
|
def get_fields_from_class(class_sym:)
|
|
113
116
|
object_type_defn = load_constant(class_sym)
|
|
114
|
-
|
|
115
|
-
if object_type_defn.is_a?(Module)
|
|
116
|
-
object_type_defn.fields
|
|
117
|
-
else
|
|
118
|
-
extracted_field_defns = {}
|
|
119
|
-
object_class = object_type_defn.metadata[:type_class]
|
|
120
|
-
object_type_defn.all_fields.each do |field_defn|
|
|
121
|
-
inner_resolve = field_defn.resolve_proc
|
|
122
|
-
resolve_with_instantiate = PerFieldProxyResolve.new(object_class: object_class, inner_resolve: inner_resolve)
|
|
123
|
-
extracted_field_defns[field_defn.name] = field_defn.redefine(resolve: resolve_with_instantiate)
|
|
124
|
-
end
|
|
125
|
-
extracted_field_defns
|
|
126
|
-
end
|
|
117
|
+
object_type_defn.fields
|
|
127
118
|
end
|
|
128
119
|
|
|
129
120
|
# This is probably not 100% robust -- but it has to be good enough to avoid modifying the built-in introspection types
|
data/lib/graphql/schema/list.rb
CHANGED
|
@@ -4,7 +4,7 @@ module GraphQL
|
|
|
4
4
|
class Schema
|
|
5
5
|
# Represents a list type in the schema.
|
|
6
6
|
# Wraps a {Schema::Member} as a list type.
|
|
7
|
-
# @see
|
|
7
|
+
# @see Schema::Member::TypeSystemHelpers#to_list_type Create a list type from another GraphQL type
|
|
8
8
|
class List < GraphQL::Schema::Wrapper
|
|
9
9
|
include Schema::Member::ValidatesInput
|
|
10
10
|
|
|
@@ -19,7 +19,11 @@ module GraphQL
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def to_type_signature
|
|
22
|
-
"[#{@of_type.to_type_signature}]"
|
|
22
|
+
@type_signature ||= -"[#{@of_type.to_type_signature}]"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def authorizes?(ctx)
|
|
26
|
+
of_type.authorizes?(ctx)
|
|
23
27
|
end
|
|
24
28
|
|
|
25
29
|
# This is for introspection, where it's expected the name will be `null`
|
|
@@ -52,7 +56,7 @@ module GraphQL
|
|
|
52
56
|
unless item_result.valid?
|
|
53
57
|
if max_errors
|
|
54
58
|
if max_errors == 0
|
|
55
|
-
|
|
59
|
+
add_max_errors_reached_message(result)
|
|
56
60
|
break
|
|
57
61
|
end
|
|
58
62
|
|
|
@@ -76,7 +80,7 @@ module GraphQL
|
|
|
76
80
|
end
|
|
77
81
|
end
|
|
78
82
|
|
|
79
|
-
def
|
|
83
|
+
def add_max_errors_reached_message(result)
|
|
80
84
|
message = "Too many errors processing list variable, max validation error limit reached. Execution aborted"
|
|
81
85
|
item_result = GraphQL::Query::InputValidationResult.from_problem(message)
|
|
82
86
|
result.merge_result!(nil, item_result)
|
|
@@ -32,7 +32,8 @@ module GraphQL
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
Class.new(GraphQL::Schema) do
|
|
35
|
-
|
|
35
|
+
add_type_and_traverse(types.values, root: false)
|
|
36
|
+
orphan_types(types.values.select { |t| t.kind.object? })
|
|
36
37
|
directives(directives)
|
|
37
38
|
description(schema["description"])
|
|
38
39
|
|
|
@@ -176,7 +177,6 @@ module GraphQL
|
|
|
176
177
|
while (of_type = unwrapped_field_hash["ofType"])
|
|
177
178
|
unwrapped_field_hash = of_type
|
|
178
179
|
end
|
|
179
|
-
type_name = unwrapped_field_hash["name"]
|
|
180
180
|
|
|
181
181
|
type_defn.field(
|
|
182
182
|
field_hash["name"],
|
|
@@ -186,9 +186,8 @@ module GraphQL
|
|
|
186
186
|
null: true,
|
|
187
187
|
camelize: false,
|
|
188
188
|
connection_extension: nil,
|
|
189
|
-
connection: type_name.end_with?("Connection"),
|
|
190
189
|
) do
|
|
191
|
-
if field_hash["args"].
|
|
190
|
+
if !field_hash["args"].empty?
|
|
192
191
|
loader.build_arguments(self, field_hash["args"], type_resolver)
|
|
193
192
|
end
|
|
194
193
|
end
|