diff --git a/CHANGELOG.md b/CHANGELOG.md index ab40a26d41..4557aa08c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,12 @@ You can find and compare releases at the [GitHub release page](https://github.co ## Unreleased +## v6.5.0 + +### Added + +- Add `Nuwave\Lighthouse\Schema\AST\ASTHelper::addDirectiveToNode()` to simplify dynamic addition of directives https://github.com/nuwave/lighthouse/pull/2369 + ## v6.4.0 ### Added diff --git a/src/Schema/AST/ASTHelper.php b/src/Schema/AST/ASTHelper.php index 3adbee82c6..a49e5ce25b 100644 --- a/src/Schema/AST/ASTHelper.php +++ b/src/Schema/AST/ASTHelper.php @@ -29,7 +29,7 @@ use GraphQL\Language\AST\UnionTypeExtensionNode; use GraphQL\Language\AST\ValueNode; use GraphQL\Language\Parser; -use GraphQL\Type\Definition\Directive; +use GraphQL\Type\Definition\Directive as DirectiveDefinition; use GraphQL\Type\Definition\EnumType; use GraphQL\Type\Definition\EnumValueDefinition; use GraphQL\Type\Definition\Type; @@ -42,8 +42,7 @@ use Nuwave\Lighthouse\Schema\Directives\BaseDirective; use Nuwave\Lighthouse\Schema\Directives\ModelDirective; use Nuwave\Lighthouse\Schema\Directives\NamespaceDirective; -use Nuwave\Lighthouse\Support\Contracts\ArgManipulator; -use Nuwave\Lighthouse\Support\Contracts\FieldManipulator; +use Nuwave\Lighthouse\Support\Contracts\Directive as DirectiveInterface; class ASTHelper { @@ -308,7 +307,7 @@ public static function qualifiedArgType( public static function deprecationReason(EnumValueDefinitionNode|FieldDefinitionNode $node): ?string { $deprecated = Values::getDirectiveValues( - Directive::deprecatedDirective(), + DirectiveDefinition::deprecatedDirective(), $node, ); @@ -392,11 +391,9 @@ public static function internalFieldName(FieldDefinitionNode $field): string } /** - * Adds a directive to a node. - * - * @api + * Adds a directive to a node, instantiates and maybe hydrates it and returns the instance. */ - public static function addDirectiveToNode(string $directiveSource, ScalarTypeDefinitionNode|ScalarTypeExtensionNode|ObjectTypeDefinitionNode|ObjectTypeExtensionNode|InterfaceTypeDefinitionNode|InterfaceTypeExtensionNode|UnionTypeDefinitionNode|UnionTypeExtensionNode|EnumTypeDefinitionNode|EnumTypeExtensionNode|InputObjectTypeDefinitionNode|InputObjectTypeExtensionNode|FieldDefinitionNode|InputValueDefinitionNode|EnumValueDefinitionNode $node): \Nuwave\Lighthouse\Support\Contracts\Directive + public static function addDirectiveToNode(string $directiveSource, ScalarTypeDefinitionNode|ScalarTypeExtensionNode|ObjectTypeDefinitionNode|ObjectTypeExtensionNode|InterfaceTypeDefinitionNode|InterfaceTypeExtensionNode|UnionTypeDefinitionNode|UnionTypeExtensionNode|EnumTypeDefinitionNode|EnumTypeExtensionNode|InputObjectTypeDefinitionNode|InputObjectTypeExtensionNode|FieldDefinitionNode|InputValueDefinitionNode|EnumValueDefinitionNode $node): DirectiveInterface { $directiveNode = Parser::directive($directiveSource); $node->directives[] = $directiveNode; diff --git a/tests/Unit/Schema/AST/ASTHelperTest.php b/tests/Unit/Schema/AST/ASTHelperTest.php index f408870db4..a15a778253 100644 --- a/tests/Unit/Schema/AST/ASTHelperTest.php +++ b/tests/Unit/Schema/AST/ASTHelperTest.php @@ -19,7 +19,6 @@ use Nuwave\Lighthouse\Schema\RootType; use Nuwave\Lighthouse\Support\Contracts\ArgManipulator; use Nuwave\Lighthouse\Support\Contracts\FieldManipulator; -use Nuwave\Lighthouse\Support\Utils; use Tests\TestCase; final class ASTHelperTest extends TestCase @@ -237,11 +236,11 @@ public function manipulateFieldDefinition( DocumentAST &$documentAST, FieldDefinitionNode &$fieldDefinition, ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode &$parentType, - ):void { + ): void { $fieldDefinition->type = Parser::namedType('Int'); } }; - + $directiveLocator = $this->app->make(DirectiveLocator::class); $directiveLocator->setResolved('foo', $directive::class); @@ -255,16 +254,14 @@ public function manipulateFieldDefinition( DocumentAST &$documentAST, FieldDefinitionNode &$fieldDefinition, ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode &$parentType, - ):void { + ): void { $directiveInstance = ASTHelper::addDirectiveToNode('@foo', $fieldDefinition); - assert($directiveInstance instanceof FieldManipulator); - + $directiveInstance->manipulateFieldDefinition($documentAST, $fieldDefinition, $parentType); } }; - $directiveLocator = $this->app->make(DirectiveLocator::class); $directiveLocator->setResolved('dynamic', $dynamicDirective::class); $this->schema = /** @lang GraphQL */ ' @@ -283,13 +280,11 @@ public function manipulateFieldDefinition( $typeType = $fieldType->type; assert($typeType instanceof NamedTypeNode); - $this->assertEquals($typeType->name->value, 'Int'); + $this->assertSame($typeType->name->value, 'Int'); } public function testDynamicallyAddedArgManipulatorDirective(): void { - $astBuilder = $this->app->make(ASTBuilder::class); - $directive = new class() extends BaseDirective implements ArgManipulator { public static function definition(): string { @@ -301,12 +296,11 @@ public function manipulateArgDefinition( InputValueDefinitionNode &$argDefinition, FieldDefinitionNode &$parentField, ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode &$parentType, - ): void - { + ): void { $argDefinition->type = Parser::namedType('Int'); } }; - + $directiveLocator = $this->app->make(DirectiveLocator::class); $directiveLocator->setResolved('foo', $directive::class); @@ -321,24 +315,23 @@ public function manipulateArgDefinition( InputValueDefinitionNode &$argDefinition, FieldDefinitionNode &$parentField, ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode &$parentType, - ): void - { + ): void { $directiveInstance = ASTHelper::addDirectiveToNode('@foo', $argDefinition); assert($directiveInstance instanceof ArgManipulator); - + $directiveInstance->manipulateArgDefinition($documentAST, $argDefinition, $parentField, $parentType); } }; - $directiveLocator = $this->app->make(DirectiveLocator::class); $directiveLocator->setResolved('dynamic', $dynamicDirective::class); $this->schema = /** @lang GraphQL */ ' type Query { - foo( name: String @dynamic ): String + foo(name: String @dynamic): String } '; + $astBuilder = $this->app->make(ASTBuilder::class); $documentAST = $astBuilder->documentAST(); $queryType = $documentAST->types[RootType::QUERY]; @@ -353,6 +346,6 @@ public function manipulateArgDefinition( $typeType = $argumentType->type; assert($typeType instanceof NamedTypeNode); - $this->assertEquals($typeType->name->value, 'Int'); + $this->assertSame($typeType->name->value, 'Int'); } }