Introspection::_typeKind()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 45
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 4.5763

Importance

Changes 0
Metric Value
eloc 31
dl 0
loc 45
ccs 3
cts 22
cp 0.1364
rs 9.424
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 4.5763
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQL\Type;
6
7
use Exception;
8
use GraphQL\Language\DirectiveLocation;
9
use GraphQL\Language\Printer;
10
use GraphQL\Type\Definition\Directive;
11
use GraphQL\Type\Definition\EnumType;
12
use GraphQL\Type\Definition\FieldArgument;
13
use GraphQL\Type\Definition\FieldDefinition;
14
use GraphQL\Type\Definition\InputObjectField;
15
use GraphQL\Type\Definition\InputObjectType;
16
use GraphQL\Type\Definition\InterfaceType;
17
use GraphQL\Type\Definition\ListOfType;
18
use GraphQL\Type\Definition\NonNull;
19
use GraphQL\Type\Definition\ObjectType;
20
use GraphQL\Type\Definition\ResolveInfo;
21
use GraphQL\Type\Definition\ScalarType;
22
use GraphQL\Type\Definition\Type;
23
use GraphQL\Type\Definition\UnionType;
24
use GraphQL\Type\Definition\WrappingType;
25
use GraphQL\Utils\AST;
26
use GraphQL\Utils\Utils;
27
use function array_filter;
28
use function array_key_exists;
29
use function array_values;
30
use function is_bool;
31
use function method_exists;
32
use function trigger_error;
33
use const E_USER_DEPRECATED;
34
35
class Introspection
36
{
37
    const SCHEMA_FIELD_NAME    = '__schema';
38
    const TYPE_FIELD_NAME      = '__type';
39
    const TYPE_NAME_FIELD_NAME = '__typename';
40
41
    /** @var array<string, mixed> */
42
    private static $map = [];
43
44
    /**
45
     * Options:
46
     *   - descriptions
47
     *     Whether to include descriptions in the introspection result.
48
     *     Default: true
49
     *
50
     * @param bool[]|bool $options
51
     *
52
     * @return string
53
     */
54 5
    public static function getIntrospectionQuery($options = [])
55
    {
56 5
        if (is_bool($options)) {
57
            trigger_error(
58
                'Calling Introspection::getIntrospectionQuery(boolean) is deprecated. ' .
59
                'Please use Introspection::getIntrospectionQuery(["descriptions" => boolean]).',
60
                E_USER_DEPRECATED
61
            );
62
            $descriptions = $options;
63
        } else {
64 5
            $descriptions = ! array_key_exists('descriptions', $options) || $options['descriptions'] === true;
65
        }
66 5
        $descriptionField = $descriptions ? 'description' : '';
67
68
        return <<<EOD
69
  query IntrospectionQuery {
70
    __schema {
71
      queryType { name }
72
      mutationType { name }
73
      subscriptionType { name }
74
      types {
75
        ...FullType
76
      }
77
      directives {
78
        name
79 5
        {$descriptionField}
80
        locations
81
        args {
82
          ...InputValue
83
        }
84
      }
85
    }
86
  }
87
88
  fragment FullType on __Type {
89
    kind
90
    name
91 5
    {$descriptionField}
92
    fields(includeDeprecated: true) {
93
      name
94 5
      {$descriptionField}
95
      args {
96
        ...InputValue
97
      }
98
      type {
99
        ...TypeRef
100
      }
101
      isDeprecated
102
      deprecationReason
103
    }
104
    inputFields {
105
      ...InputValue
106
    }
107
    interfaces {
108
      ...TypeRef
109
    }
110
    enumValues(includeDeprecated: true) {
111
      name
112 5
      {$descriptionField}
113
      isDeprecated
114
      deprecationReason
115
    }
116
    possibleTypes {
117
      ...TypeRef
118
    }
119
  }
120
121
  fragment InputValue on __InputValue {
122
    name
123 5
    {$descriptionField}
124
    type { ...TypeRef }
125
    defaultValue
126
  }
127
128
  fragment TypeRef on __Type {
129
    kind
130
    name
131
    ofType {
132
      kind
133
      name
134
      ofType {
135
        kind
136
        name
137
        ofType {
138
          kind
139
          name
140
          ofType {
141
            kind
142
            name
143
            ofType {
144
              kind
145
              name
146
              ofType {
147
                kind
148
                name
149
                ofType {
150
                  kind
151
                  name
152
                }
153
              }
154
            }
155
          }
156
        }
157
      }
158
    }
159
  }
160
EOD;
161
    }
162
163
    /**
164
     * @param Type $type
165
     *
166
     * @return bool
167
     */
168 138
    public static function isIntrospectionType($type)
169
    {
170 138
        return array_key_exists($type->name, self::getTypes());
171
    }
172
173 889
    public static function getTypes()
174
    {
175
        return [
176 889
            '__Schema'            => self::_schema(),
177 889
            '__Type'              => self::_type(),
178 889
            '__Directive'         => self::_directive(),
179 889
            '__Field'             => self::_field(),
180 889
            '__InputValue'        => self::_inputValue(),
181 889
            '__EnumValue'         => self::_enumValue(),
182 889
            '__TypeKind'          => self::_typeKind(),
183 889
            '__DirectiveLocation' => self::_directiveLocation(),
184
        ];
185
    }
186
187 889
    public static function _schema()
188
    {
189 889
        if (! isset(self::$map['__Schema'])) {
190
            self::$map['__Schema'] = new ObjectType([
191
                'name'            => '__Schema',
192
                'isIntrospection' => true,
193
                'description'     =>
194
                    'A GraphQL Schema defines the capabilities of a GraphQL ' .
195
                    'server. It exposes all available types and directives on ' .
196
                    'the server, as well as the entry points for query, mutation, and ' .
197
                    'subscription operations.',
198
                'fields'          => [
199
                    'types'            => [
200
                        'description' => 'A list of all types supported by this server.',
201
                        'type'        => new NonNull(new ListOfType(new NonNull(self::_type()))),
202
                        'resolve'     => static function (Schema $schema) {
203 4
                            return array_values($schema->getTypeMap());
204
                        },
205
                    ],
206
                    'queryType'        => [
207
                        'description' => 'The type that query operations will be rooted at.',
208
                        'type'        => new NonNull(self::_type()),
209
                        'resolve'     => static function (Schema $schema) {
210 5
                            return $schema->getQueryType();
211
                        },
212
                    ],
213
                    'mutationType'     => [
214
                        'description' =>
215
                            'If this server supports mutation, the type that ' .
216
                            'mutation operations will be rooted at.',
217
                        'type'        => self::_type(),
218
                        'resolve'     => static function (Schema $schema) {
219 3
                            return $schema->getMutationType();
220
                        },
221
                    ],
222
                    'subscriptionType' => [
223
                        'description' => 'If this server support subscription, the type that subscription operations will be rooted at.',
224
                        'type'        => self::_type(),
225
                        'resolve'     => static function (Schema $schema) {
226 3
                            return $schema->getSubscriptionType();
227
                        },
228
                    ],
229
                    'directives'       => [
230
                        'description' => 'A list of all directives supported by this server.',
231
                        'type'        => Type::nonNull(Type::listOf(Type::nonNull(self::_directive()))),
232
                        'resolve'     => static function (Schema $schema) {
233 3
                            return $schema->getDirectives();
234
                        },
235
                    ],
236
                ],
237
            ]);
238
        }
239
240 889
        return self::$map['__Schema'];
241
    }
242
243 889
    public static function _type()
244
    {
245 889
        if (! isset(self::$map['__Type'])) {
246
            self::$map['__Type'] = new ObjectType([
247
                'name'            => '__Type',
248
                'isIntrospection' => true,
249
                'description'     =>
250
                    'The fundamental unit of any GraphQL Schema is the type. There are ' .
251
                    'many kinds of types in GraphQL as represented by the `__TypeKind` enum.' .
252
                    "\n\n" .
253
                    'Depending on the kind of a type, certain fields describe ' .
254
                    'information about that type. Scalar types provide no information ' .
255
                    'beyond a name and description, while Enum types provide their values. ' .
256
                    'Object and Interface types provide the fields they describe. Abstract ' .
257
                    'types, Union and Interface, provide the Object types possible ' .
258
                    'at runtime. List and NonNull types compose other types.',
259
                'fields'          => static function () {
260
                    return [
261
                        'kind'          => [
262
                            'type'    => Type::nonNull(self::_typeKind()),
263
                            'resolve' => static function (Type $type) {
264
                                switch (true) {
265 10
                                    case $type instanceof ListOfType:
266 6
                                        return TypeKind::LIST_KIND;
267 10
                                    case $type instanceof NonNull:
268 6
                                        return TypeKind::NON_NULL;
269 10
                                    case $type instanceof ScalarType:
270 7
                                        return TypeKind::SCALAR;
271 9
                                    case $type instanceof ObjectType:
272 4
                                        return TypeKind::OBJECT;
273 8
                                    case $type instanceof EnumType:
274 5
                                        return TypeKind::ENUM;
275 4
                                    case $type instanceof InputObjectType:
276 1
                                        return TypeKind::INPUT_OBJECT;
277 3
                                    case $type instanceof InterfaceType:
278 3
                                        return TypeKind::INTERFACE_KIND;
279 1
                                    case $type instanceof UnionType:
280 1
                                        return TypeKind::UNION;
281
                                    default:
282
                                        throw new Exception('Unknown kind of type: ' . Utils::printSafe($type));
283
                                }
284
                            },
285
                        ],
286
                        'name'          => [
287
                            'type' => Type::string(),
288
                            'resolve' => static function ($obj) {
289 21
                                return $obj->name;
290
                            },
291
                        ],
292
                        'description'   => [
293
                            'type' => Type::string(),
294
                            'resolve' => static function ($obj) {
295 5
                                return $obj->description;
296
                            },
297
                        ],
298
                        'fields'        => [
299
                            'type'    => Type::listOf(Type::nonNull(self::_field())),
300
                            'args'    => [
301
                                'includeDeprecated' => ['type' => Type::boolean(), 'defaultValue' => false],
302
                            ],
303
                            'resolve' => static function (Type $type, $args) {
304 10
                                if ($type instanceof ObjectType || $type instanceof InterfaceType) {
305 10
                                    $fields = $type->getFields();
306
307 10
                                    if (empty($args['includeDeprecated'])) {
308 6
                                        $fields = array_filter(
309 6
                                            $fields,
310
                                            static function (FieldDefinition $field) {
311 6
                                                return ! $field->deprecationReason;
312 6
                                            }
313
                                        );
314
                                    }
315
316 10
                                    return array_values($fields);
317
                                }
318
319 4
                                return null;
320
                            },
321
                        ],
322
                        'interfaces'    => [
323
                            'type'    => Type::listOf(Type::nonNull(self::_type())),
324
                            'resolve' => static function ($type) {
325 4
                                if ($type instanceof ObjectType) {
326 3
                                    return $type->getInterfaces();
327
                                }
328
329 4
                                return null;
330
                            },
331
                        ],
332
                        'possibleTypes' => [
333
                            'type'    => Type::listOf(Type::nonNull(self::_type())),
334
                            'resolve' => static function ($type, $args, $context, ResolveInfo $info) {
335 4
                                if ($type instanceof InterfaceType || $type instanceof UnionType) {
336 1
                                    return $info->schema->getPossibleTypes($type);
337
                                }
338
339 3
                                return null;
340
                            },
341
                        ],
342
                        'enumValues'    => [
343
                            'type'    => Type::listOf(Type::nonNull(self::_enumValue())),
344
                            'args'    => [
345
                                'includeDeprecated' => ['type' => Type::boolean(), 'defaultValue' => false],
346
                            ],
347
                            'resolve' => static function ($type, $args) {
348 7
                                if ($type instanceof EnumType) {
349 6
                                    $values = array_values($type->getValues());
350
351 6
                                    if (empty($args['includeDeprecated'])) {
352 2
                                        $values = array_filter(
353 2
                                            $values,
354
                                            static function ($value) {
355 2
                                                return ! $value->deprecationReason;
356 2
                                            }
357
                                        );
358
                                    }
359
360 6
                                    return $values;
361
                                }
362
363 4
                                return null;
364
                            },
365
                        ],
366
                        'inputFields'   => [
367
                            'type'    => Type::listOf(Type::nonNull(self::_inputValue())),
368
                            'resolve' => static function ($type) {
369 5
                                if ($type instanceof InputObjectType) {
370 1
                                    return array_values($type->getFields());
371
                                }
372
373 4
                                return null;
374
                            },
375
                        ],
376
                        'ofType'        => [
377
                            'type'    => self::_type(),
378
                            'resolve' => static function ($type) {
379 6
                                if ($type instanceof WrappingType) {
380 6
                                    return $type->getWrappedType();
381
                                }
382
383 6
                                return null;
384
                            },
385
                        ],
386
                    ];
387
                },
388
            ]);
389
        }
390
391 889
        return self::$map['__Type'];
392
    }
393
394 889
    public static function _typeKind()
395
    {
396 889
        if (! isset(self::$map['__TypeKind'])) {
397
            self::$map['__TypeKind'] = new EnumType([
398
                'name'            => '__TypeKind',
399
                'isIntrospection' => true,
400
                'description'     => 'An enum describing what kind of type a given `__Type` is.',
401
                'values'          => [
402
                    'SCALAR'       => [
403
                        'value'       => TypeKind::SCALAR,
404
                        'description' => 'Indicates this type is a scalar.',
405
                    ],
406
                    'OBJECT'       => [
407
                        'value'       => TypeKind::OBJECT,
408
                        'description' => 'Indicates this type is an object. `fields` and `interfaces` are valid fields.',
409
                    ],
410
                    'INTERFACE'    => [
411
                        'value'       => TypeKind::INTERFACE_KIND,
412
                        'description' => 'Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.',
413
                    ],
414
                    'UNION'        => [
415
                        'value'       => TypeKind::UNION,
416
                        'description' => 'Indicates this type is a union. `possibleTypes` is a valid field.',
417
                    ],
418
                    'ENUM'         => [
419
                        'value'       => TypeKind::ENUM,
420
                        'description' => 'Indicates this type is an enum. `enumValues` is a valid field.',
421
                    ],
422
                    'INPUT_OBJECT' => [
423
                        'value'       => TypeKind::INPUT_OBJECT,
424
                        'description' => 'Indicates this type is an input object. `inputFields` is a valid field.',
425
                    ],
426
                    'LIST'         => [
427
                        'value'       => TypeKind::LIST_KIND,
428
                        'description' => 'Indicates this type is a list. `ofType` is a valid field.',
429
                    ],
430
                    'NON_NULL'     => [
431
                        'value'       => TypeKind::NON_NULL,
432
                        'description' => 'Indicates this type is a non-null. `ofType` is a valid field.',
433
                    ],
434
                ],
435
            ]);
436
        }
437
438 889
        return self::$map['__TypeKind'];
439
    }
440
441 889
    public static function _field()
442
    {
443 889
        if (! isset(self::$map['__Field'])) {
444
            self::$map['__Field'] = new ObjectType([
445
                'name'            => '__Field',
446
                'isIntrospection' => true,
447
                'description'     =>
448
                    'Object and Interface types are described by a list of Fields, each of ' .
449
                    'which has a name, potentially a list of arguments, and a return type.',
450
                'fields'          => static function () {
451
                    return [
452
                        'name'              => [
453
                            'type' => Type::nonNull(Type::string()),
454
                            'resolve' => static function (FieldDefinition $field) {
455 10
                                return $field->name;
456
                            },
457
                        ],
458
                        'description'       => [
459
                            'type' => Type::string(),
460
                            'resolve' => static function (FieldDefinition $field) {
461 3
                                return $field->description;
462
                            },
463
                        ],
464
                        'args'              => [
465
                            'type'    => Type::nonNull(Type::listOf(Type::nonNull(self::_inputValue()))),
466
                            'resolve' => static function (FieldDefinition $field) {
467 4
                                return empty($field->args) ? [] : $field->args;
468
                            },
469
                        ],
470
                        'type'              => [
471
                            'type'    => Type::nonNull(self::_type()),
472
                            'resolve' => static function (FieldDefinition $field) {
473 5
                                return $field->getType();
474
                            },
475
                        ],
476
                        'isDeprecated'      => [
477
                            'type'    => Type::nonNull(Type::boolean()),
478
                            'resolve' => static function (FieldDefinition $field) {
479 4
                                return (bool) $field->deprecationReason;
480
                            },
481
                        ],
482
                        'deprecationReason' => [
483
                            'type'    => Type::string(),
484
                            'resolve' => static function (FieldDefinition $field) {
485 4
                                return $field->deprecationReason;
486
                            },
487
                        ],
488
                    ];
489
                },
490
            ]);
491
        }
492
493 889
        return self::$map['__Field'];
494
    }
495
496 889
    public static function _inputValue()
497
    {
498 889
        if (! isset(self::$map['__InputValue'])) {
499
            self::$map['__InputValue'] = new ObjectType([
500
                'name'            => '__InputValue',
501
                'isIntrospection' => true,
502
                'description'     =>
503
                    'Arguments provided to Fields or Directives and the input fields of an ' .
504
                    'InputObject are represented as Input Values which describe their type ' .
505
                    'and optionally a default value.',
506
                'fields'          => static function () {
507
                    return [
508
                        'name'         => [
509
                            'type' => Type::nonNull(Type::string()),
510
                            'resolve' => static function ($inputValue) {
511
                                /** @var FieldArgument|InputObjectField $inputValue */
512 5
                                $inputValue = $inputValue;
513
514 5
                                return $inputValue->name;
515
                            },
516
                        ],
517
                        'description'  => [
518
                            'type' => Type::string(),
519
                            'resolve' => static function ($inputValue) {
520
                                /** @var FieldArgument|InputObjectField $inputValue */
521 3
                                $inputValue = $inputValue;
522
523 3
                                return $inputValue->description;
524
                            },
525
                        ],
526
                        'type'         => [
527
                            'type'    => Type::nonNull(self::_type()),
528
                            'resolve' => static function ($value) {
529 5
                                return method_exists($value, 'getType')
530 5
                                    ? $value->getType()
531 5
                                    : $value->type;
532
                            },
533
                        ],
534
                        'defaultValue' => [
535
                            'type'        => Type::string(),
536
                            'description' =>
537
                                'A GraphQL-formatted string representing the default value for this input value.',
538
                            'resolve'     => static function ($inputValue) {
539
                                /** @var FieldArgument|InputObjectField $inputValue */
540 5
                                $inputValue = $inputValue;
541
542 5
                                return ! $inputValue->defaultValueExists()
543 5
                                    ? null
544 4
                                    : Printer::doPrint(AST::astFromValue(
545 4
                                        $inputValue->defaultValue,
546 5
                                        $inputValue->getType()
0 ignored issues
show
Bug introduced by
$inputValue->getType() of type GraphQL\Type\Definition\Type is incompatible with the type GraphQL\Type\Definition\InputType expected by parameter $type of GraphQL\Utils\AST::astFromValue(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

546
                                        /** @scrutinizer ignore-type */ $inputValue->getType()
Loading history...
547
                                    ));
548
                            },
549
                        ],
550
                    ];
551
                },
552
            ]);
553
        }
554
555 889
        return self::$map['__InputValue'];
556
    }
557
558 889
    public static function _enumValue()
559
    {
560 889
        if (! isset(self::$map['__EnumValue'])) {
561
            self::$map['__EnumValue'] = new ObjectType([
562
                'name'            => '__EnumValue',
563
                'isIntrospection' => true,
564
                'description'     =>
565
                    'One possible value for a given Enum. Enum values are unique values, not ' .
566
                    'a placeholder for a string or numeric value. However an Enum value is ' .
567
                    'returned in a JSON response as a string.',
568
                'fields'          => [
569
                    'name'              => [
570
                        'type' => Type::nonNull(Type::string()),
571
                        'resolve' => static function ($enumValue) {
572 6
                            return $enumValue->name;
573
                        },
574
                    ],
575
                    'description'       => [
576
                        'type' => Type::string(),
577
                        'resolve' => static function ($enumValue) {
578 3
                            return $enumValue->description;
579
                        },
580
                    ],
581
                    'isDeprecated'      => [
582
                        'type'    => Type::nonNull(Type::boolean()),
583
                        'resolve' => static function ($enumValue) {
584 4
                            return (bool) $enumValue->deprecationReason;
585
                        },
586
                    ],
587
                    'deprecationReason' => [
588
                        'type' => Type::string(),
589
                        'resolve' => static function ($enumValue) {
590 4
                            return $enumValue->deprecationReason;
591
                        },
592
                    ],
593
                ],
594
            ]);
595
        }
596
597 889
        return self::$map['__EnumValue'];
598
    }
599
600 889
    public static function _directive()
601
    {
602 889
        if (! isset(self::$map['__Directive'])) {
603
            self::$map['__Directive'] = new ObjectType([
604
                'name'            => '__Directive',
605
                'isIntrospection' => true,
606
                'description'     => 'A Directive provides a way to describe alternate runtime execution and ' .
607
                    'type validation behavior in a GraphQL document.' .
608
                    "\n\nIn some cases, you need to provide options to alter GraphQL's " .
609
                    'execution behavior in ways field arguments will not suffice, such as ' .
610
                    'conditionally including or skipping a field. Directives provide this by ' .
611
                    'describing additional information to the executor.',
612
                'fields'          => [
613
                    'name'        => [
614
                        'type'    => Type::nonNull(Type::string()),
615
                        'resolve' => static function ($obj) {
616 3
                            return $obj->name;
617
                        },
618
                    ],
619
                    'description' => [
620
                        'type' => Type::string(),
621
                        'resolve' => static function ($obj) {
622 2
                            return $obj->description;
623
                        },
624
                    ],
625
                    'locations'   => [
626
                        'type' => Type::nonNull(Type::listOf(Type::nonNull(
627
                            self::_directiveLocation()
628
                        ))),
629
                        'resolve' => static function ($obj) {
630 3
                            return $obj->locations;
631
                        },
632
                    ],
633
                    'args'        => [
634
                        'type'    => Type::nonNull(Type::listOf(Type::nonNull(self::_inputValue()))),
635
                        'resolve' => static function (Directive $directive) {
636 3
                            return $directive->args ?: [];
637
                        },
638
                    ],
639
                ],
640
            ]);
641
        }
642
643 889
        return self::$map['__Directive'];
644
    }
645
646 889
    public static function _directiveLocation()
647
    {
648 889
        if (! isset(self::$map['__DirectiveLocation'])) {
649
            self::$map['__DirectiveLocation'] = new EnumType([
650
                'name'            => '__DirectiveLocation',
651
                'isIntrospection' => true,
652
                'description'     =>
653
                    'A Directive can be adjacent to many parts of the GraphQL language, a ' .
654
                    '__DirectiveLocation describes one such possible adjacencies.',
655
                'values'          => [
656
                    'QUERY'                  => [
657
                        'value'       => DirectiveLocation::QUERY,
658
                        'description' => 'Location adjacent to a query operation.',
659
                    ],
660
                    'MUTATION'               => [
661
                        'value'       => DirectiveLocation::MUTATION,
662
                        'description' => 'Location adjacent to a mutation operation.',
663
                    ],
664
                    'SUBSCRIPTION'           => [
665
                        'value'       => DirectiveLocation::SUBSCRIPTION,
666
                        'description' => 'Location adjacent to a subscription operation.',
667
                    ],
668
                    'FIELD'                  => [
669
                        'value'       => DirectiveLocation::FIELD,
670
                        'description' => 'Location adjacent to a field.',
671
                    ],
672
                    'FRAGMENT_DEFINITION'    => [
673
                        'value'       => DirectiveLocation::FRAGMENT_DEFINITION,
674
                        'description' => 'Location adjacent to a fragment definition.',
675
                    ],
676
                    'FRAGMENT_SPREAD'        => [
677
                        'value'       => DirectiveLocation::FRAGMENT_SPREAD,
678
                        'description' => 'Location adjacent to a fragment spread.',
679
                    ],
680
                    'INLINE_FRAGMENT'        => [
681
                        'value'       => DirectiveLocation::INLINE_FRAGMENT,
682
                        'description' => 'Location adjacent to an inline fragment.',
683
                    ],
684
                    'VARIABLE_DEFINITION'    => [
685
                        'value'       => DirectiveLocation::VARIABLE_DEFINITION,
686
                        'description' => 'Location adjacent to a variable definition.',
687
                    ],
688
                    'SCHEMA'                 => [
689
                        'value'       => DirectiveLocation::SCHEMA,
690
                        'description' => 'Location adjacent to a schema definition.',
691
                    ],
692
                    'SCALAR'                 => [
693
                        'value'       => DirectiveLocation::SCALAR,
694
                        'description' => 'Location adjacent to a scalar definition.',
695
                    ],
696
                    'OBJECT'                 => [
697
                        'value'       => DirectiveLocation::OBJECT,
698
                        'description' => 'Location adjacent to an object type definition.',
699
                    ],
700
                    'FIELD_DEFINITION'       => [
701
                        'value'       => DirectiveLocation::FIELD_DEFINITION,
702
                        'description' => 'Location adjacent to a field definition.',
703
                    ],
704
                    'ARGUMENT_DEFINITION'    => [
705
                        'value'       => DirectiveLocation::ARGUMENT_DEFINITION,
706
                        'description' => 'Location adjacent to an argument definition.',
707
                    ],
708
                    'INTERFACE'              => [
709
                        'value'       => DirectiveLocation::IFACE,
710
                        'description' => 'Location adjacent to an interface definition.',
711
                    ],
712
                    'UNION'                  => [
713
                        'value'       => DirectiveLocation::UNION,
714
                        'description' => 'Location adjacent to a union definition.',
715
                    ],
716
                    'ENUM'                   => [
717
                        'value'       => DirectiveLocation::ENUM,
718
                        'description' => 'Location adjacent to an enum definition.',
719
                    ],
720
                    'ENUM_VALUE'             => [
721
                        'value'       => DirectiveLocation::ENUM_VALUE,
722
                        'description' => 'Location adjacent to an enum value definition.',
723
                    ],
724
                    'INPUT_OBJECT'           => [
725
                        'value'       => DirectiveLocation::INPUT_OBJECT,
726
                        'description' => 'Location adjacent to an input object type definition.',
727
                    ],
728
                    'INPUT_FIELD_DEFINITION' => [
729
                        'value'       => DirectiveLocation::INPUT_FIELD_DEFINITION,
730
                        'description' => 'Location adjacent to an input object field definition.',
731
                    ],
732
733
                ],
734
            ]);
735
        }
736
737 889
        return self::$map['__DirectiveLocation'];
738
    }
739
740 476
    public static function schemaMetaFieldDef() : FieldDefinition
741
    {
742 476
        if (! isset(self::$map[self::SCHEMA_FIELD_NAME])) {
743 1
            self::$map[self::SCHEMA_FIELD_NAME] = FieldDefinition::create([
744 1
                'name'        => self::SCHEMA_FIELD_NAME,
745 1
                'type'        => Type::nonNull(self::_schema()),
746 1
                'description' => 'Access the current type schema of this server.',
747
                'args'        => [],
748
                'resolve'     => static function (
749
                    $source,
750
                    $args,
751
                    $context,
752
                    ResolveInfo $info
753
                ) {
754 6
                    return $info->schema;
755 1
                },
756
            ]);
757
        }
758
759 476
        return self::$map[self::SCHEMA_FIELD_NAME];
760
    }
761
762 477
    public static function typeMetaFieldDef() : FieldDefinition
763
    {
764 477
        if (! isset(self::$map[self::TYPE_FIELD_NAME])) {
765 1
            self::$map[self::TYPE_FIELD_NAME] = FieldDefinition::create([
766 1
                'name'        => self::TYPE_FIELD_NAME,
767 1
                'type'        => self::_type(),
768 1
                'description' => 'Request the type information of a single type.',
769
                'args'        => [
770 1
                    ['name' => 'name', 'type' => Type::nonNull(Type::string())],
771
                ],
772
                'resolve'     => static function ($source, $args, $context, ResolveInfo $info) {
773 15
                    return $info->schema->getType($args['name']);
774 1
                },
775
            ]);
776
        }
777
778 477
        return self::$map[self::TYPE_FIELD_NAME];
779
    }
780
781 481
    public static function typeNameMetaFieldDef() : FieldDefinition
782
    {
783 481
        if (! isset(self::$map[self::TYPE_NAME_FIELD_NAME])) {
784 1
            self::$map[self::TYPE_NAME_FIELD_NAME] = FieldDefinition::create([
785 1
                'name'        => self::TYPE_NAME_FIELD_NAME,
786 1
                'type'        => Type::nonNull(Type::string()),
787 1
                'description' => 'The name of the current Object type at runtime.',
788
                'args'        => [],
789
                'resolve'     => static function (
790
                    $source,
791
                    $args,
792
                    $context,
793
                    ResolveInfo $info
794
                ) {
795 7
                    return $info->parentType->name;
796 1
                },
797
            ]);
798
        }
799
800 481
        return self::$map[self::TYPE_NAME_FIELD_NAME];
801
    }
802
}
803