Class: GraphQL::Schema::Visibility

Inherits:
Object
  • Object
show all
Defined in:
lib/graphql/schema/visibility.rb,
lib/graphql/schema/visibility/visit.rb,
lib/graphql/schema/visibility/profile.rb,
lib/graphql/schema/visibility/migration.rb

Overview

Use this plugin to make some parts of your schema hidden from some viewers.

Defined Under Namespace

Classes: Migration, Profile, Visit

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(schema, dynamic:, preload:, profiles:, migration_errors:) ⇒ Visibility

Returns a new instance of Visibility.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/graphql/schema/visibility.rb', line 22

def initialize(schema, dynamic:, preload:, profiles:, migration_errors:)
  @schema = schema
  schema.use_visibility_profile = true
  schema.visibility_profile_class = if migration_errors
    Visibility::Migration
  else
    Visibility::Profile
  end
  @preload = preload
  @profiles = profiles
  @cached_profiles = {}
  @dynamic = dynamic
  @migration_errors = migration_errors
  # Top-level type caches:
  @visit = nil
  @interface_type_memberships = nil
  @directives = nil
  @types = nil
  @all_references = nil
  @loaded_all = false
end

Instance Attribute Details

#cached_profilesObject (readonly)

Returns the value of attribute cached_profiles.



146
147
148
# File 'lib/graphql/schema/visibility.rb', line 146

def cached_profiles
  @cached_profiles
end

#top_levelObject (readonly)

Returns the value of attribute top_level.



172
173
174
# File 'lib/graphql/schema/visibility.rb', line 172

def top_level
  @top_level
end

#unfiltered_interface_type_membershipsObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



175
176
177
# File 'lib/graphql/schema/visibility.rb', line 175

def unfiltered_interface_type_memberships
  @unfiltered_interface_type_memberships
end

Class Method Details

.use(schema, dynamic: false, profiles: EmptyObjects::EMPTY_HASH, preload: (Rails) ? Rails.env.production? : nil), migration_errors: false) ⇒ Object

Parameters:

  • schema (Class<GraphQL::Schema>)
  • profiles (Hash<Symbol => Hash>) (defaults to: EmptyObjects::EMPTY_HASH)

    A hash of name => context pairs for preloading visibility profiles

  • preload (Boolean) (defaults to: (Rails) ? Rails.env.production? : nil))

    if true, load the default schema profile and all named profiles immediately (defaults to true for Rails.env.production?)

  • migration_errors (Boolean) (defaults to: false)

    if true, raise an error when Visibility and Warden return different results



15
16
17
18
19
20
# File 'lib/graphql/schema/visibility.rb', line 15

def self.use(schema, dynamic: false, profiles: EmptyObjects::EMPTY_HASH, preload: (defined?(Rails) ? Rails.env.production? : nil), migration_errors: false)
  schema.visibility = self.new(schema, dynamic: dynamic, preload: preload, profiles: profiles, migration_errors: migration_errors)
  if preload
    schema.visibility.preload
  end
end

Instance Method Details

#all_directivesObject



44
45
46
47
# File 'lib/graphql/schema/visibility.rb', line 44

def all_directives
  load_all
  @directives
end

#all_interface_type_membershipsObject



49
50
51
52
# File 'lib/graphql/schema/visibility.rb', line 49

def all_interface_type_memberships
  load_all
  @interface_type_memberships
end

#all_referencesObject



54
55
56
57
# File 'lib/graphql/schema/visibility.rb', line 54

def all_references
  load_all
  @all_references
end

#dup_for(other_schema) ⇒ Visibility

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Make another Visibility for schema based on this one

Returns:



132
133
134
135
136
137
138
139
140
# File 'lib/graphql/schema/visibility.rb', line 132

def dup_for(other_schema)
  self.class.new(
    other_schema,
    dynamic: @dynamic,
    preload: @preload,
    profiles: @profiles,
    migration_errors: @migration_errors
  )
