class GraphQL::Language::Printer

def print(node, indent: "")

Returns:
  • (String) - Valid GraphQL for `node`

Parameters:
  • indent (String) -- Whitespace to add to the printed node

Other tags:
    Example: Building a custom printer -
    Example: Turning a document into a query string -
def print(node, indent: "")
  print_node(node, indent: indent)
end

def print_argument(argument)

def print_argument(argument)
  "#{argument.name}: #{print_node(argument.value)}".dup
end

def print_arguments(arguments, indent: "")

def print_arguments(arguments, indent: "")
  if arguments.all?{ |arg| !arg.description }
    return "(#{arguments.map{ |arg| print_input_value_definition(arg) }.join(", ")})"
  end
  out = "(\n".dup
  out << arguments.map.with_index{ |arg, i|
    "#{print_description(arg, indent: "  " + indent, first_in_block: i == 0)}  #{indent}"\
    "#{print_input_value_definition(arg)}"
  }.join("\n")
  out << "\n#{indent})"
end

def print_description(node, indent: "", first_in_block: true)

def print_description(node, indent: "", first_in_block: true)
  return ''.dup unless node.description
  description = indent != '' && !first_in_block ? "\n".dup : "".dup
  description << GraphQL::Language::BlockString.print(node.description, indent: indent)
end

def print_directive(directive)

def print_directive(directive)
  out = "@#{directive.name}".dup
  if directive.arguments.any?
    out << "(#{directive.arguments.map { |a| print_argument(a) }.join(", ")})"
  end
  out
end

def print_directive_definition(directive)

def print_directive_definition(directive)
  out = print_description(directive)
  out << "directive @#{directive.name}"
  if directive.arguments.any?
    out << print_arguments(directive.arguments)
  end
  out << " on #{directive.locations.map(&:name).join(' | ')}"
end

def print_directives(directives)

def print_directives(directives)
  if directives.any?
    directives.map { |d| " #{print_directive(d)}" }.join
  else
    ""
  end
end

def print_document(document)

def print_document(document)
  document.definitions.map { |d| print_node(d) }.join("\n\n")
end

def print_enum(enum)

def print_enum(enum)
  "#{enum.name}".dup
end

def print_enum_type_definition(enum_type)

def print_enum_type_definition(enum_type)
  out = print_description(enum_type)
  out << "enum #{enum_type.name}#{print_directives(enum_type.directives)} {\n"
  enum_type.values.each.with_index do |value, i|
    out << print_description(value, indent: '  ', first_in_block: i == 0)
    out << print_enum_value_definition(value)
  end
  out << "}"
end

def print_enum_value_definition(enum_value)

def print_enum_value_definition(enum_value)
  out = "  #{enum_value.name}".dup
  out << print_directives(enum_value.directives)
  out << "\n"
end

def print_field(field, indent: "")

def print_field(field, indent: "")
  out = "#{indent}".dup
  out << "#{field.alias}: " if field.alias
  out << "#{field.name}"
  out << "(#{field.arguments.map { |a| print_argument(a) }.join(", ")})" if field.arguments.any?
  out << print_directives(field.directives)
  out << print_selections(field.selections, indent: indent)
  out
end

def print_field_definition(field)

def print_field_definition(field)
  out = field.name.dup
  unless field.arguments.empty?
    out << print_arguments(field.arguments, indent: "  ")
  end
  out << ": #{print_node(field.type)}"
  out << print_directives(field.directives)
end

def print_field_definitions(fields)

def print_field_definitions(fields)
  out = " {\n".dup
  fields.each.with_index do |field, i|
    out << print_description(field, indent: '  ', first_in_block: i == 0)
    out << "  #{print_field_definition(field)}\n"
  end
  out << "}"
end

def print_fragment_definition(fragment_def, indent: "")

def print_fragment_definition(fragment_def, indent: "")
  out = "#{indent}fragment #{fragment_def.name}".dup
  if fragment_def.type
    out << " on #{print_node(fragment_def.type)}"
  end
  out << print_directives(fragment_def.directives)
  out << print_selections(fragment_def.selections, indent: indent)
  out
end

def print_fragment_spread(fragment_spread, indent: "")

def print_fragment_spread(fragment_spread, indent: "")
  out = "#{indent}...#{fragment_spread.name}".dup
  out << print_directives(fragment_spread.directives)
  out
end

def print_inline_fragment(inline_fragment, indent: "")

def print_inline_fragment(inline_fragment, indent: "")
  out = "#{indent}...".dup
  if inline_fragment.type
    out << " on #{print_node(inline_fragment.type)}"
  end
  out << print_directives(inline_fragment.directives)
  out << print_selections(inline_fragment.selections, indent: indent)
  out
end

def print_input_object(input_object)

def print_input_object(input_object)
  "{#{input_object.arguments.map { |a| "#{a.name}: #{print(a.value)}" }.join(", ")}}"
end

def print_input_object_type_definition(input_object_type)

def print_input_object_type_definition(input_object_type)
  out = print_description(input_object_type)
  out << "input #{input_object_type.name}"
  out << print_directives(input_object_type.directives)
  out << " {\n"
  input_object_type.fields.each.with_index do |field, i|
    out << print_description(field, indent: '  ', first_in_block: i == 0)
    out << "  #{print_input_value_definition(field)}\n"
  end
  out << "}"
end

def print_input_value_definition(input_value)

def print_input_value_definition(input_value)
  out = "#{input_value.name}: #{print_node(input_value.type)}".dup
  out << " = #{print_node(input_value.default_value)}" unless input_value.default_value.nil?
  out << print_directives(input_value.directives)
end

def print_interface_type_definition(interface_type)

