package GraphQL::Role::Abstract;
use 5.014;
use strict;
use warnings;
use Moo::Role;
use GraphQL::MaybeTypeCheck;
use Types::Standard -all;
our $VERSION = '0.02';
=head1 NAME
GraphQL::Role::Abstract - GraphQL object role
=head1 SYNOPSIS
with qw(GraphQL::Role::Abstract);
# or runtime
Role::Tiny->apply_roles_to_object($foo, qw(GraphQL::Role::Abstract));
=head1 DESCRIPTION
Allows type constraints for abstract objects.
=cut
method _complete_value(
HashRef $context,
ArrayRef[HashRef] $nodes,
HashRef $info,
ArrayRef $path,
Any $result,
) {
my $runtime_type = ($self->resolve_type || \&_default_resolve_type)->(
$result, $context->{context_value}, $info, $self
);
# TODO promise stuff
$self->_ensure_valid_runtime_type(
$runtime_type,
$context,
$nodes,
$info,
$result,
)->_complete_value(@_);
}
method _ensure_valid_runtime_type(
(Str | InstanceOf['GraphQL::Type::Object']) $runtime_type_or_name,
HashRef $context,
ArrayRef[HashRef] $nodes,
HashRef $info,
Any $result,
) :ReturnType(InstanceOf['GraphQL::Type::Object']) {
my $runtime_type = is_InstanceOf($runtime_type_or_name)
? $runtime_type_or_name
: $context->{schema}->name2type->{$runtime_type_or_name};
die GraphQL::Error->new(
message => "Abstract type @{[$self->name]} must resolve to an " .
"Object type at runtime for field @{[$info->{parent_type}->name]}." .
"@{[$info->{field_name}]} with value $result, received '@{[$runtime_type->name]}'.",
nodes => [ $nodes ],
) if !$runtime_type->isa('GraphQL::Type::Object');
die GraphQL::Error->new(
message => "Runtime Object type '@{[$runtime_type->name]}' is not a possible type for " .
"'@{[$self->name]}'.",
nodes => [ $nodes ],
) if !$context->{schema}->is_possible_type($self, $runtime_type);
$runtime_type;
}
fun _default_resolve_type(
Any $value,
Any $context,
HashRef $info,
(ConsumerOf['GraphQL::Role::Abstract']) $abstract_type,
) {
my @possibles = @{ $info->{schema}->get_possible_types($abstract_type) };
# TODO promise stuff
(grep $_->is_type_of->($value, $context, $info), grep $_->is_type_of, @possibles)[0];
}
__PACKAGE__->meta->make_immutable();
1;