mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-25 06:16:05 +03:00
TASK: Change KnownDirectives rule to match reference
https://github.com/graphql/graphql-js/blob/master/src/validation/rules/KnownDirectives.js
This commit is contained in:
parent
b1cd086177
commit
b65aa4e657
@ -11,6 +11,7 @@ use GraphQL\Language\AST\Node;
|
||||
use GraphQL\Language\AST\NodeKind;
|
||||
use GraphQL\Language\AST\NodeList;
|
||||
use GraphQL\Language\DirectiveLocation;
|
||||
use GraphQL\Type\Definition\Directive;
|
||||
use GraphQL\Validator\ValidationContext;
|
||||
use function count;
|
||||
use function in_array;
|
||||
@ -18,40 +19,51 @@ use function sprintf;
|
||||
|
||||
class KnownDirectives extends ValidationRule
|
||||
{
|
||||
/**
|
||||
* @param ValidationContext $context
|
||||
* @return array
|
||||
*/
|
||||
public function getVisitor(ValidationContext $context)
|
||||
{
|
||||
return [
|
||||
NodeKind::DIRECTIVE => function (DirectiveNode $node, $key, $parent, $path, $ancestors) use ($context) {
|
||||
$directiveDef = null;
|
||||
foreach ($context->getSchema()->getDirectives() as $def) {
|
||||
if ($def->name === $node->name->value) {
|
||||
$directiveDef = $def;
|
||||
break;
|
||||
}
|
||||
$locationsMap = [];
|
||||
$schema = $context->getSchema();
|
||||
|
||||
$definedDirectives = $schema ? $schema->getDirectives() : Directive::getInternalDirectives();
|
||||
|
||||
foreach ($definedDirectives as $directive) {
|
||||
$locationsMap[$directive->name] = $directive->locations;
|
||||
}
|
||||
|
||||
if (! $directiveDef) {
|
||||
$astDefinition = $context->getDocument()->definitions;
|
||||
foreach ($astDefinition as $def) {
|
||||
if ($def->kind === NodeKind::DIRECTIVE_DEFINITION) {
|
||||
$locationsMap[$def->name->value] = array_map(function ($name) {
|
||||
return $name->value;
|
||||
}, $def->locations);
|
||||
}
|
||||
}
|
||||
return [
|
||||
NodeKind::DIRECTIVE => function (DirectiveNode $node, $key, $parent, $path, $ancestors) use ($context, $locationsMap) {
|
||||
$name = $node->name->value;
|
||||
$locations = $locationsMap[$name] ?? null;
|
||||
|
||||
if (!$locations) {
|
||||
$context->reportError(new Error(
|
||||
self::unknownDirectiveMessage($node->name->value),
|
||||
self::unknownDirectiveMessage($name),
|
||||
[$node]
|
||||
));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$candidateLocation = $this->getDirectiveLocationForASTPath($ancestors);
|
||||
|
||||
if (! $candidateLocation) {
|
||||
if ($candidateLocation && !in_array($candidateLocation, $locations)) {
|
||||
$context->reportError(new Error(
|
||||
self::misplacedDirectiveMessage($node->name->value, $node->type),
|
||||
[$node]
|
||||
));
|
||||
} elseif (! in_array($candidateLocation, $directiveDef->locations)) {
|
||||
$context->reportError(new Error(
|
||||
self::misplacedDirectiveMessage($node->name->value, $candidateLocation),
|
||||
self::misplacedDirectiveMessage($name, $candidateLocation),
|
||||
[$node]
|
||||
));
|
||||
}
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@ -88,6 +100,7 @@ class KnownDirectives extends ValidationRule
|
||||
case NodeKind::FRAGMENT_DEFINITION:
|
||||
return DirectiveLocation::FRAGMENT_DEFINITION;
|
||||
case NodeKind::SCHEMA_DEFINITION:
|
||||
case NodeKind::SCHEMA_EXTENSION:
|
||||
return DirectiveLocation::SCHEMA;
|
||||
case NodeKind::SCALAR_TYPE_DEFINITION:
|
||||
case NodeKind::SCALAR_TYPE_EXTENSION:
|
||||
|
Loading…
Reference in New Issue
Block a user