File Coverage

blib/lib/GraphQL/Directive.pm
Criterion Covered Total %
statement 68 68 100.0
branch 15 24 62.5
condition n/a
subroutine 15 15 100.0
pod 1 1 100.0
total 99 108 91.6


line stmt bran cond sub pod time code
1              
2             use 5.014;
3 17     17   351 use strict;
  17         59  
4 17     17   83 use warnings;
  17         38  
  17         319  
5 17     17   72 use Moo;
  17         32  
  17         406  
6 17     17   78 use MooX::Thunking;
  17         28  
  17         107  
7 17     17   10223 use GraphQL::MaybeTypeCheck;
  17         185225  
  17         108  
8 17     17   2246 use GraphQL::Debug qw(_debug);
  17         33  
  17         109  
9 17     17   94 use Types::Standard -all;
  17         37  
  17         750  
10 17     17   93 use GraphQL::Type::Library -all;
  17         37  
  17         118  
11 17     17   676310 use GraphQL::Type::Scalar qw($Boolean $String);
  17         37  
  17         144  
12 17     17   206579 with qw(
  17         63  
  17         2922  
13             GraphQL::Role::Named
14             GraphQL::Role::FieldsEither
15             );
16              
17             our $VERSION = '0.02';
18             use constant DEBUG => $ENV{GRAPHQL_DEBUG};
19 17     17   134  
  17         36  
  17         2204  
20             my @LOCATIONS = qw(
21             QUERY
22             MUTATION
23             SUBSCRIPTION
24             FIELD
25             FRAGMENT_DEFINITION
26             FRAGMENT_SPREAD
27             INLINE_FRAGMENT
28             SCHEMA
29             SCALAR
30             OBJECT
31             FIELD_DEFINITION
32             ARGUMENT_DEFINITION
33             INTERFACE
34             UNION
35             ENUM
36             ENUM_VALUE
37             INPUT_OBJECT
38             INPUT_FIELD_DEFINITION
39             );
40              
41             =head1 NAME
42              
43             GraphQL::Directive - GraphQL directive
44              
45             =head1 SYNOPSIS
46              
47             use GraphQL::Directive;
48             my $directive = GraphQL::Directive->new(
49             name => 'Object',
50             interfaces => [ $interfaceType ],
51             fields => { field_name => { type => $scalar_type, resolve => sub { '' } }},
52             );
53              
54             =head1 ATTRIBUTES
55              
56             Has C<name>, C<description> from L<GraphQL::Role::Named>.
57              
58             =head2 locations
59              
60             Array-ref of locations where the directive can occur. Must be one of
61             these strings:
62              
63             QUERY
64             MUTATION
65             SUBSCRIPTION
66             FIELD
67             FRAGMENT_DEFINITION
68             FRAGMENT_SPREAD
69             INLINE_FRAGMENT
70             SCHEMA
71             SCALAR
72             OBJECT
73             FIELD_DEFINITION
74             ARGUMENT_DEFINITION
75             INTERFACE
76             UNION
77             ENUM
78             ENUM_VALUE
79             INPUT_OBJECT
80             INPUT_FIELD_DEFINITION
81              
82             =cut
83              
84             has locations => (is => 'ro', isa => ArrayRef[Enum[@LOCATIONS]], required => 1);
85              
86             =head2 args
87              
88             Hash-ref of arguments. See L<GraphQL::Type::Library/FieldMapInput>.
89              
90             =cut
91              
92             has args => (is => 'thunked', isa => FieldMapInput, required => 1);
93              
94             =head1 METHODS
95              
96             =head2 from_ast
97              
98             See L<GraphQL::Type/from_ast>.
99              
100             =cut
101              
102             method from_ast(
103             HashRef $name2type,
104             HashRef $ast_node,
105             ) :ReturnType(InstanceOf[__PACKAGE__]) {
106 9 50   9 1 353 DEBUG and _debug('Directive.from_ast', $ast_node);
  9 50       25  
  9 50       18  
  9 50       21  
  9         31  
  9         80  
  9         52  
107 9         15 $self->new(
108             $self->_from_ast_named($ast_node),
109             locations => $ast_node->{locations},
110             $self->_from_ast_fields($name2type, $ast_node, 'args'),
111 9         36 );
112             }
113 17     17   5229  
  17         34  
  17         148  