end

#get_type(type_name) ⇒ Object



59
60
61
62
# File 'lib/graphql/schema/visibility.rb', line 59

def get_type(type_name)
  load_all
  @types[type_name]
end

#introspection_system_configured(introspection_system) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



119
120
121
122
123
124
125
126
127
# File 'lib/graphql/schema/visibility.rb', line 119

def introspection_system_configured(introspection_system)
  if @preload
    introspection_types = [
      *@schema.introspection_system.types.values,
      *@schema.introspection_system.entry_points.map { |ep| ep.type.unwrap },
    ]
    ensure_all_loaded(introspection_types)
  end
end

#migration_errors?Boolean

Returns:

  • (Boolean)


142
143
144
# File 'lib/graphql/schema/visibility.rb', line 142

def migration_errors?
  @migration_errors
end

#mutation_configured(mutation_type) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



98
99
100
101
102
# File 'lib/graphql/schema/visibility.rb', line 98

def mutation_configured(mutation_type)
  if @preload
    ensure_all_loaded([mutation_type])
  end
end

#orphan_types_configured(orphan_types) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



112
113
114
115
116
# File 'lib/graphql/schema/visibility.rb', line 112

def orphan_types_configured(orphan_types)
  if @preload
    ensure_all_loaded(orphan_types)
  end
end

#preloadObject



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/graphql/schema/visibility.rb', line 68

def preload
  # Traverse the schema now (and in the *_configured hooks below)
  # To make sure things are loaded during boot
  @preloaded_types = Set.new
  types_to_visit = [
    @schema.query,
    @schema.mutation,
    @schema.subscription,
    *@schema.introspection_system.types.values,
    *@schema.introspection_system.entry_points.map { |ep| ep.type.unwrap },
    *@schema.orphan_types,
  ]
  # Root types may have been nil:
  types_to_visit.compact!
  ensure_all_loaded(types_to_visit)
  @profiles.each do |profile_name, example_ctx|
    example_ctx[:visibility_profile] = profile_name
    prof = profile_for(example_ctx, profile_name)
    prof.all_types # force loading
  end
end

#preload?Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/graphql/schema/visibility.rb', line 64

def preload?
  @preload
end

#profile_for(context, visibility_profile) ⇒ Object



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/graphql/schema/visibility.rb', line 148

def profile_for(context, visibility_profile)
  if !@profiles.empty?
    if visibility_profile.nil?
      if @dynamic
        if context.is_a?(Query::NullContext)
          top_level_profile
        else
          @schema.visibility_profile_class.new(context: context, schema: @schema)
        end
      elsif !@profiles.empty?
        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."
      end
    elsif !@profiles.include?(visibility_profile)
      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."
    else
      @cached_profiles[visibility_profile] ||= @schema.visibility_profile_class.new(name: visibility_profile, context: context, schema: @schema)
    end
  elsif context.is_a?(Query::NullContext)
    top_level_profile
  else
    @schema.visibility_profile_class.new(context: context, schema: @schema)
  end
end

#query_configured(query_type) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



91
92
93
94
95
# File 'lib/graphql/schema/visibility.rb', line 91

def query_configured(query_type)
  if @preload
    ensure_all_loaded([query_type])
  end
end

#subscription_configured(subscription_type) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



105
106
107
108
109
# File 'lib/graphql/schema/visibility.rb', line 105

def subscription_configured(subscription_type)
  if @preload
    ensure_all_loaded([subscription_type])
  end
end

#top_level_profile(refresh: false) ⇒ Object



177
178
179
180
181
182
# File 'lib/graphql/schema/visibility.rb', line 177

def top_level_profile(refresh: false)
  if refresh
    @top_level_profile = nil
  end
  @top_level_profile ||= @schema.visibility_profile_class.new(context: Query::NullContext.instance, schema: @schema)
end