graphql 2.2.17 → 2.5.16
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/install/mutation_root_generator.rb +2 -2
- data/lib/generators/graphql/install_generator.rb +46 -0
- data/lib/generators/graphql/orm_mutations_base.rb +1 -1
- data/lib/generators/graphql/templates/base_resolver.erb +2 -0
- data/lib/generators/graphql/templates/schema.erb +3 -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/{ast/query_depth.rb → query_depth.rb} +23 -25
- 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/current.rb +57 -0
- data/lib/graphql/dashboard/detailed_traces.rb +47 -0
- data/lib/graphql/dashboard/installable.rb +22 -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/subscriptions.rb +96 -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 +23 -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 +158 -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 +46 -19
- data/lib/graphql/dataloader/null_dataloader.rb +51 -10
- data/lib/graphql/dataloader/source.rb +20 -9
- data/lib/graphql/dataloader.rb +153 -45
- data/lib/graphql/date_encoding_error.rb +1 -1
- data/lib/graphql/dig.rb +2 -1
- 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 +63 -5
- data/lib/graphql/execution/interpreter/runtime.rb +321 -222
- data/lib/graphql/execution/interpreter.rb +23 -30
- data/lib/graphql/execution/lookahead.rb +18 -11
- data/lib/graphql/execution/multiplex.rb +6 -5
- data/lib/graphql/introspection/directive_location_enum.rb +1 -1
- data/lib/graphql/introspection/directive_type.rb +1 -1
- data/lib/graphql/introspection/entry_points.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +1 -1
- data/lib/graphql/introspection/schema_type.rb +6 -11
- data/lib/graphql/introspection/type_type.rb +5 -5
- data/lib/graphql/invalid_name_error.rb +1 -1
- data/lib/graphql/invalid_null_error.rb +20 -17
- data/lib/graphql/language/cache.rb +13 -0
- data/lib/graphql/language/comment.rb +18 -0
- data/lib/graphql/language/document_from_schema_definition.rb +64 -35
- data/lib/graphql/language/lexer.rb +72 -42
- data/lib/graphql/language/nodes.rb +93 -52
- data/lib/graphql/language/parser.rb +168 -61
- data/lib/graphql/language/printer.rb +31 -15
- data/lib/graphql/language/sanitized_printer.rb +1 -1
- data/lib/graphql/language.rb +61 -1
- data/lib/graphql/pagination/connection.rb +1 -1
- data/lib/graphql/query/context/scoped_context.rb +1 -1
- data/lib/graphql/query/context.rb +46 -47
- data/lib/graphql/query/null_context.rb +3 -5
- data/lib/graphql/query/partial.rb +179 -0
- data/lib/graphql/query/validation_pipeline.rb +2 -2
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/query.rb +123 -69
- data/lib/graphql/railtie.rb +7 -0
- 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 +57 -8
- data/lib/graphql/schema/build_from_definition.rb +116 -49
- data/lib/graphql/schema/directive/flagged.rb +4 -2
- data/lib/graphql/schema/directive.rb +54 -2
- data/lib/graphql/schema/enum.rb +107 -24
- data/lib/graphql/schema/enum_value.rb +10 -2
- data/lib/graphql/schema/field/connection_extension.rb +1 -1
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +134 -45
- data/lib/graphql/schema/field_extension.rb +1 -1
- data/lib/graphql/schema/has_single_input_argument.rb +6 -2
- data/lib/graphql/schema/input_object.rb +122 -64
- data/lib/graphql/schema/interface.rb +23 -5
- data/lib/graphql/schema/introspection_system.rb +6 -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 -2
- data/lib/graphql/schema/member/base_dsl_methods.rb +15 -0
- data/lib/graphql/schema/member/has_arguments.rb +44 -58
- data/lib/graphql/schema/member/has_dataloader.rb +62 -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 +26 -6
- data/lib/graphql/schema/member/has_interfaces.rb +6 -6
- 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/type_system_helpers.rb +17 -4
- data/lib/graphql/schema/member.rb +1 -0
- data/lib/graphql/schema/mutation.rb +7 -0
- data/lib/graphql/schema/object.rb +25 -8
- data/lib/graphql/schema/printer.rb +1 -0
- data/lib/graphql/schema/ractor_shareable.rb +79 -0
- data/lib/graphql/schema/relay_classic_mutation.rb +0 -1
- data/lib/graphql/schema/resolver.rb +29 -23
- data/lib/graphql/schema/scalar.rb +1 -6
- data/lib/graphql/schema/subscription.rb +52 -6
- data/lib/graphql/schema/timeout.rb +19 -2
- data/lib/graphql/schema/type_expression.rb +2 -2
- data/lib/graphql/schema/union.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 +190 -20
- data/lib/graphql/schema.rb +695 -167
- data/lib/graphql/static_validation/all_rules.rb +2 -2
- data/lib/graphql/static_validation/base_visitor.rb +6 -5
- data/lib/graphql/static_validation/literal_validator.rb +4 -4
- 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 +4 -4
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +3 -3
- 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 +18 -2
- data/lib/graphql/static_validation/validator.rb +6 -1
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +5 -3
- 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 +13 -2
- data/lib/graphql/subscriptions/serialize.rb +1 -1
- data/lib/graphql/subscriptions.rb +7 -5
- data/lib/graphql/testing/helpers.rb +48 -16
- data/lib/graphql/testing/mock_action_cable.rb +111 -0
- data/lib/graphql/testing.rb +1 -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 +5 -1
- data/lib/graphql/tracing/appoptics_tracing.rb +7 -0
- 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/memory_backend.rb +60 -0
- data/lib/graphql/tracing/detailed_trace/redis_backend.rb +72 -0
- data/lib/graphql/tracing/detailed_trace.rb +141 -0
- data/lib/graphql/tracing/legacy_hooks_trace.rb +1 -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 +818 -0
- data/lib/graphql/tracing/platform_tracing.rb +1 -1
- data/lib/graphql/tracing/prometheus_trace/graphql_collector.rb +2 -0
- 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 +64 -98
- data/lib/graphql/tracing/statsd_trace.rb +33 -45
- data/lib/graphql/tracing/statsd_tracing.rb +2 -0
- data/lib/graphql/tracing/trace.rb +111 -1
- data/lib/graphql/tracing.rb +31 -30
- data/lib/graphql/type_kinds.rb +2 -1
- data/lib/graphql/types/relay/connection_behaviors.rb +12 -2
- data/lib/graphql/types/relay/edge_behaviors.rb +11 -1
- data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
- data/lib/graphql/types.rb +18 -11
- data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +64 -54
- metadata +197 -22
- data/lib/graphql/analysis/ast/analyzer.rb +0 -91
- data/lib/graphql/analysis/ast/field_usage.rb +0 -82
- 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 -182
- data/lib/graphql/analysis/ast/visitor.rb +0 -276
- data/lib/graphql/analysis/ast.rb +0 -94
- data/lib/graphql/backtrace/inspect_result.rb +0 -50
- data/lib/graphql/backtrace/trace.rb +0 -93
- data/lib/graphql/backtrace/tracer.rb +0 -80
- data/lib/graphql/language/token.rb +0 -34
- 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
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require "graphql/schema/visibility/profile"
|
|
3
|
+
require "graphql/schema/visibility/migration"
|
|
4
|
+
require "graphql/schema/visibility/visit"
|
|
5
|
+
|
|
6
|
+
module GraphQL
|
|
7
|
+
class Schema
|
|
8
|
+
# Use this plugin to make some parts of your schema hidden from some viewers.
|
|
9
|
+
#
|
|
10
|
+
class Visibility
|
|
11
|
+
# @param schema [Class<GraphQL::Schema>]
|
|
12
|
+
# @param profiles [Hash<Symbol => Hash>] A hash of `name => context` pairs for preloading visibility profiles
|
|
13
|
+
# @param preload [Boolean] if `true`, load the default schema profile and all named profiles immediately (defaults to `true` for `Rails.env.production?` and `Rails.env.staging?`)
|
|
14
|
+
# @param migration_errors [Boolean] if `true`, raise an error when `Visibility` and `Warden` return different results
|
|
15
|
+
def self.use(schema, dynamic: false, profiles: EmptyObjects::EMPTY_HASH, preload: (defined?(Rails.env) ? (Rails.env.production? || Rails.env.staging?) : nil), migration_errors: false)
|
|
16
|
+
profiles&.each { |name, ctx|
|
|
17
|
+
ctx[:visibility_profile] = name
|
|
18
|
+
ctx.freeze
|
|
19
|
+
}
|
|
20
|
+
schema.visibility = self.new(schema, dynamic: dynamic, preload: preload, profiles: profiles, migration_errors: migration_errors)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def initialize(schema, dynamic:, preload:, profiles:, migration_errors:)
|
|
24
|
+
@schema = schema
|
|
25
|
+
schema.use_visibility_profile = true
|
|
26
|
+
schema.visibility_profile_class = if migration_errors
|
|
27
|
+
Visibility::Migration
|
|
28
|
+
else
|
|
29
|
+
Visibility::Profile
|
|
30
|
+
end
|
|
31
|
+
@preload = preload
|
|
32
|
+
@profiles = profiles
|
|
33
|
+
@cached_profiles = {}
|
|
34
|
+
@dynamic = dynamic
|
|
35
|
+
@migration_errors = migration_errors
|
|
36
|
+
# Top-level type caches:
|
|
37
|
+
@visit = nil
|
|
38
|
+
@interface_type_memberships = nil
|
|
39
|
+
@directives = nil
|
|
40
|
+
@types = nil
|
|
41
|
+
@all_references = nil
|
|
42
|
+
@loaded_all = false
|
|
43
|
+
if preload
|
|
44
|
+
self.preload
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def freeze
|
|
49
|
+
load_all
|
|
50
|
+
@visit = true
|
|
51
|
+
@interface_type_memberships.default_proc = nil
|
|
52
|
+
@all_references.default_proc = nil
|
|
53
|
+
super
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def all_directives
|
|
57
|
+
load_all
|
|
58
|
+
@directives
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def all_interface_type_memberships
|
|
62
|
+
load_all
|
|
63
|
+
@interface_type_memberships
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def all_references
|
|
67
|
+
load_all
|
|
68
|
+
@all_references
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def get_type(type_name)
|
|
72
|
+
load_all
|
|
73
|
+
@types[type_name]
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
attr_accessor :types
|
|
77
|
+
|
|
78
|
+
def preload?
|
|
79
|
+
@preload
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def preload
|
|
83
|
+
# Traverse the schema now (and in the *_configured hooks below)
|
|
84
|
+
# To make sure things are loaded during boot
|
|
85
|
+
@preloaded_types = Set.new
|
|
86
|
+
types_to_visit = [
|
|
87
|
+
@schema.query,
|
|
88
|
+
@schema.mutation,
|
|
89
|
+
@schema.subscription,
|
|
90
|
+
*@schema.introspection_system.types.values,
|
|
91
|
+
*@schema.introspection_system.entry_points.map { |ep| ep.type.unwrap },
|
|
92
|
+
*@schema.orphan_types,
|
|
93
|
+
]
|
|
94
|
+
# Root types may have been nil:
|
|
95
|
+
types_to_visit.compact!
|
|
96
|
+
ensure_all_loaded(types_to_visit)
|
|
97
|
+
@profiles.each do |profile_name, example_ctx|
|
|
98
|
+
prof = profile_for(example_ctx)
|
|
99
|
+
prof.preload
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# @api private
|
|
104
|
+
def query_configured(query_type)
|
|
105
|
+
if @preload
|
|
106
|
+
ensure_all_loaded([query_type])
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# @api private
|
|
111
|
+
def mutation_configured(mutation_type)
|
|
112
|
+
if @preload
|
|
113
|
+
ensure_all_loaded([mutation_type])
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# @api private
|
|
118
|
+
def subscription_configured(subscription_type)
|
|
119
|
+
if @preload
|
|
120
|
+
ensure_all_loaded([subscription_type])
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# @api private
|
|
125
|
+
def orphan_types_configured(orphan_types)
|
|
126
|
+
if @preload
|
|
127
|
+
ensure_all_loaded(orphan_types)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# @api private
|
|
132
|
+
def introspection_system_configured(introspection_system)
|
|
133
|
+
if @preload
|
|
134
|
+
introspection_types = [
|
|
135
|
+
*@schema.introspection_system.types.values,
|
|
136
|
+
*@schema.introspection_system.entry_points.map { |ep| ep.type.unwrap },
|
|
137
|
+
]
|
|
138
|
+
ensure_all_loaded(introspection_types)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Make another Visibility for `schema` based on this one
|
|
143
|
+
# @return [Visibility]
|
|
144
|
+
# @api private
|
|
145
|
+
def dup_for(other_schema)
|
|
146
|
+
self.class.new(
|
|
147
|
+
other_schema,
|
|
148
|
+
dynamic: @dynamic,
|
|
149
|
+
preload: @preload,
|
|
150
|
+
profiles: @profiles,
|
|
151
|
+
migration_errors: @migration_errors
|
|
152
|
+
)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def migration_errors?
|
|
156
|
+
@migration_errors
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
attr_reader :cached_profiles
|
|
160
|
+
|
|
161
|
+
def profile_for(context)
|
|
162
|
+
if !@profiles.empty?
|
|
163
|
+
visibility_profile = context[:visibility_profile]
|
|
164
|
+
if @profiles.include?(visibility_profile)
|
|
165
|
+
profile_ctx = @profiles[visibility_profile]
|
|
166
|
+
@cached_profiles[visibility_profile] ||= @schema.visibility_profile_class.new(name: visibility_profile, context: profile_ctx, schema: @schema, visibility: self)
|
|
167
|
+
elsif @dynamic
|
|
168
|
+
if context.is_a?(Query::NullContext)
|
|
169
|
+
top_level_profile
|
|
170
|
+
else
|
|
171
|
+
@schema.visibility_profile_class.new(context: context, schema: @schema, visibility: self)
|
|
172
|
+
end
|
|
173
|
+
elsif !context.key?(:visibility_profile)
|
|
174
|
+
raise ArgumentError, "#{@schema} expects a visibility profile, but `visibility_profile:` wasn't passed. Provide a `visibility_profile:` value or add `dynamic: true` to your visibility configuration."
|
|
175
|
+
else
|
|
176
|
+
raise ArgumentError, "`#{visibility_profile.inspect}` isn't allowed for `visibility_profile:` (must be one of #{@profiles.keys.map(&:inspect).join(", ")}). Or, add `#{visibility_profile.inspect}` to the list of profiles in the schema definition."
|
|
177
|
+
end
|
|
178
|
+
elsif context.is_a?(Query::NullContext)
|
|
179
|
+
top_level_profile
|
|
180
|
+
else
|
|
181
|
+
@schema.visibility_profile_class.new(context: context, schema: @schema, visibility: self)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
attr_reader :top_level
|
|
186
|
+
|
|
187
|
+
# @api private
|
|
188
|
+
attr_reader :unfiltered_interface_type_memberships
|
|
189
|
+
|
|
190
|
+
def top_level_profile(refresh: false)
|
|
191
|
+
if refresh
|
|
192
|
+
@top_level_profile = nil
|
|
193
|
+
end
|
|
194
|
+
@top_level_profile ||= @schema.visibility_profile_class.new(context: Query::NullContext.instance, schema: @schema, visibility: self)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
private
|
|
198
|
+
|
|
199
|
+
def ensure_all_loaded(types_to_visit)
|
|
200
|
+
while (type = types_to_visit.shift)
|
|
201
|
+
if type.kind.fields? && @preloaded_types.add?(type)
|
|
202
|
+
type.all_field_definitions.each do |field_defn|
|
|
203
|
+
field_defn.ensure_loaded
|
|
204
|
+
types_to_visit << field_defn.type.unwrap
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
top_level_profile(refresh: true)
|
|
209
|
+
nil
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def load_all(types: nil)
|
|
213
|
+
if @visit.nil?
|
|
214
|
+
# Set up the visit system
|
|
215
|
+
@interface_type_memberships = Hash.new { |h, interface_type|
|
|
216
|
+
h[interface_type] = Hash.new { |h2, obj_type|
|
|
217
|
+
h2[obj_type] = []
|
|
218
|
+
}.compare_by_identity
|
|
219
|
+
}.compare_by_identity
|
|
220
|
+
@directives = []
|
|
221
|
+
@types = {} # String => Module
|
|
222
|
+
@all_references = Hash.new { |h, member| h[member] = Set.new.compare_by_identity }.compare_by_identity
|
|
223
|
+
@unions_for_references = Set.new
|
|
224
|
+
@visit = Visibility::Visit.new(@schema) do |member|
|
|
225
|
+
if member.is_a?(Module)
|
|
226
|
+
type_name = member.graphql_name
|
|
227
|
+
if (prev_t = @types[type_name])
|
|
228
|
+
if prev_t.is_a?(Array)
|
|
229
|
+
prev_t << member
|
|
230
|
+
else
|
|
231
|
+
@types[type_name] = [member, prev_t]
|
|
232
|
+
end
|
|
233
|
+
else
|
|
234
|
+
@types[member.graphql_name] = member
|
|
235
|
+
end
|
|
236
|
+
member.directives.each { |dir| @all_references[dir.class] << member }
|
|
237
|
+
if member < GraphQL::Schema::Directive
|
|
238
|
+
@directives << member
|
|
239
|
+
elsif member.respond_to?(:interface_type_memberships)
|
|
240
|
+
member.interface_type_memberships.each do |itm|
|
|
241
|
+
@all_references[itm.abstract_type] << member
|
|
242
|
+
# `itm.object_type` may not actually be `member` if this implementation
|
|
243
|
+
# is inherited from a superclass
|
|
244
|
+
@interface_type_memberships[itm.abstract_type][member] << itm
|
|
245
|
+
end
|
|
246
|
+
elsif member < GraphQL::Schema::Union
|
|
247
|
+
@unions_for_references << member
|
|
248
|
+
end
|
|
249
|
+
elsif member.is_a?(GraphQL::Schema::Argument)
|
|
250
|
+
member.validate_default_value
|
|
251
|
+
@all_references[member.type.unwrap] << member
|
|
252
|
+
if !(dirs = member.directives).empty?
|
|
253
|
+
dir_owner = member.owner
|
|
254
|
+
if dir_owner.respond_to?(:owner)
|
|
255
|
+
dir_owner = dir_owner.owner
|
|
256
|
+
end
|
|
257
|
+
dirs.each { |dir| @all_references[dir.class] << dir_owner }
|
|
258
|
+
end
|
|
259
|
+
elsif member.is_a?(GraphQL::Schema::Field)
|
|
260
|
+
@all_references[member.type.unwrap] << member
|
|
261
|
+
if !(dirs = member.directives).empty?
|
|
262
|
+
dir_owner = member.owner
|
|
263
|
+
dirs.each { |dir| @all_references[dir.class] << dir_owner }
|
|
264
|
+
end
|
|
265
|
+
elsif member.is_a?(GraphQL::Schema::EnumValue)
|
|
266
|
+
if !(dirs = member.directives).empty?
|
|
267
|
+
dir_owner = member.owner
|
|
268
|
+
dirs.each { |dir| @all_references[dir.class] << dir_owner }
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
true
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
@schema.root_types.each { |t| @all_references[t] << true }
|
|
275
|
+
@schema.introspection_system.types.each_value { |t| @all_references[t] << true }
|
|
276
|
+
@schema.directives.each_value { |dir_class| @all_references[dir_class] << true }
|
|
277
|
+
|
|
278
|
+
@visit.visit_each(types: []) # visit default directives
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
if types
|
|
282
|
+
@visit.visit_each(types: types, directives: [])
|
|
283
|
+
elsif @loaded_all == false
|
|
284
|
+
@loaded_all = true
|
|
285
|
+
@visit.visit_each
|
|
286
|
+
else
|
|
287
|
+
# already loaded all
|
|
288
|
+
return
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
# TODO: somehow don't iterate over all these,
|
|
292
|
+
# only the ones that may have been modified
|
|
293
|
+
@interface_type_memberships.each do |int_type, obj_type_memberships|
|
|
294
|
+
referrers = @all_references[int_type].select { |r| r.is_a?(GraphQL::Schema::Field) }
|
|
295
|
+
if !referrers.empty?
|
|
296
|
+
obj_type_memberships.each_key do |impl_type|
|
|
297
|
+
@all_references[impl_type] |= referrers
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
@unions_for_references.each do |union_type|
|
|
303
|
+
refs = @all_references[union_type]
|
|
304
|
+
union_type.all_possible_types.each do |object_type|
|
|
305
|
+
@all_references[object_type] |= refs # Add new items
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
end
|
|
@@ -19,6 +19,17 @@ module GraphQL
|
|
|
19
19
|
PassThruWarden
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
def self.types_from_context(context)
|
|
23
|
+
context.types || PassThruWarden
|
|
24
|
+
rescue NoMethodError
|
|
25
|
+
# this might be a hash which won't respond to #warden
|
|
26
|
+
PassThruWarden
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.use(schema)
|
|
30
|
+
# no-op
|
|
31
|
+
end
|
|
32
|
+
|
|
22
33
|
# @param visibility_method [Symbol] a Warden method to call for this entry
|
|
23
34
|
# @param entry [Object, Array<Object>] One or more definitions for a given name in a GraphQL Schema
|
|
24
35
|
# @param context [GraphQL::Query::Context]
|
|
@@ -61,23 +72,33 @@ module GraphQL
|
|
|
61
72
|
def interface_type_memberships(obj_t, ctx); obj_t.interface_type_memberships; end
|
|
62
73
|
def arguments(owner, ctx); owner.arguments(ctx); end
|
|
63
74
|
def loadable?(type, ctx); type.visible?(ctx); end
|
|
75
|
+
def loadable_possible_types(type, ctx); type.possible_types(ctx); end
|
|
76
|
+
def visibility_profile
|
|
77
|
+
@visibility_profile ||= Warden::VisibilityProfile.new(self)
|
|
78
|
+
end
|
|
64
79
|
end
|
|
65
80
|
end
|
|
66
81
|
|
|
67
82
|
class NullWarden
|
|
68
83
|
def initialize(_filter = nil, context:, schema:)
|
|
69
84
|
@schema = schema
|
|
85
|
+
@visibility_profile = Warden::VisibilityProfile.new(self)
|
|
70
86
|
end
|
|
71
87
|
|
|
88
|
+
# No-op, but for compatibility:
|
|
89
|
+
attr_writer :skip_warning
|
|
90
|
+
|
|
91
|
+
attr_reader :visibility_profile
|
|
92
|
+
|
|
72
93
|
def visible_field?(field_defn, _ctx = nil, owner = nil); true; end
|
|
73
94
|
def visible_argument?(arg_defn, _ctx = nil); true; end
|
|
74
95
|
def visible_type?(type_defn, _ctx = nil); true; end
|
|
75
|
-
def visible_enum_value?(enum_value, _ctx = nil);
|
|
96
|
+
def visible_enum_value?(enum_value, _ctx = nil); enum_value.visible?(Query::NullContext.instance); end
|
|
76
97
|
def visible_type_membership?(type_membership, _ctx = nil); true; end
|
|
77
98
|
def interface_type_memberships(obj_type, _ctx = nil); obj_type.interface_type_memberships; end
|
|
78
|
-
def get_type(type_name); @schema.get_type(type_name); end # rubocop:disable Development/ContextIsPassedCop
|
|
99
|
+
def get_type(type_name); @schema.get_type(type_name, Query::NullContext.instance, false); end # rubocop:disable Development/ContextIsPassedCop
|
|
79
100
|
def arguments(argument_owner, ctx = nil); argument_owner.all_argument_definitions; end
|
|
80
|
-
def enum_values(enum_defn); enum_defn.enum_values; end # rubocop:disable Development/ContextIsPassedCop
|
|
101
|
+
def enum_values(enum_defn); enum_defn.enum_values(Query::NullContext.instance); end # rubocop:disable Development/ContextIsPassedCop
|
|
81
102
|
def get_argument(parent_type, argument_name); parent_type.get_argument(argument_name); end # rubocop:disable Development/ContextIsPassedCop
|
|
82
103
|
def types; @schema.types; end # rubocop:disable Development/ContextIsPassedCop
|
|
83
104
|
def root_type_for_operation(op_name); @schema.root_type_for_operation(op_name); end
|
|
@@ -86,11 +107,94 @@ module GraphQL
|
|
|
86
107
|
def get_field(parent_type, field_name); @schema.get_field(parent_type, field_name); end
|
|
87
108
|
def reachable_type?(type_name); true; end
|
|
88
109
|
def loadable?(type, _ctx); true; end
|
|
110
|
+
def loadable_possible_types(abstract_type, _ctx); union_type.possible_types; end
|
|
89
111
|
def reachable_types; @schema.types.values; end # rubocop:disable Development/ContextIsPassedCop
|
|
90
|
-
def possible_types(type_defn); @schema.possible_types(type_defn); end
|
|
112
|
+
def possible_types(type_defn); @schema.possible_types(type_defn, Query::NullContext.instance, false); end
|
|
91
113
|
def interfaces(obj_type); obj_type.interfaces; end
|
|
92
114
|
end
|
|
93
115
|
|
|
116
|
+
def visibility_profile
|
|
117
|
+
@visibility_profile ||= VisibilityProfile.new(self)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
class VisibilityProfile
|
|
121
|
+
def initialize(warden)
|
|
122
|
+
@warden = warden
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def directives
|
|
126
|
+
@warden.directives
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def directive_exists?(dir_name)
|
|
130
|
+
@warden.directives.any? { |d| d.graphql_name == dir_name }
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def type(name)
|
|
134
|
+
@warden.get_type(name)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def field(owner, field_name)
|
|
138
|
+
@warden.get_field(owner, field_name)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def argument(owner, arg_name)
|
|
142
|
+
@warden.get_argument(owner, arg_name)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def query_root
|
|
146
|
+
@warden.root_type_for_operation("query")
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def mutation_root
|
|
150
|
+
@warden.root_type_for_operation("mutation")
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def subscription_root
|
|
154
|
+
@warden.root_type_for_operation("subscription")
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def arguments(owner)
|
|
158
|
+
@warden.arguments(owner)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def fields(owner)
|
|
162
|
+
@warden.fields(owner)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def possible_types(type)
|
|
166
|
+
@warden.possible_types(type)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def enum_values(enum_type)
|
|
170
|
+
@warden.enum_values(enum_type)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def all_types
|
|
174
|
+
@warden.reachable_types
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def interfaces(obj_type)
|
|
178
|
+
@warden.interfaces(obj_type)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def loadable?(t, ctx) # TODO remove ctx here?
|
|
182
|
+
@warden.loadable?(t, ctx)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def loadable_possible_types(t, ctx)
|
|
186
|
+
@warden.loadable_possible_types(t, ctx)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def reachable_type?(type_name)
|
|
190
|
+
!!@warden.reachable_type?(type_name)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def visible_enum_value?(enum_value, ctx = nil)
|
|
194
|
+
@warden.visible_enum_value?(enum_value, ctx)
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
94
198
|
# @param context [GraphQL::Query::Context]
|
|
95
199
|
# @param schema [GraphQL::Schema]
|
|
96
200
|
def initialize(context:, schema:)
|
|
@@ -100,17 +204,19 @@ module GraphQL
|
|
|
100
204
|
@mutation = @schema.mutation
|
|
101
205
|
@subscription = @schema.subscription
|
|
102
206
|
@context = context
|
|
103
|
-
@visibility_cache = read_through { |m| schema
|
|
104
|
-
@visibility_cache.compare_by_identity
|
|
207
|
+
@visibility_cache = read_through { |m| check_visible(schema, m) }
|
|
105
208
|
# Initialize all ivars to improve object shape consistency:
|
|
106
209
|
@types = @visible_types = @reachable_types = @visible_parent_fields =
|
|
107
210
|
@visible_possible_types = @visible_fields = @visible_arguments = @visible_enum_arrays =
|
|
108
211
|
@visible_enum_values = @visible_interfaces = @type_visibility = @type_memberships =
|
|
109
212
|
@visible_and_reachable_type = @unions = @unfiltered_interfaces =
|
|
110
|
-
@reachable_type_set =
|
|
213
|
+
@reachable_type_set = @visibility_profile = @loadable_possible_types =
|
|
111
214
|
nil
|
|
215
|
+
@skip_warning = schema.plugins.any? { |(plugin, _opts)| plugin == GraphQL::Schema::Warden }
|
|
112
216
|
end
|
|
113
217
|
|
|
218
|
+
attr_writer :skip_warning
|
|
219
|
+
|
|
114
220
|
# @return [Hash<String, GraphQL::BaseType>] Visible types in the schema
|
|
115
221
|
def types
|
|
116
222
|
@types ||= begin
|
|
@@ -126,13 +232,28 @@ module GraphQL
|
|
|
126
232
|
|
|
127
233
|
# @return [Boolean] True if this type is used for `loads:` but not in the schema otherwise and not _explicitly_ hidden.
|
|
128
234
|
def loadable?(type, _ctx)
|
|
129
|
-
|
|
235
|
+
visible_type?(type) &&
|
|
236
|
+
!referenced?(type) &&
|
|
237
|
+
(type.respond_to?(:interfaces) ? interfaces(type).all? { |i| loadable?(i, _ctx) } : true)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# This abstract type was determined to be used for `loads` only.
|
|
241
|
+
# All its possible types are valid possibilities here -- no filtering.
|
|
242
|
+
def loadable_possible_types(abstract_type, _ctx)
|
|
243
|
+
@loadable_possible_types ||= read_through do |t|
|
|
244
|
+
if t.is_a?(Class) # union
|
|
245
|
+
t.possible_types
|
|
246
|
+
else
|
|
247
|
+
@schema.possible_types(abstract_type)
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
@loadable_possible_types[abstract_type]
|
|
130
251
|
end
|
|
131
252
|
|
|
132
253
|
# @return [GraphQL::BaseType, nil] The type named `type_name`, if it exists (else `nil`)
|
|
133
254
|
def get_type(type_name)
|
|
134
255
|
@visible_types ||= read_through do |name|
|
|
135
|
-
type_defn = @schema.get_type(name, @context)
|
|
256
|
+
type_defn = @schema.get_type(name, @context, false)
|
|
136
257
|
if type_defn && visible_and_reachable_type?(type_defn)
|
|
137
258
|
type_defn
|
|
138
259
|
else
|
|
@@ -179,7 +300,7 @@ module GraphQL
|
|
|
179
300
|
# @return [Array<GraphQL::BaseType>] The types which may be member of `type_defn`
|
|
180
301
|
def possible_types(type_defn)
|
|
181
302
|
@visible_possible_types ||= read_through { |type_defn|
|
|
182
|
-
pt = @schema.possible_types(type_defn, @context)
|
|
303
|
+
pt = @schema.possible_types(type_defn, @context, false)
|
|
183
304
|
pt.select { |t| visible_and_reachable_type?(t) }
|
|
184
305
|
}
|
|
185
306
|
@visible_possible_types[type_defn]
|
|
@@ -197,7 +318,7 @@ module GraphQL
|
|
|
197
318
|
def arguments(argument_owner, ctx = nil)
|
|
198
319
|
@visible_arguments ||= read_through { |o|
|
|
199
320
|
args = o.arguments(@context)
|
|
200
|
-
if args.
|
|
321
|
+
if !args.empty?
|
|
201
322
|
args = args.values
|
|
202
323
|
args.select! { |a| visible_argument?(a, @context) }
|
|
203
324
|
args
|
|
@@ -229,7 +350,7 @@ module GraphQL
|
|
|
229
350
|
def interfaces(obj_type)
|
|
230
351
|
@visible_interfaces ||= read_through { |t|
|
|
231
352
|
ints = t.interfaces(@context)
|
|
232
|
-
if ints.
|
|
353
|
+
if !ints.empty?
|
|
233
354
|
ints.select! { |i| visible_type?(i) }
|
|
234
355
|
end
|
|
235
356
|
ints
|
|
@@ -289,13 +410,13 @@ module GraphQL
|
|
|
289
410
|
next true if root_type?(type_defn) || type_defn.introspection?
|
|
290
411
|
|
|
291
412
|
if type_defn.kind.union?
|
|
292
|
-
possible_types(type_defn).
|
|
413
|
+
!possible_types(type_defn).empty? && (referenced?(type_defn) || orphan_type?(type_defn))
|
|
293
414
|
elsif type_defn.kind.interface?
|
|
294
|
-
if possible_types(type_defn).
|
|
415
|
+
if !possible_types(type_defn).empty?
|
|
295
416
|
true
|
|
296
417
|
else
|
|
297
418
|
if @context.respond_to?(:logger) && (logger = @context.logger)
|
|
298
|
-
logger.debug { "Interface `#{type_defn.graphql_name}` hidden because it has no visible
|
|
419
|
+
logger.debug { "Interface `#{type_defn.graphql_name}` hidden because it has no visible implementers" }
|
|
299
420
|
end
|
|
300
421
|
false
|
|
301
422
|
end
|
|
@@ -363,8 +484,7 @@ module GraphQL
|
|
|
363
484
|
end
|
|
364
485
|
|
|
365
486
|
def referenced?(type_defn)
|
|
366
|
-
|
|
367
|
-
members = @schema.references_to(graphql_name)
|
|
487
|
+
members = @schema.references_to(type_defn)
|
|
368
488
|
members.any? { |m| visible?(m) }
|
|
369
489
|
end
|
|
370
490
|
|
|
@@ -377,11 +497,61 @@ module GraphQL
|
|
|
377
497
|
end
|
|
378
498
|
|
|
379
499
|
def read_through
|
|
380
|
-
|
|
381
|
-
h.compare_by_identity
|
|
382
|
-
h
|
|
500
|
+
Hash.new { |h, k| h[k] = yield(k) }.compare_by_identity
|
|
383
501
|
end
|
|
384
502
|
|
|
503
|
+
def check_visible(schema, member)
|
|
504
|
+
if schema.visible?(member, @context)
|
|
505
|
+
true
|
|
506
|
+
elsif @skip_warning
|
|
507
|
+
false
|
|
508
|
+
else
|
|
509
|
+
member_s = member.respond_to?(:path) ? member.path : member.inspect
|
|
510
|
+
member_type = case member
|
|
511
|
+
when Module
|
|
512
|
+
if member.respond_to?(:kind)
|
|
513
|
+
member.kind.name.downcase
|
|
514
|
+
else
|
|
515
|
+
""
|
|
516
|
+
end
|
|
517
|
+
when GraphQL::Schema::Field
|
|
518
|
+
"field"
|
|
519
|
+
when GraphQL::Schema::EnumValue
|
|
520
|
+
"enum value"
|
|
521
|
+
when GraphQL::Schema::Argument
|
|
522
|
+
"argument"
|
|
523
|
+
else
|
|
524
|
+
""
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
schema_s = schema.name ? "#{schema.name}'s" : ""
|
|
528
|
+
schema_name = schema.name ? "#{schema.name}" : "your schema"
|
|
529
|
+
warn(ADD_WARDEN_WARNING % { schema_s: schema_s, schema_name: schema_name, member: member_s, member_type: member_type })
|
|
530
|
+
@skip_warning = true # only warn once per query
|
|
531
|
+
# If there's no schema name, add the backtrace for additional context:
|
|
532
|
+
if schema_s == ""
|
|
533
|
+
puts caller.map { |l| " #{l}"}
|
|
534
|
+
end
|
|
535
|
+
false
|
|
536
|
+
end
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
ADD_WARDEN_WARNING = <<~WARNING
|
|
540
|
+
DEPRECATION: %{schema_s} "%{member}" %{member_type} returned `false` for `.visible?` but `GraphQL::Schema::Visibility` isn't configured yet.
|
|
541
|
+
|
|
542
|
+
Address this warning by adding:
|
|
543
|
+
|
|
544
|
+
use GraphQL::Schema::Visibility
|
|
545
|
+
|
|
546
|
+
to the definition for %{schema_name}. (Future GraphQL-Ruby versions won't check `.visible?` methods by default.)
|
|
547
|
+
|
|
548
|
+
Alternatively, for legacy behavior, add:
|
|
549
|
+
|
|
550
|
+
use GraphQL::Schema::Warden # legacy visibility behavior
|
|
551
|
+
|
|
552
|
+
For more information see: https://graphql-ruby.org/authorization/visibility.html
|
|
553
|
+
WARNING
|
|
554
|
+
|
|
385
555
|
def reachable_type_set
|
|
386
556
|
return @reachable_type_set if @reachable_type_set
|
|
387
557
|
|