Class: GraphQL::StaticValidation::DefinitionDependencies

Inherits:
Object
  • Object
show all
Defined in:
lib/graphql/static_validation/definition_dependencies.rb

Overview

Track fragment dependencies for operations and expose the fragment definitions which are used by a given operation

Defined Under Namespace

Classes: DependencyMap, NodeWithPath

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDefinitionDependencies

Returns a new instance of DefinitionDependencies.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/graphql/static_validation/definition_dependencies.rb', line 14

def initialize
  # { name => node } pairs for fragments
  @fragment_definitions = {}

  # This tracks dependencies from fragment to Node where it was used
  # { frag_name => [dependent_node, dependent_node]}
  @dependent_definitions = Hash.new { |h, k| h[k] = Set.new }

  # First-level usages of spreads within definitions
  # (When a key has an empty list as its value,
  #  we can resolve that key's depenedents)
  # { string => [node, node ...] }
  @immediate_dependencies = Hash.new { |h, k| h[k] = Set.new }
end

Class Method Details

.mount(visitor) ⇒ Object



8
9
10
11
12
# File 'lib/graphql/static_validation/definition_dependencies.rb', line 8

def self.mount(visitor)
  deps = self.new
  deps.mount(visitor)
  deps
end

Instance Method Details

#dependency_map(&block) ⇒ DependencyMap

A map of operation definitions to an array of that operation's dependencies

Returns:



31
32
33
# File 'lib/graphql/static_validation/definition_dependencies.rb', line 31

def dependency_map(&block)
  @dependency_map ||= resolve_dependencies(&block)
end

#mount(context) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/graphql/static_validation/definition_dependencies.rb', line 35

def mount(context)
  visitor = context.visitor
  # When we encounter a spread,
  # this node is the one who depends on it
  current_parent = nil

  visitor[GraphQL::Language::Nodes::OperationDefinition] << ->(node, prev_node) {
    current_parent = NodeWithPath.new(node, context.path)
  }

  visitor[GraphQL::Language::Nodes::OperationDefinition].leave << ->(node, prev_node) {
    current_parent = nil
  }

  visitor[GraphQL::Language::Nodes::FragmentDefinition] << ->(node, prev_node) {
    current_parent = @fragment_definitions[node.name] = NodeWithPath.new(node, context.path)
  }

  visitor[GraphQL::Language::Nodes::FragmentDefinition].leave << ->(node, prev_node) {
    current_parent = nil
  }

  visitor[GraphQL::Language::Nodes::FragmentSpread] << ->(node, prev_node) {
    # Track both sides of the dependency
    @dependent_definitions[node.name] << current_parent
    @immediate_dependencies[current_parent.name] << NodeWithPath.new(node, context.path)
  }
end