GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Introspection::schemaMetaFieldDef()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 2

Importance

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

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