Version 4.6.0
This commit is contained in:
1 parent
f79dcf067a
commit
517a5e1f70
2036 files changed
+110041
-26162
No files matched your search
+128
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Validator\Rules;
|
||||
|
||||
use GraphQL\Error\Error;
|
||||
use GraphQL\Language\AST\ArgumentNode;
|
||||
use GraphQL\Language\AST\DirectiveDefinitionNode;
|
||||
use GraphQL\Language\AST\DirectiveNode;
|
||||
use GraphQL\Language\AST\InputValueDefinitionNode;
|
||||
use GraphQL\Language\AST\NodeKind;
|
||||
use GraphQL\Language\AST\NonNullTypeNode;
|
||||
use GraphQL\Language\Printer;
|
||||
use GraphQL\Type\Definition\Directive;
|
||||
use GraphQL\Type\Definition\FieldArgument;
|
||||
use GraphQL\Utils\Utils;
|
||||
use GraphQL\Validator\ASTValidationContext;
|
||||
use GraphQL\Validator\SDLValidationContext;
|
||||
use GraphQL\Validator\ValidationContext;
|
||||
use function array_filter;
|
||||
|
||||
/**
|
||||
* Provided required arguments on directives
|
||||
*
|
||||
* A directive is only valid if all required (non-null without a
|
||||
* default value) field arguments have been provided.
|
||||
*/
|
||||
class ProvidedRequiredArgumentsOnDirectives extends ValidationRule
|
||||
{
|
||||
public static function missingDirectiveArgMessage(string $directiveName, string $argName, string $type)
|
||||
{
|
||||
return 'Directive "@' . $directiveName . '" argument "' . $argName
|
||||
. '" of type "' . $type . '" is required but not provided.';
|
||||
}
|
||||
|
||||
public function getSDLVisitor(SDLValidationContext $context)
|
||||
{
|
||||
return $this->getASTVisitor($context);
|
||||
}
|
||||
|
||||
public function getVisitor(ValidationContext $context)
|
||||
{
|
||||
return $this->getASTVisitor($context);
|
||||
}
|
||||
|
||||
public function getASTVisitor(ASTValidationContext $context)
|
||||
{
|
||||
$requiredArgsMap = [];
|
||||
$schema = $context->getSchema();
|
||||
$definedDirectives = $schema
|
||||
? $schema->getDirectives()
|
||||
: Directive::getInternalDirectives();
|
||||
|
||||
foreach ($definedDirectives as $directive) {
|
||||
$requiredArgsMap[$directive->name] = Utils::keyMap(
|
||||
array_filter($directive->args, static function (FieldArgument $arg) : bool {
|
||||
return $arg->isRequired();
|
||||
}),
|
||||
static function (FieldArgument $arg) : string {
|
||||
return $arg->name;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$astDefinition = $context->getDocument()->definitions;
|
||||
foreach ($astDefinition as $def) {
|
||||
if (! ($def instanceof DirectiveDefinitionNode)) {
|
||||
continue;
|
||||
}
|
||||
$arguments = $def->arguments ?? [];
|
||||
|
||||
$requiredArgsMap[$def->name->value] = Utils::keyMap(
|
||||
Utils::filter($arguments, static function (InputValueDefinitionNode $argument) : bool {
|
||||
return $argument->type instanceof NonNullTypeNode &&
|
||||
(
|
||||
! isset($argument->defaultValue) ||
|
||||
$argument->defaultValue === null
|
||||
);
|
||||
}),
|
||||
static function (InputValueDefinitionNode $argument) : string {
|
||||
return $argument->name->value;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return [
|
||||
NodeKind::DIRECTIVE => [
|
||||
// Validate on leave to allow for deeper errors to appear first.
|
||||
'leave' => static function (DirectiveNode $directiveNode) use ($requiredArgsMap, $context) : ?string {
|
||||
$directiveName = $directiveNode->name->value;
|
||||
$requiredArgs = $requiredArgsMap[$directiveName] ?? null;
|
||||
if (! $requiredArgs) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$argNodes = $directiveNode->arguments ?? [];
|
||||
$argNodeMap = Utils::keyMap(
|
||||
$argNodes,
|
||||
static function (ArgumentNode $arg) : string {
|
||||
return $arg->name->value;
|
||||
}
|
||||
);
|
||||
|
||||
foreach ($requiredArgs as $argName => $arg) {
|
||||
if (isset($argNodeMap[$argName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($arg instanceof FieldArgument) {
|
||||
$argType = (string) $arg->getType();
|
||||
} elseif ($arg instanceof InputValueDefinitionNode) {
|
||||
$argType = Printer::doPrint($arg->type);
|
||||
} else {
|
||||
$argType = '';
|
||||
}
|
||||
|
||||
$context->reportError(
|
||||
new Error(static::missingDirectiveArgMessage($directiveName, $argName, $argType), [$directiveNode])
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user