Module: GraphQL::Language::Generation

Extended by:
Generation
Included in:
Generation
Defined in:
lib/graphql/language/generation.rb

Overview

Exposes #generate, which turns AST nodes back into query strings.

Instance Method Summary collapse

Instance Method Details

#generate(node, indent: "") ⇒ String

Turn an AST node back into a string.

Examples:

Turning a document into a query

document = GraphQL.parse(query_string)
GraphQL::Language::Generation.generate(document)
# => "{ ... }"

Parameters:

Returns:

  • (String)

    Valid GraphQL for ‘node`



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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/graphql/language/generation.rb', line 17

def generate(node, indent: "")
  case node
  when Nodes::Document
    node.definitions.map { |d| generate(d) }.join("\n\n")
  when Nodes::Argument
    "#{node.name}: #{generate(node.value)}"
  when Nodes::Directive
    "@#{node.name}(#{node.arguments.map { |a| generate(a) }.join(", ")})"
  when Nodes::Enum
    "#{node.name}"
  when Nodes::Field
    out = "#{indent}"
    out << "#{node.alias}: " if node.alias
    out << "#{node.name}"
    out << "(#{node.arguments.map { |a| generate(a) }.join(", ")})" if node.arguments.any?
    out << generate_directives(node.directives)
    out << generate_selections(node.selections, indent: indent)
    out
  when Nodes::FragmentDefinition
    out = "#{indent}fragment #{node.name}"
    out << " on #{node.type}" if node.type
    out << generate_directives(node.directives)
    out << generate_selections(node.selections, indent: indent)
    out

  when Nodes::FragmentSpread
    out = "#{indent}...#{node.name}"
    out << generate_directives(node.directives)
    out
  when Nodes::InlineFragment
    out = "#{indent}..."
    out << " on #{node.type}" if node.type
    out << generate_directives(node.directives)
    out << generate_selections(node.selections, indent: indent)
    out
  when Nodes::InputObject
    generate(node.to_h)
  when Nodes::ListType
    "[#{generate(node.of_type)}]"
  when Nodes::NonNullType
    "#{generate(node.of_type)}!"
  when Nodes::OperationDefinition
    out = "#{indent}#{node.operation_type}"
    out << " #{node.name}" if node.name
    out << "(#{node.variables.map { |v| generate(v) }.join(", ")})" if node.variables.any?
    out << generate_directives(node.directives)
    out << generate_selections(node.selections, indent: indent)
    out
  when Nodes::TypeName
    "#{node.name}"
  when Nodes::VariableDefinition
    out = "$#{node.name}: #{generate(node.type)}"
    out << " = #{generate(node.default_value)}" unless node.default_value.nil?
    out
  when Nodes::VariableIdentifier
    "$#{node.name}"
  when Nodes::SchemaDefinition
    out = "schema {\n"
    out << "  query: #{node.query}\n" if node.query
    out << "  mutation: #{node.mutation}\n" if node.mutation
    out << "  subscription: #{node.subscription}\n" if node.subscription
    out << "}"
  when Nodes::ScalarTypeDefinition
    "scalar #{node.name}"
  when Nodes::ObjectTypeDefinition
    out = "type #{node.name}"
    out << " implements " << node.interfaces.join(", ") unless node.interfaces.empty?
    out << generate_field_definitions(node.fields)
  when Nodes::InputValueDefinition
    out = "#{node.name}: #{generate(node.type)}"
    out << " = #{generate(node.default_value)}" unless node.default_value.nil?
    out
  when Nodes::FieldDefinition
    out = node.name.dup
    unless node.arguments.empty?
      out << "(" << node.arguments.map{ |arg| generate(arg) }.join(", ") << ")"
    end
    out << ": #{generate(node.type)}"
  when Nodes::InterfaceTypeDefinition
    out = "interface #{node.name}"
    out << generate_field_definitions(node.fields)
  when Nodes::UnionTypeDefinition
    "union #{node.name} = " + node.types.join(" | ")
  when Nodes::EnumTypeDefinition
    out = "enum #{node.name} {\n"
    node.values.each do |value|
      out << "  #{value}\n"
    end
    out << "}"
  when Nodes::InputObjectTypeDefinition
    out = "input #{node.name} {\n"
    node.fields.each do |field|
      out << "  #{generate(field)}\n"
    end
    out << "}"
  when Nodes::AbstractNode
    node.to_query_string(indent: indent)
  when FalseClass, Float, Integer, NilClass, String, TrueClass
    JSON.generate(node, quirks_mode: true)
  when Array
    "[#{node.map { |v| generate(v) }.join(", ")}]"
  when Hash
    "{ #{node.map { |k, v| "#{k}: #{generate(v)}" }.join(", ")} }"
  else
    raise TypeError
  end
end