Module: GraphQL::Client::DefinitionVariables

Defined in:
lib/graphql/client/definition_variables.rb

Overview

Internal: Detect variables used in a definition.

Class Method Summary collapse

Class Method Details

.operation_variables(schema, document, definition_name = nil) ⇒ Object

Internal: Detect all variables used in a given operation or fragment definition.

schema - A GraphQL::Schema document - A GraphQL::Language::Nodes::Document to scan definition_name - A String definition name. Defaults to anonymous definition.

Returns a Hash to VariableDefinition objects.


57
58
59
60
61
# File 'lib/graphql/client/definition_variables.rb', line 57

def self.operation_variables(schema, document, definition_name = nil)
  variables(schema, document, definition_name).map { |name, type|
    GraphQL::Language::Nodes::VariableDefinition.new(name: name.to_s, type: variable_node(type))
  }
end

.variable_node(type) ⇒ Object

Internal: Get AST node for GraphQL type.

type - A GraphQL::Type

Returns GraphQL::Language::Nodes::Type.


68
69
70
71
72
73
74
75
76
77
# File 'lib/graphql/client/definition_variables.rb', line 68

def self.variable_node(type)
  case type
  when GraphQL::NonNullType
    GraphQL::Language::Nodes::NonNullType.new(of_type: variable_node(type.of_type))
  when GraphQL::ListType
    GraphQL::Language::Nodes::ListType.new(of_type: variable_node(type.of_type))
  else
    GraphQL::Language::Nodes::TypeName.new(name: type.name)
  end
end

.variables(schema, document, definition_name = nil) ⇒ Object

Internal: Detect all variables used in a given operation or fragment definition.

schema - A GraphQL::Schema document - A GraphQL::Language::Nodes::Document to scan definition_name - A String definition name. Defaults to anonymous definition.

Returns a Hash to GraphQL::Type objects.


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
# File 'lib/graphql/client/definition_variables.rb', line 16

def self.variables(schema, document, definition_name = nil)
  unless schema.is_a?(GraphQL::Schema)
    raise TypeError, "expected schema to be a GraphQL::Schema, but was #{schema.class}"
  end

  unless document.is_a?(GraphQL::Language::Nodes::Document)
    raise TypeError, "expected document to be a GraphQL::Language::Nodes::Document, but was #{document.class}"
  end

  sliced_document = GraphQL::Language::DefinitionSlice.slice(document, definition_name)

  visitor = GraphQL::Language::Visitor.new(sliced_document)
  type_stack = GraphQL::StaticValidation::TypeStack.new(schema, visitor)

  variables = {}

  visitor[GraphQL::Language::Nodes::VariableIdentifier] << ->(node, parent) do
    if definition = type_stack.argument_definitions.last
      existing_type = variables[node.name.to_sym]

      if existing_type && existing_type.unwrap != definition.type.unwrap
        raise GraphQL::Client::ValidationError, "$#{node.name} was already declared as #{existing_type.unwrap}, but was #{definition.type.unwrap}"
      elsif !existing_type.is_a?(GraphQL::NonNullType)
        variables[node.name.to_sym] = definition.type
      end
    end
  end

  visitor.visit

  variables
end