-
-
Notifications
You must be signed in to change notification settings - Fork 570
Description
After running AST::fromArray
on the output of AST::toArray
, the DirectiveDefinitionNode->locations
goes from an array to a NodeList. The KnownDirectives
usage of DirectiveDefinitionNode->locations
expects to work with an array so an error is generated instead.
Warning: array_map(): Expected parameter 2 to be an array, object given
graphql-php/src/Language/AST/DirectiveDefinitionNode.php
Lines 24 to 25 in 4f34309
/** @var NameNode[] */ | |
public $locations; |
Lines 104 to 116 in 4f34309
foreach ($node as $key => $value) { | |
if ($key === 'loc' || $key === 'kind') { | |
continue; | |
} | |
if (is_array($value)) { | |
if (isset($value[0]) || count($value) === 0) { | |
$value = new NodeList($value); | |
} else { | |
$value = self::fromArray($value); | |
} | |
} | |
$instance->{$key} = $value; | |
} |
graphql-php/src/Validator/Rules/KnownDirectives.php
Lines 74 to 84 in 4f34309
foreach ($astDefinition as $def) { | |
if (! ($def instanceof DirectiveDefinitionNode)) { | |
continue; | |
} | |
$locationsMap[$def->name->value] = array_map( | |
static function ($name) : string { | |
return $name->value; | |
}, | |
$def->locations | |
); |
I'm not sure if the correct fix is to change KnownDirective to use Utils::map
, adjust AST::fromArray
to ensure it stays as an array, and/or to adjust the creation of DirectiveDefinitionNode
to use a NodeList initially.
diffs for exposing the problem and a naive "fix"
The easiest way to expose this problem:
diff --git a/tests/Validator/KnownDirectivesTest.php b/tests/Validator/KnownDirectivesTest.php
index 38c190e..f35e94b 100644
--- a/tests/Validator/KnownDirectivesTest.php
+++ b/tests/Validator/KnownDirectivesTest.php
@@ -5,8 +5,10 @@ declare(strict_types=1);
namespace GraphQL\Tests\Validator;
use GraphQL\Error\FormattedError;
+use GraphQL\Language\Parser;
use GraphQL\Language\SourceLocation;
use GraphQL\Type\Schema;
+use GraphQL\Utils\AST;
use GraphQL\Utils\BuildSchema;
use GraphQL\Validator\Rules\KnownDirectives;
@@ -17,7 +19,7 @@ class KnownDirectivesTest extends ValidatorTestCase
public function setUp() : void
{
- $this->schemaWithSDLDirectives = BuildSchema::build('
+ $this->schemaWithSDLDirectives = BuildSchema::build(AST::fromArray(AST::toArray(Parser::parse('
directive @onSchema on SCHEMA
directive @onScalar on SCALAR
directive @onObject on OBJECT
@@ -29,7 +31,7 @@ class KnownDirectivesTest extends ValidatorTestCase
directive @onEnumValue on ENUM_VALUE
directive @onInputObject on INPUT_OBJECT
directive @onInputFieldDefinition on INPUT_FIELD_DEFINITION
- ');
+ '))));
}
private function expectSDLErrors($sdlString, $schema = null, $errors = [])
The easiest immediate "fix" (though having the type change doesn't seem correct?):
diff --git a/src/Validator/Rules/KnownDirectives.php b/src/Validator/Rules/KnownDirectives.php
index 6dbf849..758e861 100644
--- a/src/Validator/Rules/KnownDirectives.php
+++ b/src/Validator/Rules/KnownDirectives.php
@@ -36,6 +36,7 @@ use GraphQL\Language\AST\UnionTypeExtensionNode;
use GraphQL\Language\AST\VariableDefinitionNode;
use GraphQL\Language\DirectiveLocation;
use GraphQL\Type\Definition\Directive;
+use GraphQL\Utils\Utils;
use GraphQL\Validator\ASTValidationContext;
use GraphQL\Validator\SDLValidationContext;
use GraphQL\Validator\ValidationContext;
@@ -76,11 +77,11 @@ class KnownDirectives extends ValidationRule
continue;
}
- $locationsMap[$def->name->value] = array_map(
+ $locationsMap[$def->name->value] = Utils::map(
+ $def->locations,
static function ($name) : string {
return $name->value;
- },
- $def->locations
+ }
);
}