def print_interface_type_definition(interface_type)
  out = print_description(interface_type)
  out << "interface #{interface_type.name}"
  out << print_directives(interface_type.directives)
  out << print_field_definitions(interface_type.fields)
end

def print_list_type(list_type)

def print_list_type(list_type)
  "[#{print_node(list_type.of_type)}]".dup
end

def print_node(node, indent: "")

def print_node(node, indent: "")
  case node
  when Nodes::Document
    print_document(node)
  when Nodes::Argument
    print_argument(node)
  when Nodes::Directive
    print_directive(node)
  when Nodes::Enum
    print_enum(node)
  when Nodes::NullValue
    print_null_value
  when Nodes::Field
    print_field(node, indent: indent)
  when Nodes::FragmentDefinition
    print_fragment_definition(node, indent: indent)
  when Nodes::FragmentSpread
    print_fragment_spread(node, indent: indent)
  when Nodes::InlineFragment
    print_inline_fragment(node, indent: indent)
  when Nodes::InputObject
    print_input_object(node)
  when Nodes::ListType
    print_list_type(node)
  when Nodes::NonNullType
    print_non_null_type(node)
  when Nodes::OperationDefinition
    print_operation_definition(node, indent: indent)
  when Nodes::TypeName
    print_type_name(node)
  when Nodes::VariableDefinition
    print_variable_definition(node)
  when Nodes::VariableIdentifier
    print_variable_identifier(node)
  when Nodes::SchemaDefinition
    print_schema_definition(node)
  when Nodes::ScalarTypeDefinition
    print_scalar_type_definition(node)
  when Nodes::ObjectTypeDefinition
    print_object_type_definition(node)
  when Nodes::InputValueDefinition
    print_input_value_definition(node)
  when Nodes::FieldDefinition
    print_field_definition(node)
  when Nodes::InterfaceTypeDefinition
    print_interface_type_definition(node)
  when Nodes::UnionTypeDefinition
    print_union_type_definition(node)
  when Nodes::EnumTypeDefinition
    print_enum_type_definition(node)
  when Nodes::EnumValueDefinition
    print_enum_value_definition(node)
  when Nodes::InputObjectTypeDefinition
    print_input_object_type_definition(node)
  when Nodes::DirectiveDefinition
    print_directive_definition(node)
  when FalseClass, Float, Integer, NilClass, String, TrueClass, Symbol
    GraphQL::Language.serialize(node)
  when Array
    "[#{node.map { |v| print_node(v) }.join(", ")}]".dup
  when Hash
    "{#{node.map { |k, v| "#{k}: #{print_node(v)}" }.join(", ")}}".dup
  else
    GraphQL::Language.serialize(node.to_s)
  end
end

def print_non_null_type(non_null_type)

def print_non_null_type(non_null_type)
  "#{print_node(non_null_type.of_type)}!".dup
end

def print_null_value

def print_null_value
  "null".dup
end

def print_object_type_definition(object_type)

def print_object_type_definition(object_type)
  out = print_description(object_type)
  out << "type #{object_type.name}"
  out << " implements " << object_type.interfaces.map(&:name).join(" & ") unless object_type.interfaces.empty?
  out << print_directives(object_type.directives)
  out << print_field_definitions(object_type.fields)
end

def print_operation_definition(operation_definition, indent: "")

def print_operation_definition(operation_definition, indent: "")
  out = "#{indent}#{operation_definition.operation_type}".dup
  out << " #{operation_definition.name}" if operation_definition.name
  if operation_definition.variables.any?
    out << "(#{operation_definition.variables.map { |v| print_variable_definition(v) }.join(", ")})"
  end
  out << print_directives(operation_definition.directives)
  out << print_selections(operation_definition.selections, indent: indent)
  out
end

def print_scalar_type_definition(scalar_type)

def print_scalar_type_definition(scalar_type)
  out = print_description(scalar_type)
  out << "scalar #{scalar_type.name}"
  out << print_directives(scalar_type.directives)
end

def print_schema_definition(schema)

def print_schema_definition(schema)
  if (schema.query.nil? || schema.query == 'Query') &&
     (schema.mutation.nil? || schema.mutation == 'Mutation') &&
     (schema.subscription.nil? || schema.subscription == 'Subscription') &&
     (schema.directives.none?)
    return
  end
  out = "schema".dup
  if schema.directives.any?
    schema.directives.each do |dir|
      out << "\n  "
      out << print_node(dir)
    end
    out << "\n{"
  else
    out << " {\n"
  end
  out << "  query: #{schema.query}\n" if schema.query
  out << "  mutation: #{schema.mutation}\n" if schema.mutation
  out << "  subscription: #{schema.subscription}\n" if schema.subscription
  out << "}"
end

def print_selections(selections, indent: "")

def print_selections(selections, indent: "")
  if selections.any?
    out = " {\n".dup
    selections.each do |selection|
      out << print_node(selection, indent: indent + "  ") << "\n"
    end
    out << "#{indent}}"
  else
    ""
  end
end

def print_type_name(type_name)

def print_type_name(type_name)
  "#{type_name.name}".dup
end

def print_union_type_definition(union_type)

def print_union_type_definition(union_type)
  out = print_description(union_type)
  out << "union #{union_type.name}"
  out << print_directives(union_type.directives)
  out << " = " + union_type.types.map(&:name).join(" | ")
end

def print_variable_definition(variable_definition)

def print_variable_definition(variable_definition)
  out = "$#{variable_definition.name}: #{print_node(variable_definition.type)}".dup
  out << " = #{print_node(variable_definition.default_value)}" unless variable_definition.default_value.nil?
  out
end

def print_variable_identifier(variable_identifier)

def print_variable_identifier(variable_identifier)
  "$#{variable_identifier.name}".dup
end