1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
|
# frozen_string_literal: true
module GraphQL
class Schema
class Directive < GraphQL::Schema::Member
# This is _similar_ to {Directive::Feature}, except it's prescribed by the server, not the client.
#
# In this case, the server hides types and fields _entirely_, unless the current context has certain `:flags` present.
class Flagged < GraphQL::Schema::Directive
def initialize(target, **options)
if target.is_a?(Module) && !target.ancestors.include?(VisibleByFlag)
# This is type class of some kind, `include` will put this module
# in between the type class itself and its super class, so `super` will work fine
target.include(VisibleByFlag)
elsif !target.is_a?(VisibleByFlag)
# This is an instance of a base class. `include` won't put this in front of the
# base class implementation, so we need to `.prepend`.
# `#visible?` could probably be moved to a module and then this could use `include` instead.
target.class.prepend(VisibleByFlag)
end
super
end
description "Hides this part of the schema unless the named flag is present in context[:flags]"
locations(
GraphQL::Schema::Directive::FIELD_DEFINITION,
GraphQL::Schema::Directive::OBJECT,
GraphQL::Schema::Directive::SCALAR,
GraphQL::Schema::Directive::ENUM,
GraphQL::Schema::Directive::UNION,
GraphQL::Schema::Directive::INTERFACE,
GraphQL::Schema::Directive::INPUT_OBJECT,
GraphQL::Schema::Directive::ENUM_VALUE,
GraphQL::Schema::Directive::ARGUMENT_DEFINITION,
GraphQL::Schema::Directive::INPUT_FIELD_DEFINITION,
)
argument :by, [String], "Flags to check for this schema member"
module VisibleByFlag
def self.included(schema_class)
schema_class.extend(self)
end
def visible?(context)
if dir = self.directives.find { |d| d.is_a?(Flagged) }
relevant_flags = (f = context[:flags]) && dir.arguments[:by] & f # rubocop:disable Development/ContextIsPassedCop -- definition-related
relevant_flags && relevant_flags.any? && super
else
super
end
end
end
end
end
end
end
|