Completed
Pull Request — master (#206)
by Christoffer
02:31
created

newField()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 20
nc 1
nop 1
dl 0
loc 24
rs 8.9713
c 0
b 0
f 0
1
<?php
2
3
namespace Digia\GraphQL\Type;
4
5
use Digia\GraphQL\Error\InvalidTypeException;
6
use Digia\GraphQL\Error\InvariantException;
7
use Digia\GraphQL\Schema\Schema;
8
use Digia\GraphQL\Type\Definition\AbstractTypeInterface;
9
use Digia\GraphQL\Type\Definition\Argument;
10
use Digia\GraphQL\Type\Definition\CompositeTypeInterface;
11
use Digia\GraphQL\Type\Definition\Directive;
12
use Digia\GraphQL\Type\Definition\EnumType;
13
use Digia\GraphQL\Type\Definition\EnumValue;
14
use Digia\GraphQL\Type\Definition\Field;
15
use Digia\GraphQL\Type\Definition\InputField;
16
use Digia\GraphQL\Type\Definition\InputObjectType;
17
use Digia\GraphQL\Type\Definition\InputTypeInterface;
18
use Digia\GraphQL\Type\Definition\InterfaceType;
19
use Digia\GraphQL\Type\Definition\LeafTypeInterface;
20
use Digia\GraphQL\Type\Definition\ListType;
21
use Digia\GraphQL\Type\Definition\NamedTypeInterface;
22
use Digia\GraphQL\Type\Definition\NonNullType;
23
use Digia\GraphQL\Type\Definition\ObjectType;
24
use Digia\GraphQL\Type\Definition\OutputTypeInterface;
25
use Digia\GraphQL\Type\Definition\ScalarType;
26
use Digia\GraphQL\Type\Definition\TypeInterface;
27
use Digia\GraphQL\Type\Definition\UnionType;
28
use Digia\GraphQL\Type\Definition\WrappingTypeInterface;
29
use function Digia\GraphQL\Util\invariant;
30
31
/**
32
 * @param $thunk
33
 * @return null|array
34
 */
35
function resolveThunk($thunk): ?array
36
{
37
    return \is_callable($thunk) ? $thunk() : $thunk;
38
}
39
40
/**
41
 * @param mixed $value
42
 * @return bool
43
 */
44
function isAssocArray($value): bool
45
{
46
    if (!\is_array($value)) {
47
        return false;
48
    }
49
    if (empty($value)) {
50
        return true;
51
    }
52
    $keys = \array_keys($value);
53
    return $keys !== \array_keys($keys);
54
}
55
56
/**
57
 * @param $type
58
 * @throws InvariantException
59
 */
60
function assertType($type)
61
{
62
    invariant(
63
        $type instanceof TypeInterface,
64
        \sprintf('Expected %s to be a GraphQL type.', (string)$type)
65
    );
66
}
67
68
/**
69
 * @param TypeInterface $type
70
 * @throws InvariantException
71
 */
72
function assertScalarType(TypeInterface $type)
73
{
74
    invariant(
75
        $type instanceof ScalarType,
76
        \sprintf('Expected %s to be a GraphQL Scalar type.', (string)$type)
77
    );
78
}
79
80
/**
81
 * @param TypeInterface $type
82
 * @throws InvariantException
83
 */
84
function assertObjectType(TypeInterface $type)
85
{
86
    invariant(
87
        $type instanceof ObjectType,
88
        \sprintf('Expected %s to be a GraphQL Object type.', (string)$type)
89
    );
90
}
91
92
/**
93
 * @param TypeInterface $type
94
 * @throws InvariantException
95
 */
96
function assertInterfaceType(TypeInterface $type)
97
{
98
    invariant(
99
        $type instanceof InterfaceType,
100
        \sprintf('Expected %s to be a GraphQL Interface type.', (string)$type)
101
    );
102
}
103
104
/**
105
 * @param TypeInterface $type
106
 * @throws InvariantException
107
 */
108
function assertUnionType(TypeInterface $type)
109
{
110
    invariant(
111
        $type instanceof UnionType,
112
        \sprintf('Expected %s to be a GraphQL Union type.', (string)$type)
113
    );
114
}
115
116
/**
117
 * @param TypeInterface $type
118
 * @throws InvariantException
119
 */
120
function assertEnumType(TypeInterface $type)
121
{
122
    invariant(
123
        $type instanceof EnumType,
124
        \sprintf('Expected %s to be a GraphQL Enum type.', (string)$type)
125
    );
126
}
127
128
/**
129
 * @param TypeInterface $type
130
 * @throws InvariantException
131
 */
132
function assertInputObjectType(TypeInterface $type)
133
{
134
    invariant(
135
        $type instanceof InputObjectType,
136
        \sprintf('Expected %s to be a GraphQL InputObject type.', (string)$type)
137
    );
138
}
139
140
/**
141
 * @param TypeInterface $type
142
 * @throws InvariantException
143
 */
144
function assertListType(TypeInterface $type)
145
{
146
    invariant(
147
        $type instanceof ListType,
148
        \sprintf('Expected %s to be a GraphQL List type.', (string)$type)
149
    );
150
}
151
152
/**
153
 * @param TypeInterface $type
154
 * @throws InvariantException
155
 */
156
function assertNonNullType(TypeInterface $type)
157
{
158
    invariant(
159
        $type instanceof NonNullType,
160
        \sprintf('Expected %s to be a GraphQL NonNull type.', (string)$type)
161
    );
162
}
163
164
/**
165
 * Whether a type is an input type cannot be determined with `instanceof`
166
 * because lists and non-nulls can also be output types if the wrapped type is an output type.
167
 *
168
 * @param TypeInterface|null $type
169
 * @return bool
170
 */
171
function isInputType(?TypeInterface $type): bool
172
{
173
    return null !== $type && ($type instanceof InputTypeInterface || ($type instanceof WrappingTypeInterface && isInputType($type->getOfType())));
174
}
175
176
/**
177
 * @param TypeInterface $type
178
 * @throws InvariantException
179
 */
180
function assertInputType(TypeInterface $type)
181
{
182
    invariant(
183
        isInputType($type),
184
        \sprintf('Expected %s to be a GraphQL input type.', (string)$type)
185
    );
186
}
187
188
/**
189
 * Whether a type is an output type cannot be determined with `instanceof`
190
 * because lists and non-nulls can also be output types if the wrapped type is an output type.
191
 *
192
 * @param TypeInterface|null $type
193
 * @return bool
194
 */
195
function isOutputType(?TypeInterface $type): bool
196
{
197
    return null !== $type && ($type instanceof OutputTypeInterface || ($type instanceof WrappingTypeInterface && isOutputType($type->getOfType())));
198
}
199
200
/**
201
 * @param TypeInterface $type
202
 * @throws InvariantException
203
 */
204
function assertOutputType(TypeInterface $type)
205
{
206
    invariant(
207
        isOutputType($type),
208
        \sprintf('Expected %s to be a GraphQL output type.', (string)$type)
209
    );
210
}
211
212
/**
213
 * @param TypeInterface $type
214
 * @throws InvariantException
215
 */
216
function assertLeafType(TypeInterface $type)
217
{
218
    invariant(
219
        $type instanceof LeafTypeInterface,
220
        \sprintf('Expected %s to be a GraphQL leaf type.', (string)$type)
221
    );
222
}
223
224
/**
225
 * @param TypeInterface $type
226
 * @throws InvariantException
227
 */
228
function assertCompositeType(TypeInterface $type)
229
{
230
    invariant(
231
        $type instanceof CompositeTypeInterface,
232
        \sprintf('Expected %s to be a GraphQL composite type.', (string)$type)
233
    );
234
}
235
236
/**
237
 * @param TypeInterface $type
238
 * @throws InvariantException
239
 */
240
function assertAbstractType(TypeInterface $type)
241
{
242
    invariant(
243
        $type instanceof AbstractTypeInterface,
244
        \sprintf('Expected %s to be a GraphQL abstract type.', (string)$type)
245
    );
246
}
247
248
/**
249
 * @param TypeInterface $type
250
 * @throws InvariantException
251
 */
252
function assertWrappingType(TypeInterface $type)
253
{
254
    invariant(
255
        $type instanceof WrappingTypeInterface,
256
        \sprintf('Expected %s to be a GraphQL wrapping type.', (string)$type)
257
    );
258
}
259
260
/**
261
 * @param TypeInterface $type
262
 * @return bool
263
 */
264
function isNullableType(TypeInterface $type): bool
265
{
266
    return !($type instanceof NonNullType);
267
}
268
269
/**
270
 * @param TypeInterface $type
271
 * @return TypeInterface
272
 * @throws InvariantException
273
 */
274
function assertNullableType(TypeInterface $type): TypeInterface
275
{
276
    invariant(
277
        isNullableType($type),
278
        \sprintf('Expected %s to be a GraphQL nullable type.', (string)$type)
279
    );
280
281
    return $type;
282
}
283
284
/**
285
 * @param TypeInterface|null $type
286
 * @return TypeInterface|null
287
 */
288
function getNullableType(?TypeInterface $type): ?TypeInterface
289
{
290
    if (null === $type) {
291
        return null;
292
    }
293
294
    return $type instanceof NonNullType ? $type->getOfType() : $type;
295
}
296
297
/**
298
 * @param TypeInterface $type
299
 * @throws InvariantException
300
 */
301
function assertNamedType(TypeInterface $type)
302
{
303
    invariant(
304
        $type instanceof NamedTypeInterface,
305
        \sprintf('Expected %s to be a GraphQL named type.', (string)$type)
306
    );
307
}
308
309
/**
310
 * @param TypeInterface|null $type
311
 * @return NamedTypeInterface|null
312
 */
313
function getNamedType(?TypeInterface $type): ?NamedTypeInterface
314
{
315
    if (!$type) {
316
        return null;
317
    }
318
319
    $unwrappedType = $type;
320
321
    while ($unwrappedType instanceof WrappingTypeInterface) {
322
        $unwrappedType = $unwrappedType->getOfType();
323
    }
324
325
    return $unwrappedType;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $unwrappedType returns the type Digia\GraphQL\Type\Definition\TypeInterface which is incompatible with the type-hinted return null|Digia\GraphQL\Type\...tion\NamedTypeInterface.
Loading history...
326
}
327
328
/**
329
 * @param array $config
330
 * @return ScalarType
331
 * @throws InvariantException
332
 */
333
function newScalarType(array $config = []): ScalarType
334
{
335
    [
336
        'name'         => $name,
337
        'description'  => $description,
338
        'serialize'    => $serialize,
339
        'parseValue'   => $parseValue,
340
        'parseLiteral' => $parseLiteral,
341
        'astNode'      => $astNode,
342
    ] = $config;
343
344
    return new ScalarType($name, $description, $serialize, $parseValue, $parseLiteral, $astNode);
345
}
346
347
/**
348
 * @param array $config
349
 * @return EnumType
350
 * @throws InvariantException
351
 */
352
function newEnumType(array $config = []): EnumType
353
{
354
    [
355
        'name'        => $name,
356
        'description' => $description,
357
        'values'      => $rawValues,
358
        'astNode'     => $astNode,
359
    ] = $config;
360
361
    return new EnumType($name, $description, $rawValues ?? [], $astNode);
362
}
363
364
/**
365
 * @param array $config
366
 * @return EnumValue
367
 */
368
function newEnumValue(array $config = []): EnumValue
369
{
370
    [
371
        'name'              => $name,
372
        'description'       => $description,
373
        'deprecationReason' => $deprecationReason,
374
        'astNode'           => $astNode,
375
        'value'             => $value,
376
    ] = $config;
377
378
    return new EnumValue($name, $description, $deprecationReason, $astNode, $value);
379
}
380
381
/**
382
 * @param array $config
383
 * @return InputObjectType
384
 * @throws InvariantException
385
 */
386
function newInputObjectType(array $config = []): InputObjectType
387
{
388
    [
389
        'name'        => $name,
390
        'description' => $description,
391
        'fields'      => $rawFieldsOrThunk,
392
        'astNode'     => $astNode,
393
    ] = $config;
394
395
    return new InputObjectType($name, $description, $rawFieldsOrThunk ?? [], $astNode);
396
}
397
398
/**
399
 * @param array $config
400
 * @return InputField
401
 */
402
function newInputField(array $config = []): InputField
403
{
404
    [
405
        'name'         => $name,
406
        'description'  => $description,
407
        'type'         => $type,
408
        'defaultValue' => $defaultValue,
409
        'astNode'      => $astNode,
410
    ] = $config;
411
412
    return new InputField($name, $description, $type, $defaultValue, $astNode);
413
}
414
415
/**
416
 * @param array $config
417
 * @return InterfaceType
418
 * @throws InvariantException
419
 */
420
function newInterfaceType(array $config = []): InterfaceType
421
{
422
423
    [
424
        'name'              => $name,
425
        'description'       => $description,
426
        'fields'            => $rawFieldsOrThunk,
427
        'resolveType'       => $resolveTypeCallback,
428
        'astNode'           => $astNode,
429
        'extensionASTNodes' => $extensionASTNodes,
430
    ] = $config;
431
432
    return new InterfaceType(
433
        $name,
434
        $description,
435
        $rawFieldsOrThunk ?? [],
436
        $resolveTypeCallback,
437
        $astNode,
438
        $extensionASTNodes ?? []
439
    );
440
}
441
442
/**
443
 * @param array $config
444
 * @return ObjectType
445
 * @throws InvariantException
446
 */
447
function newObjectType(array $config = []): ObjectType
448
{
449
    [
450
        'name'              => $name,
451
        'description'       => $description,
452
        'fields'            => $rawFieldsOrThunk,
453
        'interfaces'        => $interfacesOrThunk,
454
        'isTypeOf'          => $isTypeOfCallback,
455
        'astNode'           => $astNode,
456
        'extensionASTNodes' => $extensionASTNodes,
457
    ] = $config;
458
459
    return new ObjectType(
460
        $name,
461
        $description,
462
        $rawFieldsOrThunk ?? [],
463
        $interfacesOrThunk ?? [],
464
        $isTypeOfCallback,
465
        $astNode,
466
        $extensionASTNodes ?? []
467
    );
468
}
469
470
/**
471
 * @param array $config
472
 * @return Field
473
 * @throws InvariantException
474
 */
475
function newField(array $config = []): Field
476
{
477
    [
478
        'name'              => $name,
479
        'description'       => $description,
480
        'type'              => $type,
481
        'args'              => $rawArguments,
482
        'resolve'           => $resolveCallback,
483
        'subscribe'         => $subscribeCallback,
484
        'deprecationReason' => $deprecationReason,
485
        'astNode'           => $astNode,
486
        'typeName'          => $typeName,
487
    ] = $config;
488
489
    return new Field(
490
        $name,
491
        $description,
492
        $type,
493
        $rawArguments ?? [],
494
        $resolveCallback,
495
        $subscribeCallback,
496
        $deprecationReason,
497
        $astNode,
498
        $typeName ?? '' // Type name is only unset for inspection meta fields
499
    );
500
}
501
502
function newArgument(array $config = []): Argument
503
{
504
    [
505
        'name'         => $name,
506
        'description'  => $description,
507
        'type'         => $type,
508
        'defaultValue' => $defaultValue,
509
        'astNode'      => $astNode,
510
    ] = $config;
511
512
    return new Argument($name, $description, $type, $defaultValue, $astNode);
513
}
514
515
/**
516
 * @param array $config
517
 * @return UnionType
518
 * @throws InvariantException
519
 */
520
function newUnionType(array $config = []): UnionType
521
{
522
    [
523
        'name'        => $name,
524
        'description' => $description,
525
        'types'       => $rawTypesOrThunk,
526
        'resolveType' => $resolveTypeCallback,
527
        'astNode'     => $astNode,
528
    ] = $config;
529
530
    return new UnionType($name, $description, $rawTypesOrThunk ?? [], $resolveTypeCallback, $astNode);
531
}
532
533
/**
534
 * @param array $config
535
 * @return Schema
536
 * @throws InvariantException
537
 */
538
function newSchema(array $config = []): Schema
539
{
540
    [
541
        'query'        => $queryType,
542
        'mutation'     => $mutationType,
543
        'subscription' => $subscriptionType,
544
        'types'        => $types,
545
        'directives'   => $directives,
546
        'assumeValid'  => $assumeValid,
547
        'astNode'      => $astNode,
548
    ] = $config;
549
550
    return new Schema(
551
        $queryType,
552
        $mutationType,
553
        $subscriptionType,
554
        $types ?? [],
555
        $directives ?? [],
556
        $assumeValid ?? false,
557
        $astNode
558
    );
559
}
560
561
/**
562
 * @param array $config
563
 * @return Directive
564
 * @throws InvariantException
565
 */
566
function newDirective(array $config = []): Directive
567
{
568
    [
569
        'name'        => $name,
570
        'description' => $description,
571
        'locations'   => $locations,
572
        'args'        => $rawArguments,
573
        'astNode'     => $astNode,
574
        'typeName'    => $typeName
575
    ] = $config;
576
577
    return new Directive($name, $description, $locations ?? [], $rawArguments ?? [], $astNode, $typeName ?? '');
578
}
579
580
/**
581
 * @param TypeInterface $ofType
582
 * @return ListType
583
 */
584
function newList(TypeInterface $ofType): ListType
585
{
586
    return new ListType($ofType);
587
}
588
589
/**
590
 * @param TypeInterface $ofType
591
 * @return NonNullType
592
 * @throws InvalidTypeException
593
 */
594
function newNonNull(TypeInterface $ofType): NonNullType
595
{
596
    return new NonNullType($ofType);
597
}
598