graphql 2.0.32 → 2.5.22
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 +95 -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/interpreter/argument_value.rb +5 -1
- data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
- 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 +363 -434
- data/lib/graphql/execution/interpreter.rb +91 -164
- data/lib/graphql/execution/lookahead.rb +105 -31
- data/lib/graphql/execution/multiplex.rb +7 -6
- data/lib/graphql/execution/next/field_resolve_step.rb +711 -0
- data/lib/graphql/execution/next/load_argument_step.rb +60 -0
- data/lib/graphql/execution/next/prepare_object_step.rb +129 -0
- data/lib/graphql/execution/next/runner.rb +389 -0
- data/lib/graphql/execution/next/selections_step.rb +37 -0
- data/lib/graphql/execution/next.rb +70 -0
- data/lib/graphql/execution.rb +1 -0
- data/lib/graphql/execution_error.rb +13 -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 +319 -193
- data/lib/graphql/language/nodes.rb +136 -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 +23 -83
- 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 +82 -144
- data/lib/graphql/query/null_context.rb +15 -18
- data/lib/graphql/query/partial.rb +179 -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 +126 -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/schema/addition.rb +26 -13
- data/lib/graphql/schema/always_visible.rb +7 -2
- data/lib/graphql/schema/argument.rb +75 -9
- data/lib/graphql/schema/base_64_encoder.rb +3 -5
- data/lib/graphql/schema/build_from_definition.rb +123 -60
- 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 +54 -2
- data/lib/graphql/schema/enum.rb +110 -27
- data/lib/graphql/schema/enum_value.rb +10 -2
- data/lib/graphql/schema/field/connection_extension.rb +15 -49
- data/lib/graphql/schema/field/scope_extension.rb +23 -7
- data/lib/graphql/schema/field.rb +245 -118
- data/lib/graphql/schema/field_extension.rb +34 -1
- data/lib/graphql/schema/has_single_input_argument.rb +160 -0
- data/lib/graphql/schema/input_object.rb +116 -60
- data/lib/graphql/schema/interface.rb +34 -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 +3 -3
- data/lib/graphql/schema/loader.rb +3 -4
- data/lib/graphql/schema/member/base_dsl_methods.rb +18 -2
- 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 +4 -4
- data/lib/graphql/schema/member/has_fields.rb +115 -15
- data/lib/graphql/schema/member/has_interfaces.rb +26 -12
- 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 +17 -4
- 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/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 +90 -32
- data/lib/graphql/schema/scalar.rb +4 -9
- data/lib/graphql/schema/subscription.rb +63 -10
- 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 +445 -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.rb +950 -210
- data/lib/graphql/static_validation/all_rules.rb +3 -3
- data/lib/graphql/static_validation/base_visitor.rb +7 -6
- data/lib/graphql/static_validation/literal_validator.rb +6 -7
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
- data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +1 -1
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +3 -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 +12 -2
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +47 -13
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +88 -25
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +10 -2
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +12 -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 +5 -5
- 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 +11 -2
- data/lib/graphql/static_validation/validation_context.rb +21 -5
- 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 +12 -10
- data/lib/graphql/subscriptions/event.rb +21 -4
- data/lib/graphql/subscriptions/serialize.rb +3 -1
- data/lib/graphql/subscriptions.rb +21 -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 +7 -3
- data/lib/graphql/tracing/appoptics_tracing.rb +9 -2
- data/lib/graphql/tracing/appsignal_trace.rb +32 -59
- 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 -162
- 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 +183 -37
- 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_tracing.rb +3 -1
- data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +5 -1
- data/lib/graphql/tracing/prometheus_trace.rb +73 -73
- data/lib/graphql/tracing/prometheus_tracing.rb +2 -0
- data/lib/graphql/tracing/scout_trace.rb +32 -58
- 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 -45
- data/lib/graphql/tracing/statsd_tracing.rb +2 -0
- data/lib/graphql/tracing/trace.rb +112 -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 +44 -2
- data/lib/graphql/types/relay/edge_behaviors.rb +18 -0
- 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 +5 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +71 -54
- data/readme.md +12 -2
- metadata +233 -37
- 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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def self.authorized?(obj, value, ctx)
|
|
59
|
-
# Authorize each argument (but this doesn't apply if `prepare` is implemented):
|
|
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
|
|
60
|
+
new_h = {}
|
|
61
|
+
keys.each { |k| @ruby_style_hash.key?(k) && new_h[k] = @ruby_style_hash[k] }
|
|
62
|
+
new_h
|
|
67
63
|
end
|
|
68
|
-
# It didn't early-return false:
|
|
69
|
-
true
|
|
70
64
|
end
|
|
71
65
|
|
|
72
|
-
def
|
|
73
|
-
|
|
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,7 +151,9 @@ module GraphQL
|
|
|
131
151
|
end
|
|
132
152
|
end
|
|
133
153
|
# Add a method access
|
|
134
|
-
|
|
154
|
+
suppress_redefinition_warning do
|
|
155
|
+
define_accessor_method(argument_defn.keyword)
|
|
156
|
+
end
|
|
135
157
|
argument_defn
|
|
136
158
|
end
|
|
137
159
|
|
|
@@ -140,10 +162,10 @@ module GraphQL
|
|
|
140
162
|
end
|
|
141
163
|
|
|
142
164
|
# @api private
|
|
143
|
-
INVALID_OBJECT_MESSAGE = "Expected %{object} to be a key-value object
|
|
165
|
+
INVALID_OBJECT_MESSAGE = "Expected %{object} to be a key-value object."
|
|
144
166
|
|
|
145
167
|
def validate_non_null_input(input, ctx, max_errors: nil)
|
|
146
|
-
|
|
168
|
+
types = ctx.types
|
|
147
169
|
|
|
148
170
|
if input.is_a?(Array)
|
|
149
171
|
return GraphQL::Query::InputValidationResult.from_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
|
|
@@ -154,30 +176,37 @@ module GraphQL
|
|
|
154
176
|
return GraphQL::Query::InputValidationResult.from_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
|
|
155
177
|
end
|
|
156
178
|
|
|
157
|
-
# Inject missing required arguments
|
|
158
|
-
missing_required_inputs = self.arguments(ctx).reduce({}) do |m, (argument_name, argument)|
|
|
159
|
-
if !input.key?(argument_name) && argument.type.non_null? && warden.get_argument(self, argument_name)
|
|
160
|
-
m[argument_name] = nil
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
m
|
|
164
|
-
end
|
|
165
179
|
|
|
166
180
|
result = nil
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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?
|
|
177
197
|
result ||= Query::InputValidationResult.new
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
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)
|
|
181
210
|
end
|
|
182
211
|
end
|
|
183
212
|
end
|
|
@@ -210,8 +239,7 @@ module GraphQL
|
|
|
210
239
|
if resolved_arguments.is_a?(GraphQL::Error)
|
|
211
240
|
raise resolved_arguments
|
|
212
241
|
else
|
|
213
|
-
|
|
214
|
-
input_obj_instance.prepare
|
|
242
|
+
self.new(resolved_arguments, ruby_kwargs: resolved_arguments.keyword_arguments, context: ctx, defaults_used: nil)
|
|
215
243
|
end
|
|
216
244
|
end
|
|
217
245
|
end
|
|
@@ -238,8 +266,36 @@ module GraphQL
|
|
|
238
266
|
result
|
|
239
267
|
end
|
|
240
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
|
+
|
|
241
288
|
private
|
|
242
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
|
+
|
|
243
299
|
def define_accessor_method(method_name)
|
|
244
300
|
define_method(method_name) { self[method_name] }
|
|
245
301
|
alias_method(method_name, method_name)
|
|
@@ -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,16 @@ 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)
|
|
24
34
|
end
|
|
25
35
|
|
|
26
36
|
# @see {Schema::Warden} hides interfaces without visible implementations
|
|
@@ -47,22 +57,14 @@ module GraphQL
|
|
|
47
57
|
|
|
48
58
|
child_class.type_membership_class(self.type_membership_class)
|
|
49
59
|
child_class.ancestors.reverse_each do |ancestor|
|
|
50
|
-
if ancestor.const_defined?(:DefinitionMethods)
|
|
60
|
+
if ancestor.const_defined?(:DefinitionMethods) && ancestor != child_class
|
|
51
61
|
child_class.extend(ancestor::DefinitionMethods)
|
|
52
62
|
end
|
|
53
63
|
end
|
|
54
64
|
|
|
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
65
|
child_class.introspection(introspection)
|
|
65
66
|
child_class.description(description)
|
|
67
|
+
child_class.comment(nil)
|
|
66
68
|
# If interfaces are mixed into each other, only define this class once
|
|
67
69
|
if !child_class.const_defined?(:UnresolvedTypeError, false)
|
|
68
70
|
add_unresolved_type_error(child_class)
|
|
@@ -82,13 +84,29 @@ module GraphQL
|
|
|
82
84
|
super
|
|
83
85
|
end
|
|
84
86
|
|
|
87
|
+
# Register other Interface or Object types as implementers of this Interface.
|
|
88
|
+
#
|
|
89
|
+
# When those Interfaces or Objects aren't used as the return values of fields,
|
|
90
|
+
# they may have to be registered using this method so that GraphQL-Ruby can find them.
|
|
91
|
+
# @param types [Class, Module]
|
|
92
|
+
# @return [Array<Module, Class>] Implementers of this interface, if they're registered
|
|
85
93
|
def orphan_types(*types)
|
|
86
|
-
if types.
|
|
87
|
-
@orphan_types
|
|
94
|
+
if !types.empty?
|
|
95
|
+
@orphan_types ||= []
|
|
96
|
+
@orphan_types.concat(types)
|
|
88
97
|
else
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
98
|
+
if defined?(@orphan_types)
|
|
99
|
+
all_orphan_types = @orphan_types.dup
|
|
100
|
+
if defined?(super)
|
|
101
|
+
all_orphan_types += super
|
|
102
|
+
all_orphan_types.uniq!
|
|
103
|
+
end
|
|
104
|
+
all_orphan_types
|
|
105
|
+
elsif defined?(super)
|
|
106
|
+
super
|
|
107
|
+
else
|
|
108
|
+
EmptyObjects::EMPTY_ARRAY
|
|
109
|
+
end
|
|
92
110
|
end
|
|
93
111
|
end
|
|
94
112
|
|
|
@@ -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
|
|
|
@@ -52,7 +52,7 @@ module GraphQL
|
|
|
52
52
|
unless item_result.valid?
|
|
53
53
|
if max_errors
|
|
54
54
|
if max_errors == 0
|
|
55
|
-
|
|
55
|
+
add_max_errors_reached_message(result)
|
|
56
56
|
break
|
|
57
57
|
end
|
|
58
58
|
|
|
@@ -76,7 +76,7 @@ module GraphQL
|
|
|
76
76
|
end
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
-
def
|
|
79
|
+
def add_max_errors_reached_message(result)
|
|
80
80
|
message = "Too many errors processing list variable, max validation error limit reached. Execution aborted"
|
|
81
81
|
item_result = GraphQL::Query::InputValidationResult.from_problem(message)
|
|
82
82
|
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
|
|
@@ -50,12 +50,27 @@ module GraphQL
|
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
# Call this method to provide a new comment; OR
|
|
54
|
+
# call it without an argument to get the comment
|
|
55
|
+
# @param new_comment [String]
|
|
56
|
+
# @return [String, nil]
|
|
57
|
+
def comment(new_comment = NOT_CONFIGURED)
|
|
58
|
+
if !NOT_CONFIGURED.equal?(new_comment)
|
|
59
|
+
@comment = new_comment
|
|
60
|
+
elsif defined?(@comment)
|
|
61
|
+
@comment
|
|
62
|
+
else
|
|
63
|
+
nil
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
53
67
|
# This pushes some configurations _down_ the inheritance tree,
|
|
54
68
|
# in order to prevent repetitive lookups at runtime.
|
|
55
69
|
module ConfigurationExtension
|
|
56
70
|
def inherited(child_class)
|
|
57
71
|
child_class.introspection(introspection)
|
|
58
72
|
child_class.description(description)
|
|
73
|
+
child_class.comment(nil)
|
|
59
74
|
child_class.default_graphql_name = nil
|
|
60
75
|
|
|
61
76
|
if defined?(@graphql_name) && @graphql_name && (self.name.nil? || graphql_name != default_graphql_name)
|
|
@@ -102,7 +117,8 @@ module GraphQL
|
|
|
102
117
|
def default_graphql_name
|
|
103
118
|
@default_graphql_name ||= begin
|
|
104
119
|
raise GraphQL::RequiredImplementationMissingError, 'Anonymous class should declare a `graphql_name`' if name.nil?
|
|
105
|
-
-name.split("::").last
|
|
120
|
+
g_name = -name.split("::").last
|
|
121
|
+
g_name.end_with?("Type") ? g_name.sub(/Type\Z/, "") : g_name
|
|
106
122
|
end
|
|
107
123
|
end
|
|
108
124
|
|
|
@@ -114,7 +130,7 @@ module GraphQL
|
|
|
114
130
|
true
|
|
115
131
|
end
|
|
116
132
|
|
|
117
|
-
def default_relay
|
|
133
|
+
def default_relay?
|
|
118
134
|
false
|
|
119
135
|
end
|
|
120
136
|
|