Skip to content

Commit 96aeb2b

Browse files
authored
Merge pull request #5291 from rmosolgo/hide-unreferenced-arg-types
Visibility: hide unreferenced arg types
2 parents 130924f + 2865409 commit 96aeb2b

File tree

2 files changed

+61
-11
lines changed

2 files changed

+61
-11
lines changed

Diff for: lib/graphql/schema/visibility/profile.rb

+31-11
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,21 @@ def initialize(name: nil, context:, schema:)
4747
end.compare_by_identity
4848
}.compare_by_identity
4949

50-
@cached_visible_arguments = Hash.new do |h, arg|
51-
h[arg] = if @cached_visible[arg] && (arg_type = arg.type.unwrap) && @cached_visible[arg_type]
52-
true
53-
else
54-
false
55-
end
50+
@cached_visible_arguments = Hash.new do |h, owner|
51+
h[owner] = Hash.new do |h2, arg|
52+
h2[arg] = if @cached_visible[arg] && (arg_type = arg.type.unwrap) && @cached_visible[arg_type]
53+
case owner
54+
when GraphQL::Schema::Field
55+
@cached_visible_fields[owner.owner][owner]
56+
when Class
57+
@cached_visible[owner]
58+
else
59+
raise "Unexpected argument owner for `#{arg.path}`: #{owner.inspect}"
60+
end
61+
else
62+
false
63+
end
64+
end.compare_by_identity
5665
end.compare_by_identity
5766

5867
@cached_parent_fields = Hash.new do |h, type|
@@ -82,7 +91,7 @@ def initialize(name: nil, context:, schema:)
8291
end.compare_by_identity
8392

8493
@cached_arguments = Hash.new do |h, owner|
85-
h[owner] = non_duplicate_items(owner.all_argument_definitions, @cached_visible_arguments)
94+
h[owner] = non_duplicate_items(owner.all_argument_definitions, @cached_visible_arguments[owner])
8695
end.compare_by_identity
8796

8897
@loadable_possible_types = Hash.new { |h, union_type| h[union_type] = union_type.possible_types }.compare_by_identity
@@ -180,7 +189,7 @@ def argument(owner, arg_name)
180189
if arg.is_a?(Array)
181190
visible_arg = nil
182191
arg.each do |arg_defn|
183-
if @cached_visible_arguments[arg_defn]
192+
if @cached_visible_arguments[owner][arg_defn]
184193
if visible_arg.nil?
185194
visible_arg = arg_defn
186195
else
@@ -190,7 +199,7 @@ def argument(owner, arg_name)
190199
end
191200
visible_arg
192201
else
193-
if arg && @cached_visible_arguments[arg]
202+
if arg && @cached_visible_arguments[owner][arg]
194203
arg
195204
else
196205
nil
@@ -292,7 +301,7 @@ def load_all_types
292301
@all_types_loaded = true
293302
visit = Visibility::Visit.new(@schema) do |member|
294303
if member.is_a?(Module) && member.respond_to?(:kind)
295-
if @cached_visible[member]
304+
if @cached_visible[member] && referenced?(member)
296305
type_name = member.graphql_name
297306
if (prev_t = @all_types[type_name]) && !prev_t.equal?(member)
298307
raise_duplicate_definition(member, prev_t)
@@ -312,7 +321,18 @@ def load_all_types
312321
end
313322

314323
def referenced?(type_defn)
315-
@schema.visibility.all_references[type_defn].any? { |r| r == true || @cached_visible[r] }
324+
@schema.visibility.all_references[type_defn].any? do |ref|
325+
case ref
326+
when GraphQL::Schema::Argument
327+
@cached_visible_arguments[ref.owner][ref]
328+
when GraphQL::Schema::Field
329+
@cached_visible_fields[ref.owner][ref]
330+
when Module
331+
@cached_visible[ref]
332+
when true
333+
true
334+
end
335+
end
316336
end
317337

318338
def possible_types_for(type)

Diff for: spec/graphql/schema/visibility_spec.rb

+30
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@ def visible?(ctx)
1616

1717
class BaseObject < GraphQL::Schema::Object
1818
field_class(BaseField)
19+
20+
def self.visible?(ctx)
21+
(@admin_only ? !!ctx[:is_admin] : true) && super
22+
end
23+
24+
def self.admin_only(new_value = nil)
25+
if new_value.nil?
26+
@admin_only
27+
else
28+
@admin_only = new_value
29+
end
30+
end
1931
end
2032

2133
class Product < BaseObject
@@ -24,8 +36,21 @@ class Product < BaseObject
2436
field :cost_of_goods_sold, Integer, admin_only: true
2537
end
2638

39+
class Widget < BaseObject
40+
admin_only(true)
41+
field :name, String
42+
end
43+
44+
class WidgetKind < GraphQL::Schema::Enum
45+
value :FOO
46+
value :BAR
47+
end
48+
2749
class Query < BaseObject
2850
field :products, [Product]
51+
field :widget, Widget do
52+
argument :type, WidgetKind
53+
end
2954

3055
def products
3156
[{ name: "Pool Noodle", price: 100, cost_of_goods_sold: 5 }]
@@ -55,6 +80,11 @@ def exec_query(...)
5580
end
5681
end
5782

83+
it "hides unused arguments" do
84+
schema_sdl = VisSchema.to_definition(context: { visibility_profile: :public })
85+
refute_includes schema_sdl, "WidgetKind"
86+
end
87+
5888
describe "running queries" do
5989
it "requires context[:visibility]" do
6090
err = assert_raises ArgumentError do

0 commit comments

Comments
 (0)