Repository URL to install this package:
|
Version:
1.8.2 ▾
|
# frozen_string_literal: true
module GraphQL
module Compatibility
module ExecutionSpecification
module SpecificationSchema
BOGUS_NODE = OpenStruct.new({ bogus: true })
DATA = {
"1001" => OpenStruct.new({
name: "Fannie Lou Hamer",
birthdate: Time.new(1917, 10, 6),
organization_ids: [],
}),
"1002" => OpenStruct.new({
name: "John Lewis",
birthdate: Time.new(1940, 2, 21),
organization_ids: ["2001"],
}),
"1003" => OpenStruct.new({
name: "Diane Nash",
birthdate: Time.new(1938, 5, 15),
organization_ids: ["2001", "2002"],
}),
"1004" => OpenStruct.new({
name: "Ralph Abernathy",
birthdate: Time.new(1926, 3, 11),
organization_ids: ["2002"],
}),
"2001" => OpenStruct.new({
name: "SNCC",
leader_id: nil, # fail on purpose
}),
"2002" => OpenStruct.new({
name: "SCLC",
leader_id: "1004",
}),
"2003" => BOGUS_NODE,
}
# A list object must implement #each
class CustomCollection
def initialize(storage)
@storage = storage
end
def each
@storage.each { |i| yield(i) }
end
end
module TestMiddleware
# TODO: Once deprecated `next_middleware` argument becomes unsupported, add `&` to the argument
def self.call(parent_type, parent_object, field_definition, field_args, query_context, next_middleware)
query_context[:middleware_log] && query_context[:middleware_log] << field_definition.name
next_middleware.call
end
end
def self.build(execution_strategy)
organization_type = nil
timestamp_type = GraphQL::ScalarType.define do
name "Timestamp"
coerce_input ->(value, _ctx) { Time.at(value.to_i) }
coerce_result ->(value, _ctx) { value.to_i }
end
named_entity_interface_type = GraphQL::InterfaceType.define do
name "NamedEntity"
field :name, !types.String
end
person_type = GraphQL::ObjectType.define do
name "Person"
interfaces [named_entity_interface_type]
field :name, !types.String
field :birthdate, timestamp_type
field :age, types.Int do
argument :on, !timestamp_type
resolve ->(obj, args, ctx) {
if obj.birthdate.nil?
nil
else
age_on = args[:on]
age_years = age_on.year - obj.birthdate.year
this_year_birthday = Time.new(age_on.year, obj.birthdate.month, obj.birthdate.day)
if this_year_birthday > age_on
age_years -= 1
end
end
age_years
}
end
field :organizations, types[organization_type] do
resolve ->(obj, args, ctx) {
CustomCollection.new(obj.organization_ids.map { |id| DATA[id] })
}
end
field :first_organization, !organization_type do
resolve ->(obj, args, ctx) {
DATA[obj.organization_ids.first]
}
end
end
organization_type = GraphQL::ObjectType.define do
name "Organization"
interfaces [named_entity_interface_type]
field :name, !types.String
field :leader, !person_type do
resolve ->(obj, args, ctx) {
DATA[obj.leader_id] || (ctx[:return_error] ? ExecutionError.new("Error on Nullable") : nil)
}
end
field :returnedError, types.String do
resolve ->(o, a, c) {
GraphQL::ExecutionError.new("This error was returned")
}
end
field :raisedError, types.String do
resolve ->(o, a, c) {
raise GraphQL::ExecutionError.new("This error was raised")
}
end
field :nodePresence, !types[!types.Boolean] do
resolve ->(o, a, ctx) {
[
ctx.irep_node.is_a?(GraphQL::InternalRepresentation::Node),
ctx.ast_node.is_a?(GraphQL::Language::Nodes::AbstractNode),
false, # just testing
]
}
end
end
node_union_type = GraphQL::UnionType.define do
name "Node"
possible_types [person_type, organization_type]
end
query_type = GraphQL::ObjectType.define do
name "Query"
field :node, node_union_type do
argument :id, !types.ID
resolve ->(obj, args, ctx) {
obj[args[:id]]
}
end
field :requiredNode, node_union_type.to_non_null_type do
argument :id, !types.ID
resolve ->(obj, args, ctx) {
obj[args[:id]]
}
end
field :organization, !organization_type do
argument :id, !types.ID
resolve ->(obj, args, ctx) {
if args[:id].start_with?("2")
obj[args[:id]]
else
# test context.skip
ctx.skip
end
}
end
field :organizations, types[organization_type] do
resolve ->(obj, args, ctx) {
[obj["2001"], obj["2002"]]
}
end
end
GraphQL::Schema.define do
query_execution_strategy execution_strategy
query query_type
resolve_type ->(type, obj, ctx) {
if obj.respond_to?(:birthdate)
person_type
elsif obj.respond_to?(:leader_id)
organization_type
else
nil
end
}
type_error ->(err, ctx) {
ctx[:type_errors] && (ctx[:type_errors] << err.value)
ctx[:gobble] || GraphQL::Schema::DefaultTypeError.call(err, ctx)
}
middleware(TestMiddleware)
end
end
end
end
end
end