114             has to_doc => (is => 'lazy', isa => Str);
115             my ($self) = @_;
116             DEBUG and _debug('Directive.to_doc', $self);
117 3     3   43 my @start = (
118 3         5 $self->_description_doc_lines($self->description),
119 3         43 "directive \@@{[$self->name]}(",
120             );
121 3         20 my @argtuples = $self->_make_fieldtuples($self->args);
122             DEBUG and _debug('Directive.to_doc(args)', \@argtuples);
123 3         65 my $end = ") on " . join(' | ', @{$self->locations});
124 3         6 return join("\n", @start).join(
125 3         7 ', ', map $_->[0], @argtuples
  3         16  
126 3 100       50 ).$end."\n" if !grep $_->[1], @argtuples; # no descriptions
127             # if descriptions
128             join '', map "$_\n",
129             @start,
130             (map {
131             my ($main, @description) = @$_;
132             (
133 1         3 map length() ? " $_" : "", @description, $main,
  1         4  
134             )
135 1 50       28 } @argtuples),
136             $end;
137             }
138              
139             =head1 PACKAGE VARIABLES
140              
141             =head2 $GraphQL::Directive::DEPRECATED
142              
143             =cut
144              
145             $GraphQL::Directive::DEPRECATED = GraphQL::Directive->new(
146             name => 'deprecated',
147             description => 'Marks an element of a GraphQL schema as no longer supported.',
148             locations => [ qw(FIELD_DEFINITION ENUM_VALUE) ],
149             args => {
150             reason => {
151             type => $String,
152             description =>
153             'Explains why this element was deprecated, usually also including ' .
154             'a suggestion for how to access supported similar data. Formatted ' .
155             'in [Markdown](https://daringfireball.net/projects/markdown/).',
156             default_value => 'No longer supported',
157             },
158             },
159             );
160              
161             =head2 $GraphQL::Directive::INCLUDE
162              
163             =cut
164              
165             $GraphQL::Directive::INCLUDE = GraphQL::Directive->new(
166             name => 'include',
167             description => 'Directs the executor to include this field or fragment only when the `if` argument is true.',
168             locations => [ qw(FIELD FRAGMENT_SPREAD INLINE_FRAGMENT) ],
169             args => {
170             if => {
171             type => $Boolean->non_null,
172             description => 'Included when true.',
173             },
174             },
175             );
176              
177             =head2 $GraphQL::Directive::SKIP
178              
179             =cut
180              
181             $GraphQL::Directive::SKIP = GraphQL::Directive->new(
182             name => 'skip',
183             description => 'Directs the executor to skip this field or fragment when the `if` argument is true.',
184             locations => [ qw(FIELD FRAGMENT_SPREAD INLINE_FRAGMENT) ],
185             args => {
186             if => {
187             type => $Boolean->non_null,
188             description => 'Skipped when true.',
189             },
190             },
191             );
192              
193             =head2 @GraphQL::Directive::SPECIFIED_DIRECTIVES
194              
195             Not exported. Contains the three GraphQL-specified directives: C<@skip>,
196             C<@include>, C<@deprecated>, each of which are available with the
197             variables above. Use if you want to have these plus your own directives
198             in your schema:
199              
200             my $schema = GraphQL::Schema->new(
201             # ...
202             directives => [ @GraphQL::Directive::SPECIFIED_DIRECTIVES, $my_directive ],
203             );
204              
205             =cut
206              
207             @GraphQL::Directive::SPECIFIED_DIRECTIVES = (
208             $GraphQL::Directive::INCLUDE,
209             $GraphQL::Directive::SKIP,
210             $GraphQL::Directive::DEPRECATED,
211             );
212              
213             method _get_directive_values(
214             HashRef $node,
215             HashRef $variables,
216             ) {
217             DEBUG and _debug('_get_directive_values', $self->name, $node, $variables);
218 4723 50   4723   7093 my ($d) = grep $_->{name} eq $self->name, @{$node->{directives} || []};
  4723 50       6426  
  4723 50       5167  
  4723 50       5711  
  4723         7184  
  4723         25271  
  4723         22421  
219 4723         4545 return if !$d;
220 4723 100       4867 GraphQL::Execution::_get_argument_values($self, $d, $variables);
  4723         12853  
221 4723 100       9895 }
222 21         95  
223             __PACKAGE__->meta->make_immutable();
224              
225             1;