Support `except` and `only` masks

This commit is contained in:
Garen J. Torikian 2018-03-27 18:55:36 -04:00
Родитель 281c254104
Коммит 69d90572bc
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5BAAE86264ABDE0A
3 изменённых файлов: 24 добавлений и 9 удалений

Просмотреть файл

@ -8,8 +8,8 @@ module GraphQL::Relay
# schema - The GraphQL::Schema to build a query for.
#
# Returns a String query.
def self.query_string(schema)
QueryBuilder.new(schema).query_string
def self.query_string(schema, except: nil, only: nil)
QueryBuilder.new(schema, except: except, only: only).query_string
end
# Start traversing a graph, starting from the given relay node ID.

Просмотреть файл

@ -8,8 +8,8 @@ module GraphQL::Relay::Walker
# &blk - A block to call with each Walker::Frame that is visited.
#
# Returns nothing.
def walk(from_id:, variables: {}, context: {})
query_string = GraphQL::Relay::Walker.query_string(schema)
def walk(from_id:, except: nil, only: nil, variables: {}, context: {})
query_string = GraphQL::Relay::Walker.query_string(schema, except: except, only: only)
walker_query = parse(query_string)
GraphQL::Relay::Walker.walk(from_id: from_id) do |frame|

Просмотреть файл

@ -3,7 +3,7 @@ module GraphQL::Relay::Walker
DEFAULT_ARGUMENTS = { 'first' => 5 }.freeze
BASE_QUERY = 'query($id: ID!) { node(id: $id) { id } }'.freeze
attr_reader :schema, :connection_arguments, :ast
attr_reader :schema, :connection_arguments, :ast, :except, :only
# Initialize a new QueryBuilder.
#
@ -12,8 +12,10 @@ module GraphQL::Relay::Walker
# (optional).
#
# Returns nothing.
def initialize(schema, connection_arguments: DEFAULT_ARGUMENTS)
def initialize(schema, except: nil, only: nil, connection_arguments: DEFAULT_ARGUMENTS)
@schema = schema
@except = except
@only = only
@connection_arguments = connection_arguments
@ast = build_query
end
@ -37,13 +39,25 @@ module GraphQL::Relay::Walker
selections = d_ast.definitions.first.selections.first.selections
node_types.each do |type|
selections << inline_fragment_ast(type)
selections << inline_fragment_ast(type) if include?(type)
end
selections.compact!
end
end
# Private: Depending on the `except` or `include` filters,
# should this item be included a AST of the given type.
#
# type - The GraphQL item to identify to make the fragment
#
# Returns a Boolean.
def include?(type)
return !@except.call(type, {}) if @except
return @only.call(type, {}) if @only
true
end
# Private: Make a AST of the given type.
#
# klass - The GraphQL::Language::Nodes::AbstractNode subclass
@ -80,9 +94,10 @@ module GraphQL::Relay::Walker
if with_children
type.all_fields.each do |field|
if node_field?(field)
field_type = field.type.unwrap
if node_field?(field) && include?(field_type)
if_ast.selections << node_field_ast(field)
elsif connection_field?(field)
elsif connection_field?(field) && include?(field_type)
if_ast.selections << connection_field_ast(field)
end
end