Failed Conditions
Push — master ( 7ff3e9...e7de06 )
by Vladimir
04:33 queued 01:54
created

ASTDefinitionBuilder::buildType()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
c 0
b 0
f 0
rs 10
ccs 4
cts 4
cp 1
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQL\Utils;
6
7
use GraphQL\Error\Error;
8
use GraphQL\Executor\Values;
9
use GraphQL\Language\AST\DirectiveDefinitionNode;
10
use GraphQL\Language\AST\EnumTypeDefinitionNode;
11
use GraphQL\Language\AST\EnumTypeExtensionNode;
12
use GraphQL\Language\AST\EnumValueDefinitionNode;
13
use GraphQL\Language\AST\FieldDefinitionNode;
14
use GraphQL\Language\AST\InputObjectTypeDefinitionNode;
15
use GraphQL\Language\AST\InputValueDefinitionNode;
16
use GraphQL\Language\AST\InterfaceTypeDefinitionNode;
17
use GraphQL\Language\AST\ListTypeNode;
18
use GraphQL\Language\AST\NamedTypeNode;
19
use GraphQL\Language\AST\Node;
20
use GraphQL\Language\AST\NodeKind;
21
use GraphQL\Language\AST\NonNullTypeNode;
22
use GraphQL\Language\AST\ObjectTypeDefinitionNode;
23
use GraphQL\Language\AST\ScalarTypeDefinitionNode;
24
use GraphQL\Language\AST\TypeNode;
25
use GraphQL\Language\AST\UnionTypeDefinitionNode;
26
use GraphQL\Language\Token;
27
use GraphQL\Type\Definition\CustomScalarType;
28
use GraphQL\Type\Definition\Directive;
29
use GraphQL\Type\Definition\EnumType;
30
use GraphQL\Type\Definition\FieldArgument;
31
use GraphQL\Type\Definition\InputObjectType;
32
use GraphQL\Type\Definition\InputType;
33
use GraphQL\Type\Definition\InterfaceType;
34
use GraphQL\Type\Definition\NonNull;
35
use GraphQL\Type\Definition\ObjectType;
36
use GraphQL\Type\Definition\Type;
37
use GraphQL\Type\Definition\UnionType;
38
use Throwable;
39
use function array_reverse;
40
use function implode;
41
use function is_array;
42
use function is_string;
43
use function sprintf;
44
45
class ASTDefinitionBuilder
46
{
47
    /** @var Node[] */
48
    private $typeDefintionsMap;
49
50
    /** @var callable */
51
    private $typeConfigDecorator;
52
53
    /** @var bool[] */
54
    private $options;
55
56
    /** @var callable */
57
    private $resolveType;
58
59
    /** @var Type[] */
60
    private $cache;
61
62
    /**
63
     * @param Node[] $typeDefintionsMap
64
     * @param bool[] $options
65
     */
66 155
    public function __construct(
67
        array $typeDefintionsMap,
68
        $options,
69
        callable $resolveType,
70
        ?callable $typeConfigDecorator = null
71
    ) {
72 155
        $this->typeDefintionsMap   = $typeDefintionsMap;
73 155
        $this->typeConfigDecorator = $typeConfigDecorator;
74 155
        $this->options             = $options;
75 155
        $this->resolveType         = $resolveType;
76
77 155
        $this->cache = Type::getAllBuiltInTypes();
78 155
    }
79
80 13
    public function buildDirective(DirectiveDefinitionNode $directiveNode)
81
    {
82 13
        return new Directive([
83 13
            'name'        => $directiveNode->name->value,
84 13
            'description' => $this->getDescription($directiveNode),
85 13
            'locations'   => Utils::map(
86 13
                $directiveNode->locations,
87
                static function ($node) {
88 13
                    return $node->value;
89 13
                }
90
            ),
91 13
            'args'        => $directiveNode->arguments ? FieldArgument::createMap($this->makeInputValues($directiveNode->arguments)) : null,
92 13
            'astNode'     => $directiveNode,
93
        ]);
94
    }
95
96
    /**
97
     * Given an ast node, returns its string description.
98
     */
99 146
    private function getDescription($node)
100
    {
101 146
        if ($node->description) {
102 7
            return $node->description->value;
103
        }
104 143
        if (isset($this->options['commentDescriptions'])) {
105 3
            $rawValue = $this->getLeadingCommentBlock($node);
106 3
            if ($rawValue !== null) {
107 3
                return BlockString::value("\n" . $rawValue);
108
            }
109
        }
110
111 140
        return null;
112
    }
113
114 3
    private function getLeadingCommentBlock($node)
115
    {
116 3
        $loc = $node->loc;
117 3
        if (! $loc || ! $loc->startToken) {
118
            return null;
119
        }
120 3
        $comments = [];
121 3
        $token    = $loc->startToken->prev;
122 3
        while ($token &&
123 3
            $token->kind === Token::COMMENT &&
124 3
            $token->next && $token->prev &&
125 3
            $token->line + 1 === $token->next->line &&
126 3
            $token->line !== $token->prev->line
127
        ) {
128 3
            $value      = $token->value;
129 3
            $comments[] = $value;
130 3
            $token      = $token->prev;
131
        }
132
133 3
        return implode("\n", array_reverse($comments));
134
    }
135
136 134
    private function makeInputValues($values)
137
    {
138 134
        return Utils::keyValMap(
139 134
            $values,
140
            static function ($value) {
141 51
                return $value->name->value;
142 134
            },
143
            function ($value) {
144
                // Note: While this could make assertions to get the correctly typed
145
                // value, that would throw immediately while type system validation
146
                // with validateSchema() will produce more actionable results.
147 51
                $type   = $this->internalBuildWrappedType($value->type);
148
                $config = [
149 51
                    'name'        => $value->name->value,
150 51
                    'type'        => $type,
151 51
                    'description' => $this->getDescription($value),
152 51
                    'astNode'     => $value,
153
                ];
154 51
                if (isset($value->defaultValue)) {
155 8
                    $config['defaultValue'] = AST::valueFromAST($value->defaultValue, $type);
0 ignored issues
show
Bug introduced by
$type of type GraphQL\Type\Definition\Type is incompatible with the type GraphQL\Type\Definition\InputType expected by parameter $type of GraphQL\Utils\AST::valueFromAST(). ( Ignorable by Annotation )

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

155
                    $config['defaultValue'] = AST::valueFromAST($value->defaultValue, /** @scrutinizer ignore-type */ $type);
Loading history...
156
                }
157
158 51
                return $config;
159 134
            }
160
        );
161
    }
162
163
    /**
164
     * @return Type|InputType
165
     *
166
     * @throws Error
167
     */
168 134
    private function internalBuildWrappedType(TypeNode $typeNode)
169
    {
170 134
        $typeDef = $this->buildType($this->getNamedTypeNode($typeNode));
171
172 131
        return $this->buildWrappedType($typeDef, $typeNode);
173
    }
174
175
    /**
176
     * @param string|NamedTypeNode $ref
177
     *
178
     * @return Type
179
     *
180
     * @throws Error
181
     */
182 145
    public function buildType($ref)
183
    {
184 145
        if (is_string($ref)) {
185 108
            return $this->internalBuildType($ref);
186
        }
187
188 141
        return $this->internalBuildType($ref->name->value, $ref);
189
    }
190
191
    /**
192
     * @param string             $typeName
193
     * @param NamedTypeNode|null $typeNode
194
     *
195
     * @return Type
196
     *
197
     * @throws Error
198
     */
199 145
    private function internalBuildType($typeName, $typeNode = null)
200
    {
201 145
        if (! isset($this->cache[$typeName])) {
202 131
            if (isset($this->typeDefintionsMap[$typeName])) {
203 125
                $type = $this->makeSchemaDef($this->typeDefintionsMap[$typeName]);
204 125
                if ($this->typeConfigDecorator) {
205 2
                    $fn = $this->typeConfigDecorator;
206
                    try {
207 2
                        $config = $fn($type->config, $this->typeDefintionsMap[$typeName], $this->typeDefintionsMap);
208
                    } catch (Throwable $e) {
209
                        throw new Error(
210
                            sprintf('Type config decorator passed to %s threw an error ', static::class) .
211
                            sprintf('when building %s type: %s', $typeName, $e->getMessage()),
212
                            null,
213
                            null,
214
                            null,
215
                            null,
216
                            $e
217
                        );
218
                    }
219 2
                    if (! is_array($config) || isset($config[0])) {
220
                        throw new Error(
221
                            sprintf(
222
                                'Type config decorator passed to %s is expected to return an array, but got %s',
223
                                static::class,
224
                                Utils::getVariableType($config)
225
                            )
226
                        );
227
                    }
228 2
                    $type = $this->makeSchemaDefFromConfig($this->typeDefintionsMap[$typeName], $config);
229
                }
230 125
                $this->cache[$typeName] = $type;
231
            } else {
232 12
                $fn                     = $this->resolveType;
233 12
                $this->cache[$typeName] = $fn($typeName, $typeNode);
234
            }
235
        }
236
237 144
        return $this->cache[$typeName];
238
    }
239
240
    /**
241
     * @param ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode|EnumTypeDefinitionNode|ScalarTypeDefinitionNode|InputObjectTypeDefinitionNode|UnionTypeDefinitionNode $def
242
     *
243
     * @return CustomScalarType|EnumType|InputObjectType|InterfaceType|ObjectType|UnionType
244
     *
245
     * @throws Error
246
     */
247 125
    private function makeSchemaDef($def)
248
    {
249 125
        if (! $def) {
250
            throw new Error('def must be defined.');
251
        }
252 125
        switch ($def->kind) {
253 125
            case NodeKind::OBJECT_TYPE_DEFINITION:
254 120
                return $this->makeTypeDef($def);
0 ignored issues
show
Bug introduced by
It seems like $def can also be of type GraphQL\Language\AST\InterfaceTypeDefinitionNode and GraphQL\Language\AST\EnumTypeDefinitionNode and GraphQL\Language\AST\ScalarTypeDefinitionNode and GraphQL\Language\AST\InputObjectTypeDefinitionNode and GraphQL\Language\AST\UnionTypeDefinitionNode; however, parameter $def of GraphQL\Utils\ASTDefinitionBuilder::makeTypeDef() does only seem to accept GraphQL\Language\AST\ObjectTypeDefinitionNode, maybe add an additional type check? ( Ignorable by Annotation )

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

254
                return $this->makeTypeDef(/** @scrutinizer ignore-type */ $def);
Loading history...
255 69
            case NodeKind::INTERFACE_TYPE_DEFINITION:
256 31
                return $this->makeInterfaceDef($def);
0 ignored issues
show
Bug introduced by
It seems like $def can also be of type GraphQL\Language\AST\EnumTypeDefinitionNode and GraphQL\Language\AST\ScalarTypeDefinitionNode and GraphQL\Language\AST\InputObjectTypeDefinitionNode and GraphQL\Language\AST\UnionTypeDefinitionNode and GraphQL\Language\AST\ObjectTypeDefinitionNode; however, parameter $def of GraphQL\Utils\ASTDefinit...der::makeInterfaceDef() does only seem to accept GraphQL\Language\AST\InterfaceTypeDefinitionNode, maybe add an additional type check? ( Ignorable by Annotation )

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

256
                return $this->makeInterfaceDef(/** @scrutinizer ignore-type */ $def);
Loading history...
257 45
            case NodeKind::ENUM_TYPE_DEFINITION:
258 16
                return $this->makeEnumDef($def);
0 ignored issues
show
Bug introduced by
It seems like $def can also be of type GraphQL\Language\AST\InterfaceTypeDefinitionNode and GraphQL\Language\AST\ScalarTypeDefinitionNode and GraphQL\Language\AST\InputObjectTypeDefinitionNode and GraphQL\Language\AST\UnionTypeDefinitionNode and GraphQL\Language\AST\ObjectTypeDefinitionNode; however, parameter $def of GraphQL\Utils\ASTDefinitionBuilder::makeEnumDef() does only seem to accept GraphQL\Language\AST\EnumTypeDefinitionNode, maybe add an additional type check? ( Ignorable by Annotation )

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

258
                return $this->makeEnumDef(/** @scrutinizer ignore-type */ $def);
Loading history...
259 32
            case NodeKind::UNION_TYPE_DEFINITION:
260 16
                return $this->makeUnionDef($def);
0 ignored issues
show
Bug introduced by
It seems like $def can also be of type GraphQL\Language\AST\InterfaceTypeDefinitionNode and GraphQL\Language\AST\EnumTypeDefinitionNode and GraphQL\Language\AST\ScalarTypeDefinitionNode and GraphQL\Language\AST\InputObjectTypeDefinitionNode and GraphQL\Language\AST\ObjectTypeDefinitionNode; however, parameter $def of GraphQL\Utils\ASTDefinitionBuilder::makeUnionDef() does only seem to accept GraphQL\Language\AST\UnionTypeDefinitionNode, maybe add an additional type check? ( Ignorable by Annotation )

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

260
                return $this->makeUnionDef(/** @scrutinizer ignore-type */ $def);
Loading history...
261 20
            case NodeKind::SCALAR_TYPE_DEFINITION:
262 5
                return $this->makeScalarDef($def);
0 ignored issues
show
Bug introduced by
It seems like $def can also be of type GraphQL\Language\AST\InterfaceTypeDefinitionNode and GraphQL\Language\AST\EnumTypeDefinitionNode and GraphQL\Language\AST\InputObjectTypeDefinitionNode and GraphQL\Language\AST\UnionTypeDefinitionNode and GraphQL\Language\AST\ObjectTypeDefinitionNode; however, parameter $def of GraphQL\Utils\ASTDefinit...uilder::makeScalarDef() does only seem to accept GraphQL\Language\AST\ScalarTypeDefinitionNode, maybe add an additional type check? ( Ignorable by Annotation )

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

262
                return $this->makeScalarDef(/** @scrutinizer ignore-type */ $def);
Loading history...
263 16
            case NodeKind::INPUT_OBJECT_TYPE_DEFINITION:
264 16
                return $this->makeInputObjectDef($def);
0 ignored issues
show
Bug introduced by
It seems like $def can also be of type GraphQL\Language\AST\InterfaceTypeDefinitionNode and GraphQL\Language\AST\EnumTypeDefinitionNode and GraphQL\Language\AST\ScalarTypeDefinitionNode and GraphQL\Language\AST\UnionTypeDefinitionNode and GraphQL\Language\AST\ObjectTypeDefinitionNode; however, parameter $def of GraphQL\Utils\ASTDefinit...r::makeInputObjectDef() does only seem to accept GraphQL\Language\AST\InputObjectTypeDefinitionNode, maybe add an additional type check? ( Ignorable by Annotation )

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

264
                return $this->makeInputObjectDef(/** @scrutinizer ignore-type */ $def);
Loading history...
265
            default:
266
                throw new Error(sprintf('Type kind of %s not supported.', $def->kind));
267
        }
268
    }
269
270 120
    private function makeTypeDef(ObjectTypeDefinitionNode $def)
271
    {
272 120
        $typeName = $def->name->value;
273
274 120
        return new ObjectType([
275 120
            'name'        => $typeName,
276 120
            'description' => $this->getDescription($def),
277
            'fields'      => function () use ($def) {
278 112
                return $this->makeFieldDefMap($def);
279 120
            },
280
            'interfaces'  => function () use ($def) {
281 110
                return $this->makeImplementedInterfaces($def);
282 120
            },
283 120
            'astNode'     => $def,
284
        ]);
285
    }
286
287 113
    private function makeFieldDefMap($def)
288
    {
289 113
        return $def->fields
290 113
            ? Utils::keyValMap(
291 113
                $def->fields,
292
                static function ($field) {
293 113
                    return $field->name->value;
294 113
                },
295
                function ($field) {
296 113
                    return $this->buildField($field);
297 113
                }
298
            )
299 111
            : [];
300
    }
301
302 128
    public function buildField(FieldDefinitionNode $field)
303
    {
304
        return [
305
            // Note: While this could make assertions to get the correctly typed
306
            // value, that would throw immediately while type system validation
307
            // with validateSchema() will produce more actionable results.
308 128
            'type'              => $this->internalBuildWrappedType($field->type),
309 125
            'description'       => $this->getDescription($field),
310 125
            'args'              => $field->arguments ? $this->makeInputValues($field->arguments) : null,
311 125
            'deprecationReason' => $this->getDeprecationReason($field),
312 125
            'astNode'           => $field,
313
        ];
314
    }
315
316
    /**
317
     * Given a collection of directives, returns the string value for the
318
     * deprecation reason.
319
     *
320
     * @param EnumValueDefinitionNode | FieldDefinitionNode $node
321
     *
322
     * @return string
323
     */
324 128
    private function getDeprecationReason($node)
325
    {
326 128
        $deprecated = Values::getDirectiveValues(Directive::deprecatedDirective(), $node);
327
328 128
        return $deprecated['reason'] ?? null;
329
    }
330
331 110
    private function makeImplementedInterfaces(ObjectTypeDefinitionNode $def)
332
    {
333 110
        if ($def->interfaces) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $def->interfaces of type GraphQL\Language\AST\NamedTypeNode[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
334
            // Note: While this could make early assertions to get the correctly
335
            // typed values, that would throw immediately while type system
336
            // validation with validateSchema() will produce more actionable results.
337 29
            return Utils::map(
338 29
                $def->interfaces,
339
                function ($iface) {
340 29
                    return $this->buildType($iface);
341 29
                }
342
            );
343
        }
344
345 106
        return null;
346
    }
347
348 31
    private function makeInterfaceDef(InterfaceTypeDefinitionNode $def)
349
    {
350 31
        $typeName = $def->name->value;
351
352 31
        return new InterfaceType([
353 31
            'name'        => $typeName,
354 31
            'description' => $this->getDescription($def),
355
            'fields'      => function () use ($def) {
356 31
                return $this->makeFieldDefMap($def);
357 31
            },
358 31
            'astNode'     => $def,
359
        ]);
360
    }
361
362 16
    private function makeEnumDef(EnumTypeDefinitionNode $def)
363
    {
364 16
        return new EnumType([
365 16
            'name'        => $def->name->value,
366 16
            'description' => $this->getDescription($def),
367 16
            'values'      => $def->values
368 16
                ? Utils::keyValMap(
369 16
                    $def->values,
370
                    static function ($enumValue) {
371 15
                        return $enumValue->name->value;
372 16
                    },
373
                    function ($enumValue) {
374
                        return [
375 15
                            'description'       => $this->getDescription($enumValue),
376 15
                            'deprecationReason' => $this->getDeprecationReason($enumValue),
377 15
                            'astNode'           => $enumValue,
378
                        ];
379 16
                    }
380
                )
381
                : [],
382 16
            'astNode'     => $def,
383
        ]);
384
    }
385
386 16
    private function makeUnionDef(UnionTypeDefinitionNode $def)
387
    {
388 16
        return new UnionType([
389 16
            'name'        => $def->name->value,
390 16
            'description' => $this->getDescription($def),
391
            // Note: While this could make assertions to get the correctly typed
392
            // values below, that would throw immediately while type system
393
            // validation with validateSchema() will produce more actionable results.
394 16
            'types'       => $def->types
395 15
                ? Utils::map(
396 15
                    $def->types,
397
                    function ($typeNode) {
398 15
                        return $this->buildType($typeNode);
399 15
                    }
400
                ) :
401
                [],
402 15
            'astNode'     => $def,
403
        ]);
404
    }
405
406 5
    private function makeScalarDef(ScalarTypeDefinitionNode $def)
407
    {
408 5
        return new CustomScalarType([
409 5
            'name'        => $def->name->value,
410 5
            'description' => $this->getDescription($def),
411 5
            'astNode'     => $def,
412
            'serialize'   => static function ($value) {
413 1
                return $value;
414 5
            },
415
        ]);
416
    }
417
418 16
    private function makeInputObjectDef(InputObjectTypeDefinitionNode $def)
419
    {
420 16
        return new InputObjectType([
421 16
            'name'        => $def->name->value,
422 16
            'description' => $this->getDescription($def),
423
            'fields'      => function () use ($def) {
424 16
                return $def->fields
425 16
                    ? $this->makeInputValues($def->fields)
426 16
                    : [];
427 16
            },
428 16
            'astNode'     => $def,
429
        ]);
430
    }
431
432
    /**
433
     * @param ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode|EnumTypeExtensionNode|ScalarTypeDefinitionNode|InputObjectTypeDefinitionNode $def
434
     * @param mixed[]                                                                                                                           $config
435
     *
436
     * @return CustomScalarType|EnumType|InputObjectType|InterfaceType|ObjectType|UnionType
437
     *
438
     * @throws Error
439
     */
440 2
    private function makeSchemaDefFromConfig($def, array $config)
441
    {
442 2
        if (! $def) {
443
            throw new Error('def must be defined.');
444
        }
445 2
        switch ($def->kind) {
446 2
            case NodeKind::OBJECT_TYPE_DEFINITION:
447 2
                return new ObjectType($config);
448 2
            case NodeKind::INTERFACE_TYPE_DEFINITION:
449 2
                return new InterfaceType($config);
450 2
            case NodeKind::ENUM_TYPE_DEFINITION:
451 2
                return new EnumType($config);
452
            case NodeKind::UNION_TYPE_DEFINITION:
453
                return new UnionType($config);
454
            case NodeKind::SCALAR_TYPE_DEFINITION:
455
                return new CustomScalarType($config);
456
            case NodeKind::INPUT_OBJECT_TYPE_DEFINITION:
457
                return new InputObjectType($config);
458
            default:
459
                throw new Error(sprintf('Type kind of %s not supported.', $def->kind));
460
        }
461
    }
462
463
    /**
464
     * @param TypeNode|ListTypeNode|NonNullTypeNode $typeNode
465
     *
466
     * @return TypeNode
467
     */
468 134
    private function getNamedTypeNode(TypeNode $typeNode)
469
    {
470 134
        $namedType = $typeNode;
471 134
        while ($namedType->kind === NodeKind::LIST_TYPE || $namedType->kind === NodeKind::NON_NULL_TYPE) {
0 ignored issues
show
Bug introduced by
Accessing kind on the interface GraphQL\Language\AST\TypeNode suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
472 21
            $namedType = $namedType->type;
0 ignored issues
show
Bug introduced by
Accessing type on the interface GraphQL\Language\AST\TypeNode suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
473
        }
474
475 134
        return $namedType;
476
    }
477
478
    /**
479
     * @param TypeNode|ListTypeNode|NonNullTypeNode $inputTypeNode
480
     *
481
     * @return Type
482
     */
483 131
    private function buildWrappedType(Type $innerType, TypeNode $inputTypeNode)
484
    {
485 131
        if ($inputTypeNode->kind === NodeKind::LIST_TYPE) {
0 ignored issues
show
Bug introduced by
Accessing kind on the interface GraphQL\Language\AST\TypeNode suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
486 13
            return Type::listOf($this->buildWrappedType($innerType, $inputTypeNode->type));
0 ignored issues
show
Bug introduced by
Accessing type on the interface GraphQL\Language\AST\TypeNode suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
487
        }
488 131
        if ($inputTypeNode->kind === NodeKind::NON_NULL_TYPE) {
489 16
            $wrappedType = $this->buildWrappedType($innerType, $inputTypeNode->type);
490
491 16
            return Type::nonNull(NonNull::assertNullableType($wrappedType));
492
        }
493
494 131
        return $innerType;
495
    }
496
497
    /**
498
     * @return mixed[]
499
     */
500 4
    public function buildInputField(InputValueDefinitionNode $value) : array
501
    {
502 4
        $type = $this->internalBuildWrappedType($value->type);
503
504
        $config = [
505 3
            'name' => $value->name->value,
506 3
            'type' => $type,
507 3
            'description' => $this->getDescription($value),
508 3
            'astNode' => $value,
509
        ];
510
511 3
        if ($value->defaultValue) {
512
            $config['defaultValue'] = $value->defaultValue;
513
        }
514
515 3
        return $config;
516
    }
517
518
    /**
519
     * @return mixed[]
520
     */
521 4
    public function buildEnumValue(EnumValueDefinitionNode $value) : array
522
    {
523
        return [
524 4
            'description' => $this->getDescription($value),
525 4
            'deprecationReason' => $this->getDeprecationReason($value),
526 4
            'astNode' => $value,
527
        ];
528
    }
529
}
530