mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-22 12:56:05 +03:00
Abstract base class for validation rules
This commit is contained in:
parent
9499e5ae8e
commit
203fddfe4e
43
UPGRADE.md
43
UPGRADE.md
@ -43,6 +43,49 @@ But note that this is deprecated format and will be removed in future versions.
|
|||||||
In general, if new default formatting doesn't work for you - just set [your own error
|
In general, if new default formatting doesn't work for you - just set [your own error
|
||||||
formatter](http://webonyx.github.io/graphql-php/error-handling/#custom-error-handling-and-formatting).
|
formatter](http://webonyx.github.io/graphql-php/error-handling/#custom-error-handling-and-formatting).
|
||||||
|
|
||||||
|
### Breaking: Validation rules now have abstract base class
|
||||||
|
Previously any callable was accepted by DocumentValidator as validation rule. Now only instances of
|
||||||
|
`GraphQL\Validator\Rules\AbstractValidationRule` are allowed.
|
||||||
|
|
||||||
|
If you were using custom validation rules, just wrap them with
|
||||||
|
`GraphQL\Validator\Rules\CustomValidationRule` (created for backwards compatibility).
|
||||||
|
|
||||||
|
Before:
|
||||||
|
```php
|
||||||
|
use GraphQL\Validator\DocumentValidator;
|
||||||
|
|
||||||
|
$myRule = function(ValidationContext $context) {};
|
||||||
|
DocumentValidator::validate($schema, $ast, [$myRule]);
|
||||||
|
```
|
||||||
|
|
||||||
|
After:
|
||||||
|
```php
|
||||||
|
use GraphQL\Validator\Rules\CustomValidationRule;
|
||||||
|
use GraphQL\Validator\DocumentValidator;
|
||||||
|
|
||||||
|
$myRule = new CustomValidationRule('MyRule', function(ValidationContext $context) {});
|
||||||
|
DocumentValidator::validate($schema, $ast, [$myRule]);
|
||||||
|
```
|
||||||
|
|
||||||
|
Also `DocumentValidator::addRule()` signature changed.
|
||||||
|
|
||||||
|
Before the change:
|
||||||
|
```php
|
||||||
|
use GraphQL\Validator\DocumentValidator;
|
||||||
|
|
||||||
|
$myRule = function(ValidationContext $context) {};
|
||||||
|
DocumentValidator::addRule('MyRuleName', $myRule);
|
||||||
|
```
|
||||||
|
|
||||||
|
After the change:
|
||||||
|
```php
|
||||||
|
use GraphQL\Validator\DocumentValidator;
|
||||||
|
|
||||||
|
$myRule = new CustomValidationRulefunction('MyRule', ValidationContext $context) {});
|
||||||
|
DocumentValidator::addRule($myRule);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### Breaking: AST now uses `NodeList` vs array for lists of nodes
|
### Breaking: AST now uses `NodeList` vs array for lists of nodes
|
||||||
It helps us unserialize AST from array lazily. This change affects you only if you use `array_`
|
It helps us unserialize AST from array lazily. This change affects you only if you use `array_`
|
||||||
functions with AST or mutate AST directly.
|
functions with AST or mutate AST directly.
|
||||||
|
@ -113,9 +113,18 @@ class GraphQL
|
|||||||
$documentNode = Parser::parse(new Source($source ?: '', 'GraphQL'));
|
$documentNode = Parser::parse(new Source($source ?: '', 'GraphQL'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var QueryComplexity $queryComplexity */
|
// FIXME
|
||||||
$queryComplexity = DocumentValidator::getRule('QueryComplexity');
|
if (!empty($validationRules)) {
|
||||||
$queryComplexity->setRawVariableValues($variableValues);
|
foreach ($validationRules as $rule) {
|
||||||
|
if ($rule instanceof QueryComplexity) {
|
||||||
|
$rule->setRawVariableValues($variableValues);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/** @var QueryComplexity $queryComplexity */
|
||||||
|
$queryComplexity = DocumentValidator::getRule(QueryComplexity::class);
|
||||||
|
$queryComplexity->setRawVariableValues($variableValues);
|
||||||
|
}
|
||||||
|
|
||||||
$validationErrors = DocumentValidator::validate($schema, $documentNode, $validationRules);
|
$validationErrors = DocumentValidator::validate($schema, $documentNode, $validationRules);
|
||||||
|
|
||||||
@ -223,7 +232,7 @@ class GraphQL
|
|||||||
*
|
*
|
||||||
* @return Directive[]
|
* @return Directive[]
|
||||||
*/
|
*/
|
||||||
public static function getInternalDirectives()
|
public static function getStandardDirectives()
|
||||||
{
|
{
|
||||||
return array_values(Directive::getInternalDirectives());
|
return array_values(Directive::getInternalDirectives());
|
||||||
}
|
}
|
||||||
@ -233,9 +242,17 @@ class GraphQL
|
|||||||
*
|
*
|
||||||
* @return Type[]
|
* @return Type[]
|
||||||
*/
|
*/
|
||||||
public static function getInternalTypes()
|
public static function getStandardTypes()
|
||||||
{
|
{
|
||||||
return Type::getInternalTypes();
|
return array_values(Type::getInternalTypes());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getStandardValidationRules()
|
||||||
|
{
|
||||||
|
return array_values(DocumentValidator::defaultRules());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -253,4 +270,15 @@ class GraphQL
|
|||||||
{
|
{
|
||||||
Executor::setPromiseAdapter($promiseAdapter);
|
Executor::setPromiseAdapter($promiseAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns directives defined in GraphQL spec
|
||||||
|
*
|
||||||
|
* @deprecated Renamed to getStandardDirectives
|
||||||
|
* @return Directive[]
|
||||||
|
*/
|
||||||
|
public static function getInternalDirectives()
|
||||||
|
{
|
||||||
|
return self::getStandardDirectives();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ use GraphQL\Type\Definition\NonNull;
|
|||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
use GraphQL\Utils\TypeInfo;
|
use GraphQL\Utils\TypeInfo;
|
||||||
|
use GraphQL\Validator\Rules\AbstractValidationRule;
|
||||||
use GraphQL\Validator\Rules\ArgumentsOfCorrectType;
|
use GraphQL\Validator\Rules\ArgumentsOfCorrectType;
|
||||||
use GraphQL\Validator\Rules\DefaultValuesOfCorrectType;
|
use GraphQL\Validator\Rules\DefaultValuesOfCorrectType;
|
||||||
use GraphQL\Validator\Rules\DisableIntrospection;
|
use GraphQL\Validator\Rules\DisableIntrospection;
|
||||||
@ -53,6 +54,8 @@ class DocumentValidator
|
|||||||
|
|
||||||
private static $defaultRules;
|
private static $defaultRules;
|
||||||
|
|
||||||
|
private static $securityRules;
|
||||||
|
|
||||||
private static $initRules = false;
|
private static $initRules = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,8 +66,8 @@ class DocumentValidator
|
|||||||
public static function allRules()
|
public static function allRules()
|
||||||
{
|
{
|
||||||
if (!self::$initRules) {
|
if (!self::$initRules) {
|
||||||
self::$rules = array_merge(static::defaultRules(), self::$rules);
|
static::$rules = array_merge(static::defaultRules(), self::securityRules(), self::$rules);
|
||||||
self::$initRules = true;
|
static::$initRules = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$rules;
|
return self::$rules;
|
||||||
@ -74,64 +77,82 @@ class DocumentValidator
|
|||||||
{
|
{
|
||||||
if (null === self::$defaultRules) {
|
if (null === self::$defaultRules) {
|
||||||
self::$defaultRules = [
|
self::$defaultRules = [
|
||||||
'UniqueOperationNames' => new UniqueOperationNames(),
|
UniqueOperationNames::class => new UniqueOperationNames(),
|
||||||
'LoneAnonymousOperation' => new LoneAnonymousOperation(),
|
LoneAnonymousOperation::class => new LoneAnonymousOperation(),
|
||||||
'KnownTypeNames' => new KnownTypeNames(),
|
KnownTypeNames::class => new KnownTypeNames(),
|
||||||
'FragmentsOnCompositeTypes' => new FragmentsOnCompositeTypes(),
|
FragmentsOnCompositeTypes::class => new FragmentsOnCompositeTypes(),
|
||||||
'VariablesAreInputTypes' => new VariablesAreInputTypes(),
|
VariablesAreInputTypes::class => new VariablesAreInputTypes(),
|
||||||
'ScalarLeafs' => new ScalarLeafs(),
|
ScalarLeafs::class => new ScalarLeafs(),
|
||||||
'FieldsOnCorrectType' => new FieldsOnCorrectType(),
|
FieldsOnCorrectType::class => new FieldsOnCorrectType(),
|
||||||
'UniqueFragmentNames' => new UniqueFragmentNames(),
|
UniqueFragmentNames::class => new UniqueFragmentNames(),
|
||||||
'KnownFragmentNames' => new KnownFragmentNames(),
|
KnownFragmentNames::class => new KnownFragmentNames(),
|
||||||
'NoUnusedFragments' => new NoUnusedFragments(),
|
NoUnusedFragments::class => new NoUnusedFragments(),
|
||||||
'PossibleFragmentSpreads' => new PossibleFragmentSpreads(),
|
PossibleFragmentSpreads::class => new PossibleFragmentSpreads(),
|
||||||
'NoFragmentCycles' => new NoFragmentCycles(),
|
NoFragmentCycles::class => new NoFragmentCycles(),
|
||||||
'UniqueVariableNames' => new UniqueVariableNames(),
|
UniqueVariableNames::class => new UniqueVariableNames(),
|
||||||
'NoUndefinedVariables' => new NoUndefinedVariables(),
|
NoUndefinedVariables::class => new NoUndefinedVariables(),
|
||||||
'NoUnusedVariables' => new NoUnusedVariables(),
|
NoUnusedVariables::class => new NoUnusedVariables(),
|
||||||
'KnownDirectives' => new KnownDirectives(),
|
KnownDirectives::class => new KnownDirectives(),
|
||||||
'UniqueDirectivesPerLocation' => new UniqueDirectivesPerLocation(),
|
UniqueDirectivesPerLocation::class => new UniqueDirectivesPerLocation(),
|
||||||
'KnownArgumentNames' => new KnownArgumentNames(),
|
KnownArgumentNames::class => new KnownArgumentNames(),
|
||||||
'UniqueArgumentNames' => new UniqueArgumentNames(),
|
UniqueArgumentNames::class => new UniqueArgumentNames(),
|
||||||
'ArgumentsOfCorrectType' => new ArgumentsOfCorrectType(),
|
ArgumentsOfCorrectType::class => new ArgumentsOfCorrectType(),
|
||||||
'ProvidedNonNullArguments' => new ProvidedNonNullArguments(),
|
ProvidedNonNullArguments::class => new ProvidedNonNullArguments(),
|
||||||
'DefaultValuesOfCorrectType' => new DefaultValuesOfCorrectType(),
|
DefaultValuesOfCorrectType::class => new DefaultValuesOfCorrectType(),
|
||||||
'VariablesInAllowedPosition' => new VariablesInAllowedPosition(),
|
VariablesInAllowedPosition::class => new VariablesInAllowedPosition(),
|
||||||
'OverlappingFieldsCanBeMerged' => new OverlappingFieldsCanBeMerged(),
|
OverlappingFieldsCanBeMerged::class => new OverlappingFieldsCanBeMerged(),
|
||||||
'UniqueInputFieldNames' => new UniqueInputFieldNames(),
|
UniqueInputFieldNames::class => new UniqueInputFieldNames(),
|
||||||
|
|
||||||
// Query Security
|
|
||||||
'DisableIntrospection' => new DisableIntrospection(DisableIntrospection::DISABLED), // DEFAULT DISABLED
|
|
||||||
'QueryDepth' => new QueryDepth(QueryDepth::DISABLED), // default disabled
|
|
||||||
'QueryComplexity' => new QueryComplexity(QueryComplexity::DISABLED), // default disabled
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$defaultRules;
|
return self::$defaultRules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function securityRules()
|
||||||
|
{
|
||||||
|
// This way of defining rules is deprecated
|
||||||
|
// When custom security rule is required - it should be just added via DocumentValidator::addRule();
|
||||||
|
// TODO: deprecate this
|
||||||
|
|
||||||
|
if (null === self::$securityRules) {
|
||||||
|
self::$securityRules = [
|
||||||
|
DisableIntrospection::class => new DisableIntrospection(DisableIntrospection::DISABLED), // DEFAULT DISABLED
|
||||||
|
QueryDepth::class => new QueryDepth(QueryDepth::DISABLED), // default disabled
|
||||||
|
QueryComplexity::class => new QueryComplexity(QueryComplexity::DISABLED), // default disabled
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return self::$securityRules;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns validation rule
|
* Returns validation rule
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @return callable|null
|
* @return AbstractValidationRule
|
||||||
*/
|
*/
|
||||||
public static function getRule($name)
|
public static function getRule($name)
|
||||||
{
|
{
|
||||||
$rules = static::allRules();
|
$rules = static::allRules();
|
||||||
|
|
||||||
|
if (isset($rules[$name])) {
|
||||||
|
return $rules[$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = "GraphQL\\Validator\\Rules\\$name";
|
||||||
return isset($rules[$name]) ? $rules[$name] : null ;
|
return isset($rules[$name]) ? $rules[$name] : null ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add rule to list of default validation rules
|
* Add rule to list of default validation rules
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param AbstractValidationRule $rule
|
||||||
* @param callable $rule
|
|
||||||
*/
|
*/
|
||||||
public static function addRule($name, callable $rule)
|
public static function addRule(AbstractValidationRule $rule)
|
||||||
{
|
{
|
||||||
self::$rules[$name] = $rule;
|
self::$rules[$rule->getName()] = $rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -292,7 +313,7 @@ class DocumentValidator
|
|||||||
* @param Schema $schema
|
* @param Schema $schema
|
||||||
* @param TypeInfo $typeInfo
|
* @param TypeInfo $typeInfo
|
||||||
* @param DocumentNode $documentNode
|
* @param DocumentNode $documentNode
|
||||||
* @param array $rules
|
* @param AbstractValidationRule[] $rules
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function visitUsingRules(Schema $schema, TypeInfo $typeInfo, DocumentNode $documentNode, array $rules)
|
public static function visitUsingRules(Schema $schema, TypeInfo $typeInfo, DocumentNode $documentNode, array $rules)
|
||||||
@ -300,7 +321,7 @@ class DocumentValidator
|
|||||||
$context = new ValidationContext($schema, $documentNode, $typeInfo);
|
$context = new ValidationContext($schema, $documentNode, $typeInfo);
|
||||||
$visitors = [];
|
$visitors = [];
|
||||||
foreach ($rules as $rule) {
|
foreach ($rules as $rule) {
|
||||||
$visitors[] = $rule($context);
|
$visitors[] = $rule->getVisitor($context);
|
||||||
}
|
}
|
||||||
Visitor::visit($documentNode, Visitor::visitWithTypeInfo($typeInfo, Visitor::visitInParallel($visitors)));
|
Visitor::visit($documentNode, Visitor::visitWithTypeInfo($typeInfo, Visitor::visitInParallel($visitors)));
|
||||||
return $context->getErrors();
|
return $context->getErrors();
|
||||||
|
@ -14,7 +14,7 @@ use GraphQL\Type\Introspection;
|
|||||||
use GraphQL\Utils\TypeInfo;
|
use GraphQL\Utils\TypeInfo;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
abstract class AbstractQuerySecurity
|
abstract class AbstractQuerySecurity extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
const DISABLED = 0;
|
const DISABLED = 0;
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ abstract class AbstractQuerySecurity
|
|||||||
* time we do not know what object type will be used, so we unconditionally
|
* time we do not know what object type will be used, so we unconditionally
|
||||||
* spread in all fragments.
|
* spread in all fragments.
|
||||||
*
|
*
|
||||||
* @see GraphQL\Validator\Rules\OverlappingFieldsCanBeMerged
|
* @see \GraphQL\Validator\Rules\OverlappingFieldsCanBeMerged
|
||||||
*
|
*
|
||||||
* @param ValidationContext $context
|
* @param ValidationContext $context
|
||||||
* @param Type|null $parentType
|
* @param Type|null $parentType
|
||||||
|
26
src/Validator/Rules/AbstractValidationRule.php
Normal file
26
src/Validator/Rules/AbstractValidationRule.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
namespace GraphQL\Validator\Rules;
|
||||||
|
|
||||||
|
use GraphQL\Error\Error;
|
||||||
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
|
abstract class AbstractValidationRule
|
||||||
|
{
|
||||||
|
protected $name;
|
||||||
|
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return $this->name ?: get_class($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __invoke(ValidationContext $context)
|
||||||
|
{
|
||||||
|
return $this->getVisitor($context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ValidationContext $context
|
||||||
|
* @return Error[]
|
||||||
|
*/
|
||||||
|
abstract public function getVisitor(ValidationContext $context);
|
||||||
|
}
|
@ -9,7 +9,7 @@ use GraphQL\Language\Visitor;
|
|||||||
use GraphQL\Validator\DocumentValidator;
|
use GraphQL\Validator\DocumentValidator;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class ArgumentsOfCorrectType
|
class ArgumentsOfCorrectType extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function badValueMessage($argName, $type, $value, $verboseErrors = [])
|
static function badValueMessage($argName, $type, $value, $verboseErrors = [])
|
||||||
{
|
{
|
||||||
@ -17,7 +17,7 @@ class ArgumentsOfCorrectType
|
|||||||
return "Argument \"$argName\" has invalid value $value.$message";
|
return "Argument \"$argName\" has invalid value $value.$message";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::ARGUMENT => function(ArgumentNode $argNode) use ($context) {
|
NodeKind::ARGUMENT => function(ArgumentNode $argNode) use ($context) {
|
||||||
|
27
src/Validator/Rules/CustomValidationRule.php
Normal file
27
src/Validator/Rules/CustomValidationRule.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
namespace GraphQL\Validator\Rules;
|
||||||
|
|
||||||
|
|
||||||
|
use GraphQL\Error\Error;
|
||||||
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
|
class CustomValidationRule extends AbstractValidationRule
|
||||||
|
{
|
||||||
|
private $visitorFn;
|
||||||
|
|
||||||
|
public function __construct($name, callable $visitorFn)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
$this->visitorFn = $visitorFn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ValidationContext $context
|
||||||
|
* @return Error[]
|
||||||
|
*/
|
||||||
|
public function getVisitor(ValidationContext $context)
|
||||||
|
{
|
||||||
|
$fn = $this->visitorFn;
|
||||||
|
return $fn($context);
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ use GraphQL\Type\Definition\NonNull;
|
|||||||
use GraphQL\Validator\DocumentValidator;
|
use GraphQL\Validator\DocumentValidator;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class DefaultValuesOfCorrectType
|
class DefaultValuesOfCorrectType extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function badValueForDefaultArgMessage($varName, $type, $value, $verboseErrors = null)
|
static function badValueForDefaultArgMessage($varName, $type, $value, $verboseErrors = null)
|
||||||
{
|
{
|
||||||
@ -27,7 +27,7 @@ class DefaultValuesOfCorrectType
|
|||||||
"Perhaps you meant to use type $guessType.";
|
"Perhaps you meant to use type $guessType.";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::VARIABLE_DEFINITION => function(VariableDefinitionNode $varDefNode) use ($context) {
|
NodeKind::VARIABLE_DEFINITION => function(VariableDefinitionNode $varDefNode) use ($context) {
|
||||||
|
@ -11,7 +11,7 @@ class DisableIntrospection extends AbstractQuerySecurity
|
|||||||
const ENABLED = 1;
|
const ENABLED = 1;
|
||||||
private $isEnabled;
|
private $isEnabled;
|
||||||
|
|
||||||
public function __construct($enabled)
|
public function __construct($enabled = self::ENABLED)
|
||||||
{
|
{
|
||||||
$this->setEnabled($enabled);
|
$this->setEnabled($enabled);
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ class DisableIntrospection extends AbstractQuerySecurity
|
|||||||
return $this->isEnabled !== static::DISABLED;
|
return $this->isEnabled !== static::DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return $this->invokeIfNeeded(
|
return $this->invokeIfNeeded(
|
||||||
$context,
|
$context,
|
||||||
|
@ -7,7 +7,7 @@ use GraphQL\Language\AST\NodeKind;
|
|||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class FieldsOnCorrectType
|
class FieldsOnCorrectType extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function undefinedFieldMessage($field, $type, array $suggestedTypes = [])
|
static function undefinedFieldMessage($field, $type, array $suggestedTypes = [])
|
||||||
{
|
{
|
||||||
@ -29,7 +29,7 @@ class FieldsOnCorrectType
|
|||||||
return $message;
|
return $message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::FIELD => function(FieldNode $node) use ($context) {
|
NodeKind::FIELD => function(FieldNode $node) use ($context) {
|
||||||
|
@ -10,7 +10,7 @@ use GraphQL\Type\Definition\Type;
|
|||||||
use GraphQL\Utils\TypeInfo;
|
use GraphQL\Utils\TypeInfo;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class FragmentsOnCompositeTypes
|
class FragmentsOnCompositeTypes extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function inlineFragmentOnNonCompositeErrorMessage($type)
|
static function inlineFragmentOnNonCompositeErrorMessage($type)
|
||||||
{
|
{
|
||||||
@ -22,7 +22,7 @@ class FragmentsOnCompositeTypes
|
|||||||
return "Fragment \"$fragName\" cannot condition on non composite type \"$type\".";
|
return "Fragment \"$fragName\" cannot condition on non composite type \"$type\".";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::INLINE_FRAGMENT => function(InlineFragmentNode $node) use ($context) {
|
NodeKind::INLINE_FRAGMENT => function(InlineFragmentNode $node) use ($context) {
|
||||||
|
@ -7,7 +7,7 @@ use GraphQL\Language\AST\NodeKind;
|
|||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class KnownArgumentNames
|
class KnownArgumentNames extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
public static function unknownArgMessage($argName, $fieldName, $type)
|
public static function unknownArgMessage($argName, $fieldName, $type)
|
||||||
{
|
{
|
||||||
@ -19,7 +19,7 @@ class KnownArgumentNames
|
|||||||
return "Unknown argument \"$argName\" on directive \"@$directiveName\".";
|
return "Unknown argument \"$argName\" on directive \"@$directiveName\".";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::ARGUMENT => function(ArgumentNode $node, $key, $parent, $path, $ancestors) use ($context) {
|
NodeKind::ARGUMENT => function(ArgumentNode $node, $key, $parent, $path, $ancestors) use ($context) {
|
||||||
|
@ -9,7 +9,7 @@ use GraphQL\Language\AST\NodeKind;
|
|||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
use GraphQL\Type\Definition\DirectiveLocation;
|
use GraphQL\Type\Definition\DirectiveLocation;
|
||||||
|
|
||||||
class KnownDirectives
|
class KnownDirectives extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function unknownDirectiveMessage($directiveName)
|
static function unknownDirectiveMessage($directiveName)
|
||||||
{
|
{
|
||||||
@ -21,7 +21,7 @@ class KnownDirectives
|
|||||||
return "Directive \"$directiveName\" may not be used on \"$location\".";
|
return "Directive \"$directiveName\" may not be used on \"$location\".";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::DIRECTIVE => function (DirectiveNode $node, $key, $parent, $path, $ancestors) use ($context) {
|
NodeKind::DIRECTIVE => function (DirectiveNode $node, $key, $parent, $path, $ancestors) use ($context) {
|
||||||
|
@ -8,14 +8,14 @@ use GraphQL\Language\AST\Node;
|
|||||||
use GraphQL\Language\AST\NodeKind;
|
use GraphQL\Language\AST\NodeKind;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class KnownFragmentNames
|
class KnownFragmentNames extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function unknownFragmentMessage($fragName)
|
static function unknownFragmentMessage($fragName)
|
||||||
{
|
{
|
||||||
return "Unknown fragment \"$fragName\".";
|
return "Unknown fragment \"$fragName\".";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::FRAGMENT_SPREAD => function(FragmentSpreadNode $node) use ($context) {
|
NodeKind::FRAGMENT_SPREAD => function(FragmentSpreadNode $node) use ($context) {
|
||||||
|
@ -8,14 +8,14 @@ use GraphQL\Language\AST\NodeKind;
|
|||||||
use GraphQL\Language\Visitor;
|
use GraphQL\Language\Visitor;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class KnownTypeNames
|
class KnownTypeNames extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function unknownTypeMessage($type)
|
static function unknownTypeMessage($type)
|
||||||
{
|
{
|
||||||
return "Unknown type \"$type\".";
|
return "Unknown type \"$type\".";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
$skip = function() {return Visitor::skipNode();};
|
$skip = function() {return Visitor::skipNode();};
|
||||||
|
|
||||||
|
@ -15,14 +15,14 @@ use GraphQL\Validator\ValidationContext;
|
|||||||
* A GraphQL document is only valid if when it contains an anonymous operation
|
* A GraphQL document is only valid if when it contains an anonymous operation
|
||||||
* (the query short-hand) that it contains only that one operation definition.
|
* (the query short-hand) that it contains only that one operation definition.
|
||||||
*/
|
*/
|
||||||
class LoneAnonymousOperation
|
class LoneAnonymousOperation extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function anonOperationNotAloneMessage()
|
static function anonOperationNotAloneMessage()
|
||||||
{
|
{
|
||||||
return 'This anonymous operation must be the only defined operation.';
|
return 'This anonymous operation must be the only defined operation.';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
$operationCount = 0;
|
$operationCount = 0;
|
||||||
return [
|
return [
|
||||||
|
@ -1,11 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
|
||||||
* Created by PhpStorm.
|
|
||||||
* User: Vladimir
|
|
||||||
* Date: 11.07.2015
|
|
||||||
* Time: 18:54
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace GraphQL\Validator\Rules;
|
namespace GraphQL\Validator\Rules;
|
||||||
|
|
||||||
|
|
||||||
@ -18,7 +11,7 @@ use GraphQL\Language\Visitor;
|
|||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class NoFragmentCycles
|
class NoFragmentCycles extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function cycleErrorMessage($fragName, array $spreadNames = [])
|
static function cycleErrorMessage($fragName, array $spreadNames = [])
|
||||||
{
|
{
|
||||||
@ -32,7 +25,7 @@ class NoFragmentCycles
|
|||||||
|
|
||||||
public $spreadPathIndexByName;
|
public $spreadPathIndexByName;
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
// Tracks already visited fragments to maintain O(N) and to ensure that cycles
|
// Tracks already visited fragments to maintain O(N) and to ensure that cycles
|
||||||
// are not redundantly reported.
|
// are not redundantly reported.
|
||||||
|
@ -15,7 +15,7 @@ use GraphQL\Validator\ValidationContext;
|
|||||||
*
|
*
|
||||||
* @package GraphQL\Validator\Rules
|
* @package GraphQL\Validator\Rules
|
||||||
*/
|
*/
|
||||||
class NoUndefinedVariables
|
class NoUndefinedVariables extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function undefinedVarMessage($varName, $opName = null)
|
static function undefinedVarMessage($varName, $opName = null)
|
||||||
{
|
{
|
||||||
@ -24,7 +24,7 @@ class NoUndefinedVariables
|
|||||||
: "Variable \"$$varName\" is not defined.";
|
: "Variable \"$$varName\" is not defined.";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
$variableNameDefined = [];
|
$variableNameDefined = [];
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ use GraphQL\Language\AST\NodeKind;
|
|||||||
use GraphQL\Language\Visitor;
|
use GraphQL\Language\Visitor;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class NoUnusedFragments
|
class NoUnusedFragments extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function unusedFragMessage($fragName)
|
static function unusedFragMessage($fragName)
|
||||||
{
|
{
|
||||||
@ -18,7 +18,7 @@ class NoUnusedFragments
|
|||||||
|
|
||||||
public $fragmentDefs;
|
public $fragmentDefs;
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
$this->operationDefs = [];
|
$this->operationDefs = [];
|
||||||
$this->fragmentDefs = [];
|
$this->fragmentDefs = [];
|
||||||
|
@ -6,7 +6,7 @@ use GraphQL\Language\AST\NodeKind;
|
|||||||
use GraphQL\Language\AST\OperationDefinitionNode;
|
use GraphQL\Language\AST\OperationDefinitionNode;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class NoUnusedVariables
|
class NoUnusedVariables extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function unusedVariableMessage($varName, $opName = null)
|
static function unusedVariableMessage($varName, $opName = null)
|
||||||
{
|
{
|
||||||
@ -17,7 +17,7 @@ class NoUnusedVariables
|
|||||||
|
|
||||||
public $variableDefs;
|
public $variableDefs;
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
$this->variableDefs = [];
|
$this->variableDefs = [];
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ use GraphQL\Utils\PairSet;
|
|||||||
use GraphQL\Utils\TypeInfo;
|
use GraphQL\Utils\TypeInfo;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class OverlappingFieldsCanBeMerged
|
class OverlappingFieldsCanBeMerged extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function fieldsConflictMessage($responseName, $reason)
|
static function fieldsConflictMessage($responseName, $reason)
|
||||||
{
|
{
|
||||||
@ -49,7 +49,7 @@ class OverlappingFieldsCanBeMerged
|
|||||||
*/
|
*/
|
||||||
public $comparedSet;
|
public $comparedSet;
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
$this->comparedSet = new PairSet();
|
$this->comparedSet = new PairSet();
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ use GraphQL\Type\Definition\UnionType;
|
|||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
use GraphQL\Utils\TypeInfo;
|
use GraphQL\Utils\TypeInfo;
|
||||||
|
|
||||||
class PossibleFragmentSpreads
|
class PossibleFragmentSpreads extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function typeIncompatibleSpreadMessage($fragName, $parentType, $fragType)
|
static function typeIncompatibleSpreadMessage($fragName, $parentType, $fragType)
|
||||||
{
|
{
|
||||||
@ -28,7 +28,7 @@ class PossibleFragmentSpreads
|
|||||||
return "Fragment cannot be spread here as objects of type \"$parentType\" can never be of type \"$fragType\".";
|
return "Fragment cannot be spread here as objects of type \"$parentType\" can never be of type \"$fragType\".";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::INLINE_FRAGMENT => function(InlineFragmentNode $node) use ($context) {
|
NodeKind::INLINE_FRAGMENT => function(InlineFragmentNode $node) use ($context) {
|
||||||
|
@ -12,7 +12,7 @@ use GraphQL\Type\Definition\NonNull;
|
|||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class ProvidedNonNullArguments
|
class ProvidedNonNullArguments extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function missingFieldArgMessage($fieldName, $argName, $type)
|
static function missingFieldArgMessage($fieldName, $argName, $type)
|
||||||
{
|
{
|
||||||
@ -24,7 +24,7 @@ class ProvidedNonNullArguments
|
|||||||
return "Directive \"@$directiveName\" argument \"$argName\" of type \"$type\" is required but not provided.";
|
return "Directive \"@$directiveName\" argument \"$argName\" of type \"$type\" is required but not provided.";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::FIELD => [
|
NodeKind::FIELD => [
|
||||||
|
@ -31,9 +31,9 @@ class QueryComplexity extends AbstractQuerySecurity
|
|||||||
*/
|
*/
|
||||||
private $context;
|
private $context;
|
||||||
|
|
||||||
public function __construct($maxQueryDepth)
|
public function __construct($maxQueryComplexity)
|
||||||
{
|
{
|
||||||
$this->setMaxQueryComplexity($maxQueryDepth);
|
$this->setMaxQueryComplexity($maxQueryComplexity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function maxQueryComplexityErrorMessage($max, $count)
|
public static function maxQueryComplexityErrorMessage($max, $count)
|
||||||
@ -68,7 +68,7 @@ class QueryComplexity extends AbstractQuerySecurity
|
|||||||
return $this->rawVariableValues;
|
return $this->rawVariableValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
$this->context = $context;
|
$this->context = $context;
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ class QueryDepth extends AbstractQuerySecurity
|
|||||||
return sprintf('Max query depth should be %d but got %d.', $max, $count);
|
return sprintf('Max query depth should be %d but got %d.', $max, $count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return $this->invokeIfNeeded(
|
return $this->invokeIfNeeded(
|
||||||
$context,
|
$context,
|
||||||
|
@ -7,7 +7,7 @@ use GraphQL\Language\AST\NodeKind;
|
|||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class ScalarLeafs
|
class ScalarLeafs extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function noSubselectionAllowedMessage($field, $type)
|
static function noSubselectionAllowedMessage($field, $type)
|
||||||
{
|
{
|
||||||
@ -19,7 +19,7 @@ class ScalarLeafs
|
|||||||
return "Field \"$field\" of type \"$type\" must have a sub selection.";
|
return "Field \"$field\" of type \"$type\" must have a sub selection.";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::FIELD => function(FieldNode $node) use ($context) {
|
NodeKind::FIELD => function(FieldNode $node) use ($context) {
|
||||||
|
@ -8,7 +8,7 @@ use GraphQL\Language\AST\NodeKind;
|
|||||||
use GraphQL\Language\Visitor;
|
use GraphQL\Language\Visitor;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class UniqueArgumentNames
|
class UniqueArgumentNames extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function duplicateArgMessage($argName)
|
static function duplicateArgMessage($argName)
|
||||||
{
|
{
|
||||||
@ -17,7 +17,7 @@ class UniqueArgumentNames
|
|||||||
|
|
||||||
public $knownArgNames;
|
public $knownArgNames;
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
$this->knownArgNames = [];
|
$this->knownArgNames = [];
|
||||||
|
|
||||||
|
@ -6,14 +6,14 @@ use GraphQL\Language\AST\DirectiveNode;
|
|||||||
use GraphQL\Language\AST\Node;
|
use GraphQL\Language\AST\Node;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class UniqueDirectivesPerLocation
|
class UniqueDirectivesPerLocation extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function duplicateDirectiveMessage($directiveName)
|
static function duplicateDirectiveMessage($directiveName)
|
||||||
{
|
{
|
||||||
return 'The directive "'.$directiveName.'" can only be used once at this location.';
|
return 'The directive "'.$directiveName.'" can only be used once at this location.';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'enter' => function(Node $node) use ($context) {
|
'enter' => function(Node $node) use ($context) {
|
||||||
|
@ -9,7 +9,7 @@ use GraphQL\Language\AST\NodeKind;
|
|||||||
use GraphQL\Language\Visitor;
|
use GraphQL\Language\Visitor;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class UniqueFragmentNames
|
class UniqueFragmentNames extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function duplicateFragmentNameMessage($fragName)
|
static function duplicateFragmentNameMessage($fragName)
|
||||||
{
|
{
|
||||||
@ -18,7 +18,7 @@ class UniqueFragmentNames
|
|||||||
|
|
||||||
public $knownFragmentNames;
|
public $knownFragmentNames;
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
$this->knownFragmentNames = [];
|
$this->knownFragmentNames = [];
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ use GraphQL\Language\AST\ObjectFieldNode;
|
|||||||
use GraphQL\Language\Visitor;
|
use GraphQL\Language\Visitor;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class UniqueInputFieldNames
|
class UniqueInputFieldNames extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function duplicateInputFieldMessage($fieldName)
|
static function duplicateInputFieldMessage($fieldName)
|
||||||
{
|
{
|
||||||
@ -18,7 +18,7 @@ class UniqueInputFieldNames
|
|||||||
public $knownNames;
|
public $knownNames;
|
||||||
public $knownNameStack;
|
public $knownNameStack;
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
$this->knownNames = [];
|
$this->knownNames = [];
|
||||||
$this->knownNameStack = [];
|
$this->knownNameStack = [];
|
||||||
|
@ -8,7 +8,7 @@ use GraphQL\Language\AST\OperationDefinitionNode;
|
|||||||
use GraphQL\Language\Visitor;
|
use GraphQL\Language\Visitor;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class UniqueOperationNames
|
class UniqueOperationNames extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function duplicateOperationNameMessage($operationName)
|
static function duplicateOperationNameMessage($operationName)
|
||||||
{
|
{
|
||||||
@ -17,7 +17,7 @@ class UniqueOperationNames
|
|||||||
|
|
||||||
public $knownOperationNames;
|
public $knownOperationNames;
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
$this->knownOperationNames = [];
|
$this->knownOperationNames = [];
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ use GraphQL\Language\AST\NodeKind;
|
|||||||
use GraphQL\Language\AST\VariableDefinitionNode;
|
use GraphQL\Language\AST\VariableDefinitionNode;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class UniqueVariableNames
|
class UniqueVariableNames extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function duplicateVariableMessage($variableName)
|
static function duplicateVariableMessage($variableName)
|
||||||
{
|
{
|
||||||
@ -16,7 +16,7 @@ class UniqueVariableNames
|
|||||||
|
|
||||||
public $knownVariableNames;
|
public $knownVariableNames;
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
$this->knownVariableNames = [];
|
$this->knownVariableNames = [];
|
||||||
|
|
||||||
|
@ -12,14 +12,14 @@ use GraphQL\Type\Definition\Type;
|
|||||||
use GraphQL\Utils\TypeInfo;
|
use GraphQL\Utils\TypeInfo;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class VariablesAreInputTypes
|
class VariablesAreInputTypes extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function nonInputTypeOnVarMessage($variableName, $typeName)
|
static function nonInputTypeOnVarMessage($variableName, $typeName)
|
||||||
{
|
{
|
||||||
return "Variable \"\$$variableName\" cannot be non-input type \"$typeName\".";
|
return "Variable \"\$$variableName\" cannot be non-input type \"$typeName\".";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::VARIABLE_DEFINITION => function(VariableDefinitionNode $node) use ($context) {
|
NodeKind::VARIABLE_DEFINITION => function(VariableDefinitionNode $node) use ($context) {
|
||||||
|
@ -11,7 +11,7 @@ use GraphQL\Utils\TypeComparators;
|
|||||||
use GraphQL\Utils\TypeInfo;
|
use GraphQL\Utils\TypeInfo;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class VariablesInAllowedPosition
|
class VariablesInAllowedPosition extends AbstractValidationRule
|
||||||
{
|
{
|
||||||
static function badVarPosMessage($varName, $varType, $expectedType)
|
static function badVarPosMessage($varName, $varType, $expectedType)
|
||||||
{
|
{
|
||||||
@ -21,7 +21,7 @@ class VariablesInAllowedPosition
|
|||||||
|
|
||||||
public $varDefMap;
|
public $varDefMap;
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::OPERATION_DEFINITION => [
|
NodeKind::OPERATION_DEFINITION => [
|
||||||
|
@ -17,6 +17,7 @@ use GraphQL\Server\ServerConfig;
|
|||||||
use GraphQL\Type\Definition\ObjectType;
|
use GraphQL\Type\Definition\ObjectType;
|
||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
use GraphQL\Validator\DocumentValidator;
|
use GraphQL\Validator\DocumentValidator;
|
||||||
|
use GraphQL\Validator\Rules\CustomValidationRule;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
class QueryExecutionTest extends \PHPUnit_Framework_TestCase
|
class QueryExecutionTest extends \PHPUnit_Framework_TestCase
|
||||||
@ -219,10 +220,10 @@ class QueryExecutionTest extends \PHPUnit_Framework_TestCase
|
|||||||
$called = false;
|
$called = false;
|
||||||
|
|
||||||
$rules = [
|
$rules = [
|
||||||
function() use (&$called) {
|
new CustomValidationRule('SomeRule', function() use (&$called) {
|
||||||
$called = true;
|
$called = true;
|
||||||
return [];
|
return [];
|
||||||
}
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->config->setValidationRules($rules);
|
$this->config->setValidationRules($rules);
|
||||||
@ -268,9 +269,9 @@ class QueryExecutionTest extends \PHPUnit_Framework_TestCase
|
|||||||
} else {
|
} else {
|
||||||
$called2 = true;
|
$called2 = true;
|
||||||
return [
|
return [
|
||||||
function(ValidationContext $context) {
|
new CustomValidationRule('MyRule', function(ValidationContext $context) {
|
||||||
$context->reportError(new Error("This is the error we are looking for!"));
|
$context->reportError(new Error("This is the error we are looking for!"));
|
||||||
}
|
})
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -5,6 +5,7 @@ use GraphQL\Error\Error;
|
|||||||
use GraphQL\Language\AST\NodeKind;
|
use GraphQL\Language\AST\NodeKind;
|
||||||
use GraphQL\Language\Parser;
|
use GraphQL\Language\Parser;
|
||||||
use GraphQL\Validator\DocumentValidator;
|
use GraphQL\Validator\DocumentValidator;
|
||||||
|
use GraphQL\Validator\Rules\CustomValidationRule;
|
||||||
use GraphQL\Validator\Rules\QueryComplexity;
|
use GraphQL\Validator\Rules\QueryComplexity;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
|
||||||
@ -159,7 +160,7 @@ class QueryComplexityTest extends AbstractQuerySecurityTest
|
|||||||
$query = 'query MyQuery { human(name: INVALID_VALUE) { dogs {name} } }';
|
$query = 'query MyQuery { human(name: INVALID_VALUE) { dogs {name} } }';
|
||||||
|
|
||||||
$reportedError = new Error("OtherValidatorError");
|
$reportedError = new Error("OtherValidatorError");
|
||||||
$otherRule = function(ValidationContext $context) use ($reportedError) {
|
$otherRule = new CustomValidationRule('otherRule', function(ValidationContext $context) use ($reportedError) {
|
||||||
return [
|
return [
|
||||||
NodeKind::OPERATION_DEFINITION => [
|
NodeKind::OPERATION_DEFINITION => [
|
||||||
'leave' => function() use ($context, $reportedError) {
|
'leave' => function() use ($context, $reportedError) {
|
||||||
@ -167,7 +168,7 @@ class QueryComplexityTest extends AbstractQuerySecurityTest
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
};
|
});
|
||||||
|
|
||||||
$errors = DocumentValidator::validate(
|
$errors = DocumentValidator::validate(
|
||||||
QuerySecuritySchema::buildSchema(),
|
QuerySecuritySchema::buildSchema(),
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace GraphQL\Tests\Validator;
|
namespace GraphQL\Tests\Validator;
|
||||||
|
|
||||||
|
use GraphQL\Validator\DocumentValidator;
|
||||||
|
use GraphQL\Validator\Rules\QueryComplexity;
|
||||||
|
|
||||||
class ValidationTest extends TestCase
|
class ValidationTest extends TestCase
|
||||||
{
|
{
|
||||||
// Validate: Supports full validation
|
// Validate: Supports full validation
|
||||||
@ -23,7 +26,16 @@ class ValidationTest extends TestCase
|
|||||||
}
|
}
|
||||||
');
|
');
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
public function testAllowsSettingRulesGlobally()
|
||||||
|
{
|
||||||
|
$rule = new QueryComplexity(0);
|
||||||
|
|
||||||
|
DocumentValidator::addRule($rule);
|
||||||
|
$instance = DocumentValidator::getRule(QueryComplexity::class);
|
||||||
|
$this->assertSame($rule, $instance);
|
||||||
|
}
|
||||||
|
*/
|
||||||
public function testPassesValidationWithEmptyRules()
|
public function testPassesValidationWithEmptyRules()
|
||||||
{
|
{
|
||||||
$query = '{invalid}';
|
$query = '{invalid}';
|
||||||
|
Loading…
Reference in New Issue
Block a user