1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
# frozen_string_literal: true
require "graphql"
require "graphql/client/type_stack"
module GraphQL
class Client
# Internal: Use schema to detect definition and field types.
module DocumentTypes
class AnalyzeTypesVisitor < GraphQL::Language::Visitor
prepend GraphQL::Client::TypeStack
attr_reader :fields
def initialize(*a, **kw)
@fields = {}
super
end
def on_operation_definition(node, _parent)
@fields[node] = @object_types.last
super
end
def on_fragment_definition(node, _parent)
@fields[node] = @object_types.last
super
end
def on_inline_fragment(node, _parent)
@fields[node] = @object_types.last
super
end
def on_field(node, _parent)
@fields[node] = @field_definitions.last.type
super
end
end
# Internal: Detect all types used in a given document
#
# schema - A GraphQL::Schema
# document - A GraphQL::Language::Nodes::Document to scan
#
# Returns a Hash[Language::Nodes::Node] to GraphQL::Type objects.
def self.analyze_types(schema, document)
unless schema.is_a?(GraphQL::Schema) || (schema.is_a?(Class) && schema < 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 schema to be a GraphQL::Language::Nodes::Document, but was #{document.class}"
end
visitor = AnalyzeTypesVisitor.new(document, schema: schema)
visitor.visit
visitor.fields
rescue StandardError => err
if err.is_a?(TypeError)
raise
end
# FIXME: TypeStack my crash on invalid documents
visitor.fields
end
end
end
end
|