-
-
Notifications
You must be signed in to change notification settings - Fork 437
/
Copy pathDetectDeprecatedUsage.php
97 lines (85 loc) · 3.16 KB
/
DetectDeprecatedUsage.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?php declare(strict_types=1);
namespace Nuwave\Lighthouse\Deprecation;
use GraphQL\Language\AST\EnumValueNode;
use GraphQL\Language\AST\FieldNode;
use GraphQL\Language\AST\NodeKind;
use GraphQL\Type\Definition\EnumType;
use GraphQL\Type\Definition\EnumValueDefinition;
use GraphQL\Type\Definition\NamedType;
use GraphQL\Validator\DocumentValidator;
use GraphQL\Validator\QueryValidationContext;
use GraphQL\Validator\Rules\ValidationRule;
/**
* @experimental not enabled by default, not guaranteed to be stable
*
* @phpstan-type DeprecationHandler callable(array<string, \Nuwave\Lighthouse\Deprecation\DeprecatedUsage>): void
*/
class DetectDeprecatedUsage extends ValidationRule
{
/**
* @var array<string, \Nuwave\Lighthouse\Deprecation\DeprecatedUsage>
*/
protected array $deprecations = [];
/**
* @var DeprecationHandler
*/
protected $deprecationHandler;
/**
* @param DeprecationHandler $deprecationHandler
*/
public function __construct(callable $deprecationHandler)
{
$this->deprecationHandler = $deprecationHandler;
}
/**
* @param DeprecationHandler $deprecationHandler
*/
public static function handle(callable $deprecationHandler): void
{
DocumentValidator::addRule(new static($deprecationHandler));
}
public function getVisitor(QueryValidationContext $context): array
{
// @phpstan-ignore-next-line NodeVisitor does not know about the mapping between node kind and node type
return [
NodeKind::FIELD => function (FieldNode $_) use ($context): void {
$field = $context->getFieldDef();
if (null === $field) {
return;
}
$deprecationReason = $field->deprecationReason;
if (null !== $deprecationReason) {
$parent = $context->getParentType();
if (! $parent instanceof NamedType) {
return;
}
$this->registerDeprecation("{$parent->name()}.{$field->name}", $deprecationReason);
}
},
NodeKind::ENUM => function (EnumValueNode $node) use ($context): void {
$enum = $context->getInputType();
if (! $enum instanceof EnumType) {
return;
}
$value = $enum->getValue($node->value);
if (! $value instanceof EnumValueDefinition) {
return;
}
$deprecationReason = $value->deprecationReason;
if (null !== $deprecationReason) {
$this->registerDeprecation("{$enum->name}.{$value->name}", $deprecationReason);
}
},
NodeKind::OPERATION_DEFINITION => [
'leave' => function (): void {
($this->deprecationHandler)($this->deprecations);
},
],
];
}
protected function registerDeprecation(string $element, string $reason): void
{
$usage = $this->deprecations[$element] ??= new DeprecatedUsage($reason);
++$usage->count;
}
}