Skip to content

Instantly share code, notes, and snippets.

@rzane
Last active December 14, 2021 17:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rzane/e415f04bb84a89a27e51f5492701dda7 to your computer and use it in GitHub Desktop.
Save rzane/e415f04bb84a89a27e51f5492701dda7 to your computer and use it in GitHub Desktop.
Print fields used by GraphQL query
require "set"
require "graphql"
require "json"
SCHEMA_PATH = ENV.fetch("SCHEMA") do
abort "Run with SCHEMA=<path-to-schema.json> and try again."
end
SCHEMA = JSON.parse(File.read(SCHEMA_PATH))
REFERENCES = Hash.new do |h, t|
h[t] = Hash.new { |h2, f| h2[f] = Set.new }
end
def get_field_type(type_name, field_name)
types = SCHEMA["__schema"]["types"]
type = types.find { _1["name"] == type_name }
raise "No type named #{type_name}" unless type
fields = type.fetch("fields", [])
field = fields.find { _1["name"] == field_name }
raise "No field named #{type_name}.#{field_name}" unless field
field_type = field["type"]
field_type = field_type["ofType"] while field_type["ofType"]
field_type["name"]
end
def add_fields(type, selections, fragments:)
fields = selections.grep(GraphQL::Language::Nodes::Field)
fields.each do |field|
field_type = get_field_type(type, field.name)
field_location = "#{field.filename}:#{field.line}"
REFERENCES[type][field.name] << field_location
add_fields(field_type, field.selections, fragments: fragments)
end
spreads = selections.grep(GraphQL::Language::Nodes::FragmentSpread)
spreads.each do |spread|
fragment = fragments[spread.name]
raise "No fragment named #{spread.name}" unless fragment
add_fields(fragment.type.name, fragment.selections, fragments: fragments)
end
end
ARGV.each do |path|
document = GraphQL.parse_file(path)
fragments = document.definitions.grep(GraphQL::Language::Nodes::FragmentDefinition)
fragments = fragments.to_h { [_1.name, _1] }
operations = document.definitions.grep(GraphQL::Language::Nodes::OperationDefinition)
operations.each do |operation|
operation_type = operation.operation_type.capitalize
add_fields(operation_type, operation.selections, fragments: fragments)
end
end
REFERENCES.sort.each do |type, fields|
puts "#{type}:"
fields.sort.each do |field, locations|
puts " #{field}:"
locations.sort.each do |location|
puts " #{location}"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment