Skip to content
This repository has been archived by the owner on Jun 21, 2023. It is now read-only.

Commit

Permalink
Support except and only masks
Browse files Browse the repository at this point in the history
  • Loading branch information
gjtorikian committed Mar 27, 2018
1 parent 281c254 commit 69d9057
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 9 deletions.
4 changes: 2 additions & 2 deletions lib/graphql/relay/walker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ module Walker
# 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.
Expand Down
4 changes: 2 additions & 2 deletions lib/graphql/relay/walker/client_ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ module ClientExt
# &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|
Expand Down
25 changes: 20 additions & 5 deletions lib/graphql/relay/walker/query_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ class QueryBuilder
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.
#
Expand All @@ -12,8 +12,10 @@ class QueryBuilder
# (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
Expand All @@ -37,13 +39,25 @@ def build_query
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
Expand Down Expand Up @@ -80,9 +94,10 @@ def inline_fragment_ast(type, with_children: true)

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
Expand Down

0 comments on commit 69d9057

Please sign in to comment.