From 30f3e95fb8b691198ebab4b73d007635258b38f2 Mon Sep 17 00:00:00 2001 From: Aleksei Lebedev <1329824+LastDragon-ru@users.noreply.github.com> Date: Fri, 26 Jan 2024 14:03:38 +0400 Subject: [PATCH] refactor(graphql)!: Added parent to the `Source`. --- packages/graphql/UPGRADE.md | 2 + .../src/Builder/BuilderInfoDetectorTest.php | 271 ++++++++---------- .../src/Builder/Sources/InputFieldSource.php | 12 +- .../src/Builder/Sources/InputSource.php | 4 +- .../Sources/InterfaceFieldArgumentSource.php | 22 +- .../Builder/Sources/InterfaceFieldSource.php | 23 +- .../src/Builder/Sources/InterfaceSource.php | 4 +- .../Sources/ObjectFieldArgumentSource.php | 22 +- .../src/Builder/Sources/ObjectFieldSource.php | 18 +- .../src/Builder/Sources/ObjectSource.php | 4 +- .../graphql/src/Builder/Sources/Source.php | 12 +- .../graphql/src/Builder/Traits/WithSource.php | 28 +- .../src/Stream/Directives/Directive.php | 3 +- .../src/Stream/Directives/DirectiveTest.php | 83 +++--- 14 files changed, 242 insertions(+), 266 deletions(-) diff --git a/packages/graphql/UPGRADE.md b/packages/graphql/UPGRADE.md index 9b954174b..58d4a4dd1 100644 --- a/packages/graphql/UPGRADE.md +++ b/packages/graphql/UPGRADE.md @@ -86,6 +86,8 @@ This section is actual only if you are extending the package. Please review and * [ ] `LastDragon_ru\LaraASP\GraphQL\Builder\Directives\PropertyDirective` +* [ ] `LastDragon_ru\LaraASP\GraphQL\Builder\Sources\*` + * [ ] `LastDragon_ru\LaraASP\GraphQL\Builder\Types\InputObject` * [ ] `LastDragon_ru\LaraASP\GraphQL\SortBy\Builders\*` => `LastDragon_ru\LaraASP\GraphQL\SortBy\Sorters\*` diff --git a/packages/graphql/src/Builder/BuilderInfoDetectorTest.php b/packages/graphql/src/Builder/BuilderInfoDetectorTest.php index 8345f3196..e5877fd45 100644 --- a/packages/graphql/src/Builder/BuilderInfoDetectorTest.php +++ b/packages/graphql/src/Builder/BuilderInfoDetectorTest.php @@ -16,6 +16,7 @@ use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\InterfaceFieldSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectFieldArgumentSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectFieldSource; +use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Traits\WithManipulator; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Requirements\RequiresLaravelScout; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\TestCase; @@ -112,11 +113,10 @@ public static function dataProviderGetNodeBuilderInfo(): array { 'builder' => null, ], static function (DirectiveLocator $locator, AstManipulator $manipulator): ObjectFieldSource { - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field: String'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field: String'), + ); }, ], '@all' => [ @@ -127,11 +127,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object static function (DirectiveLocator $locator, AstManipulator $manipulator): ObjectFieldSource { $locator->setResolved('all', AllDirective::class); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field: String @all'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field: String @all'), + ); }, ], '@all(query)' => [ @@ -145,11 +144,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object $class = json_encode(BuilderInfoDetectorTest__QueryBuilderResolver::class, JSON_THROW_ON_ERROR); $field = Parser::fieldDefinition("field: String @all(builder: {$class})"); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - $field, - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + $field, + ); }, ], '@all(custom query)' => [ @@ -163,11 +161,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object $class = json_encode(BuilderInfoDetectorTest__CustomBuilderResolver::class, JSON_THROW_ON_ERROR); $field = Parser::fieldDefinition("field: String @all(builder: {$class})"); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - $field, - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + $field, + ); }, ], '@paginate' => [ @@ -178,11 +175,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object static function (DirectiveLocator $locator, AstManipulator $manipulator): ObjectFieldSource { $locator->setResolved('paginate', PaginateDirective::class); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field: String @paginate'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field: String @paginate'), + ); }, ], '@paginate(resolver)' => [ @@ -196,11 +192,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object $class = json_encode(BuilderInfoDetectorTest__PaginatorResolver::class, JSON_THROW_ON_ERROR); $field = Parser::fieldDefinition("field: String @paginate(resolver: {$class})"); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - $field, - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + $field, + ); }, ], '@paginate(query)' => [ @@ -214,11 +209,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object $class = json_encode(BuilderInfoDetectorTest__QueryBuilderResolver::class, JSON_THROW_ON_ERROR); $field = Parser::fieldDefinition("field: String @paginate(builder: {$class})"); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - $field, - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + $field, + ); }, ], '@paginate(custom query)' => [ @@ -232,11 +226,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object $class = json_encode(BuilderInfoDetectorTest__CustomBuilderResolver::class, JSON_THROW_ON_ERROR); $field = Parser::fieldDefinition("field: String @paginate(builder: {$class})"); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - $field, - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + $field, + ); }, ], '@relation' => [ @@ -247,11 +240,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object static function (DirectiveLocator $locator, AstManipulator $manipulator): ObjectFieldSource { $locator->setResolved('relation', BuilderInfoDetectorTest__RelationDirective::class); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field: String @relation'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field: String @relation'), + ); }, ], '@find' => [ @@ -262,11 +254,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object static function (DirectiveLocator $locator, AstManipulator $manipulator): ObjectFieldSource { $locator->setResolved('find', FindDirective::class); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field: String @find'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field: String @find'), + ); }, ], '@first' => [ @@ -277,11 +268,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object static function (DirectiveLocator $locator, AstManipulator $manipulator): ObjectFieldSource { $locator->setResolved('first', FirstDirective::class); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field: String @first'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field: String @first'), + ); }, ], '@count' => [ @@ -292,11 +282,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object static function (DirectiveLocator $locator, AstManipulator $manipulator): ObjectFieldSource { $locator->setResolved('count', CountDirective::class); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field: String @count'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field: String @count'), + ); }, ], '@aggregate' => [ @@ -307,11 +296,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object static function (DirectiveLocator $locator, AstManipulator $manipulator): ObjectFieldSource { $locator->setResolved('aggregate', AggregateDirective::class); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field: String @aggregate'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field: String @aggregate'), + ); }, ], '@aggregate(query)' => [ @@ -325,11 +313,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object $class = json_encode(BuilderInfoDetectorTest__QueryBuilderResolver::class, JSON_THROW_ON_ERROR); $field = Parser::fieldDefinition("field: String @aggregate(builder: {$class})"); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - $field, - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + $field, + ); }, ], BuilderInfoProvider::class => [ @@ -340,11 +327,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object static function (DirectiveLocator $locator, AstManipulator $manipulator): ObjectFieldSource { $locator->setResolved('custom', BuilderInfoDetectorTest__BuilderInfoProviderDirective::class); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field: String @custom'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field: String @custom'), + ); }, ], ]; @@ -366,11 +352,10 @@ public static function dataProviderGetNodeBuilderInfoScoutBuilder(): array { static function (DirectiveLocator $locator, AstManipulator $manipulator): ObjectFieldSource { $locator->setResolved('search', SearchDirective::class); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field(search: String @search): String'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field(search: String @search): String'), + ); }, ], '@all' => [ @@ -382,11 +367,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object $locator->setResolved('search', SearchDirective::class); $locator->setResolved('all', AllDirective::class); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field(search: String @search): String @all'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field(search: String @search): String @all'), + ); }, ], '@all(query)' => [ @@ -401,11 +385,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object $class = json_encode(BuilderInfoDetectorTest__QueryBuilderResolver::class, JSON_THROW_ON_ERROR); $field = Parser::fieldDefinition("field(search: String @search): String @all(builder: {$class})"); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - $field, - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + $field, + ); }, ], '@all(custom query)' => [ @@ -420,11 +403,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object $class = json_encode(BuilderInfoDetectorTest__CustomBuilderResolver::class, JSON_THROW_ON_ERROR); $field = Parser::fieldDefinition("field(search: String @search): String @all(builder: {$class})"); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - $field, - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + $field, + ); }, ], '@paginate' => [ @@ -436,11 +418,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object $locator->setResolved('search', SearchDirective::class); $locator->setResolved('paginate', PaginateDirective::class); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field(search: String @search): String @paginate'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field(search: String @search): String @paginate'), + ); }, ], '@paginate(resolver)' => [ @@ -457,11 +438,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object "field(search: String @search): String @paginate(resolver: {$class})", ); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - $field, - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + $field, + ); }, ], '@paginate(query)' => [ @@ -478,11 +458,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object "field(search: String @search): String @paginate(builder: {$class})", ); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - $field, - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + $field, + ); }, ], '@paginate(custom query)' => [ @@ -499,11 +478,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object "field(search: String @search): String @paginate(builder: {$class})", ); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - $field, - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + $field, + ); }, ], '@relation' => [ @@ -515,11 +493,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object $locator->setResolved('search', SearchDirective::class); $locator->setResolved('relation', BuilderInfoDetectorTest__RelationDirective::class); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field(search: String @search): String @relation'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field(search: String @search): String @relation'), + ); }, ], '@find' => [ @@ -531,11 +508,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object $locator->setResolved('search', SearchDirective::class); $locator->setResolved('find', FindDirective::class); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field(search: String @search): String @find'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field(search: String @search): String @find'), + ); }, ], '@first' => [ @@ -547,11 +523,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object $locator->setResolved('search', SearchDirective::class); $locator->setResolved('first', FirstDirective::class); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field(search: String @search): String @first'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field(search: String @search): String @first'), + ); }, ], '@count' => [ @@ -563,11 +538,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object $locator->setResolved('search', SearchDirective::class); $locator->setResolved('count', CountDirective::class); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field(search: String @search): String @count'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field(search: String @search): String @count'), + ); }, ], '@aggregate' => [ @@ -579,11 +553,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object $locator->setResolved('search', SearchDirective::class); $locator->setResolved('aggregate', AggregateDirective::class); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field(search: String @search): String @aggregate'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field(search: String @search): String @aggregate'), + ); }, ], '@aggregate(query)' => [ @@ -600,11 +573,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object "field(search: String @search): String @aggregate(builder: {$class})", ); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - $field, - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + $field, + ); }, ], BuilderInfoProvider::class => [ @@ -616,11 +588,10 @@ static function (DirectiveLocator $locator, AstManipulator $manipulator): Object $locator->setResolved('search', SearchDirective::class); $locator->setResolved('custom', BuilderInfoDetectorTest__BuilderInfoProviderDirective::class); - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Test', 'fields' => []]), - Parser::fieldDefinition('field(search: String @search): String @custom'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Test', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('field(search: String @search): String @custom'), + ); }, ], ]; diff --git a/packages/graphql/src/Builder/Sources/InputFieldSource.php b/packages/graphql/src/Builder/Sources/InputFieldSource.php index b1c7774a8..da67a2721 100644 --- a/packages/graphql/src/Builder/Sources/InputFieldSource.php +++ b/packages/graphql/src/Builder/Sources/InputFieldSource.php @@ -17,23 +17,27 @@ use LastDragon_ru\LaraASP\GraphQL\Utils\AstManipulator; /** - * @extends Source + * @extends Source */ class InputFieldSource extends Source { use Field; public function __construct( AstManipulator $manipulator, - private InputObjectTypeDefinitionNode|InputObjectType $object, + InputSource $parent, private InputValueDefinitionNode|InputObjectField $field, ) { - parent::__construct($manipulator, $field instanceof InputObjectField ? $field->getType() : $field->type); + parent::__construct( + $manipulator, + $field instanceof InputObjectField ? $field->getType() : $field->type, + $parent, + ); } // // ========================================================================= public function getObject(): InputObjectTypeDefinitionNode|InputObjectType { - return $this->object; + return $this->getParent()->getType(); } public function getField(): InputValueDefinitionNode|InputObjectField { diff --git a/packages/graphql/src/Builder/Sources/InputSource.php b/packages/graphql/src/Builder/Sources/InputSource.php index e04b6f8c8..233267c34 100644 --- a/packages/graphql/src/Builder/Sources/InputSource.php +++ b/packages/graphql/src/Builder/Sources/InputSource.php @@ -8,10 +8,10 @@ use GraphQL\Type\Definition\InputObjectType; /** - * @extends Source + * @extends Source */ class InputSource extends Source { public function getField(InputValueDefinitionNode|InputObjectField $field): InputFieldSource { - return new InputFieldSource($this->getManipulator(), $this->getType(), $field); + return new InputFieldSource($this->getManipulator(), $this, $field); } } diff --git a/packages/graphql/src/Builder/Sources/InterfaceFieldArgumentSource.php b/packages/graphql/src/Builder/Sources/InterfaceFieldArgumentSource.php index 1fe949168..5eda800cd 100644 --- a/packages/graphql/src/Builder/Sources/InterfaceFieldArgumentSource.php +++ b/packages/graphql/src/Builder/Sources/InterfaceFieldArgumentSource.php @@ -16,39 +16,35 @@ use LastDragon_ru\LaraASP\GraphQL\Utils\AstManipulator; /** - * @extends Source + * @extends Source */ class InterfaceFieldArgumentSource extends Source { use FieldArgument; public function __construct( AstManipulator $manipulator, - private InterfaceTypeDefinitionNode|InterfaceType $object, - private FieldDefinitionNode|FieldDefinition $field, + InterfaceFieldSource $parent, private InputValueDefinitionNode|Argument $argument, ) { - parent::__construct($manipulator, $argument instanceof Argument ? $argument->getType() : $argument->type); + parent::__construct( + $manipulator, + $argument instanceof Argument ? $argument->getType() : $argument->type, + $parent, + ); } // // ========================================================================= public function getObject(): InterfaceTypeDefinitionNode|InterfaceType { - return $this->object; + return $this->getParent()->getObject(); } public function getField(): FieldDefinition|FieldDefinitionNode { - return $this->field; + return $this->getParent()->getField(); } public function getArgument(): InputValueDefinitionNode|Argument { return $this->argument; } // - - // - // ================================================================================================================= - public function getParent(): InterfaceFieldSource { - return new InterfaceFieldSource($this->getManipulator(), $this->getObject(), $this->getField()); - } - // } diff --git a/packages/graphql/src/Builder/Sources/InterfaceFieldSource.php b/packages/graphql/src/Builder/Sources/InterfaceFieldSource.php index 5a7235c11..1e10a7dd9 100644 --- a/packages/graphql/src/Builder/Sources/InterfaceFieldSource.php +++ b/packages/graphql/src/Builder/Sources/InterfaceFieldSource.php @@ -16,23 +16,27 @@ use LastDragon_ru\LaraASP\GraphQL\Utils\AstManipulator; /** - * @extends Source + * @extends Source */ class InterfaceFieldSource extends Source { use Field; public function __construct( AstManipulator $manipulator, - private InterfaceTypeDefinitionNode|InterfaceType $object, + InterfaceSource $parent, private FieldDefinitionNode|FieldDefinition $field, ) { - parent::__construct($manipulator, $field instanceof FieldDefinition ? $field->getType() : $field->type); + parent::__construct( + $manipulator, + $field instanceof FieldDefinition ? $field->getType() : $field->type, + $parent, + ); } // // ========================================================================= public function getObject(): InterfaceTypeDefinitionNode|InterfaceType { - return $this->object; + return $this->getParent()->getType(); } public function getField(): FieldDefinition|FieldDefinitionNode { @@ -42,17 +46,8 @@ public function getField(): FieldDefinition|FieldDefinitionNode { // // ================================================================================================================= - public function getParent(): InterfaceSource { - return new InterfaceSource($this->getManipulator(), $this->getObject()); - } - public function getArgument(InputValueDefinitionNode|Argument $argument): InterfaceFieldArgumentSource { - return new InterfaceFieldArgumentSource( - $this->getManipulator(), - $this->getObject(), - $this->getField(), - $argument, - ); + return new InterfaceFieldArgumentSource($this->getManipulator(), $this, $argument); } // } diff --git a/packages/graphql/src/Builder/Sources/InterfaceSource.php b/packages/graphql/src/Builder/Sources/InterfaceSource.php index 600d528bc..dae936201 100644 --- a/packages/graphql/src/Builder/Sources/InterfaceSource.php +++ b/packages/graphql/src/Builder/Sources/InterfaceSource.php @@ -8,10 +8,10 @@ use GraphQL\Type\Definition\InterfaceType; /** - * @extends Source + * @extends Source */ class InterfaceSource extends Source { public function getField(FieldDefinitionNode|FieldDefinition $field): InterfaceFieldSource { - return new InterfaceFieldSource($this->getManipulator(), $this->getType(), $field); + return new InterfaceFieldSource($this->getManipulator(), $this, $field); } } diff --git a/packages/graphql/src/Builder/Sources/ObjectFieldArgumentSource.php b/packages/graphql/src/Builder/Sources/ObjectFieldArgumentSource.php index ac7f18f5f..f6f4f8f49 100644 --- a/packages/graphql/src/Builder/Sources/ObjectFieldArgumentSource.php +++ b/packages/graphql/src/Builder/Sources/ObjectFieldArgumentSource.php @@ -16,39 +16,35 @@ use LastDragon_ru\LaraASP\GraphQL\Utils\AstManipulator; /** - * @extends Source + * @extends Source */ class ObjectFieldArgumentSource extends Source { use FieldArgument; public function __construct( AstManipulator $manipulator, - private ObjectTypeDefinitionNode|ObjectType $object, - private FieldDefinitionNode|FieldDefinition $field, + ObjectFieldSource $parent, private InputValueDefinitionNode|Argument $argument, ) { - parent::__construct($manipulator, $argument instanceof Argument ? $argument->getType() : $argument->type); + parent::__construct( + $manipulator, + $argument instanceof Argument ? $argument->getType() : $argument->type, + $parent, + ); } // // ========================================================================= public function getObject(): ObjectTypeDefinitionNode|ObjectType { - return $this->object; + return $this->getParent()->getObject(); } public function getField(): FieldDefinition|FieldDefinitionNode { - return $this->field; + return $this->getParent()->getField(); } public function getArgument(): InputValueDefinitionNode|Argument { return $this->argument; } // - - // - // ================================================================================================================= - public function getParent(): ObjectFieldSource { - return new ObjectFieldSource($this->getManipulator(), $this->getObject(), $this->getField()); - } - // } diff --git a/packages/graphql/src/Builder/Sources/ObjectFieldSource.php b/packages/graphql/src/Builder/Sources/ObjectFieldSource.php index 3a85ec2a2..e5c22b09f 100644 --- a/packages/graphql/src/Builder/Sources/ObjectFieldSource.php +++ b/packages/graphql/src/Builder/Sources/ObjectFieldSource.php @@ -16,23 +16,27 @@ use LastDragon_ru\LaraASP\GraphQL\Utils\AstManipulator; /** - * @extends Source + * @extends Source */ class ObjectFieldSource extends Source { use Field; public function __construct( AstManipulator $manipulator, - private ObjectTypeDefinitionNode|ObjectType $object, + ObjectSource $parent, private FieldDefinitionNode|FieldDefinition $field, ) { - parent::__construct($manipulator, $field instanceof FieldDefinition ? $field->getType() : $field->type); + parent::__construct( + $manipulator, + $field instanceof FieldDefinition ? $field->getType() : $field->type, + $parent, + ); } // // ========================================================================= public function getObject(): ObjectTypeDefinitionNode|ObjectType { - return $this->object; + return $this->getParent()->getType(); } public function getField(): FieldDefinition|FieldDefinitionNode { @@ -42,12 +46,8 @@ public function getField(): FieldDefinition|FieldDefinitionNode { // // ================================================================================================================= - public function getParent(): ObjectSource { - return new ObjectSource($this->getManipulator(), $this->getObject()); - } - public function getArgument(InputValueDefinitionNode|Argument $argument): ObjectFieldArgumentSource { - return new ObjectFieldArgumentSource($this->getManipulator(), $this->getObject(), $this->getField(), $argument); + return new ObjectFieldArgumentSource($this->getManipulator(), $this, $argument); } // } diff --git a/packages/graphql/src/Builder/Sources/ObjectSource.php b/packages/graphql/src/Builder/Sources/ObjectSource.php index 69e078d53..dfcbaebf6 100644 --- a/packages/graphql/src/Builder/Sources/ObjectSource.php +++ b/packages/graphql/src/Builder/Sources/ObjectSource.php @@ -8,10 +8,10 @@ use GraphQL\Type\Definition\ObjectType; /** - * @extends Source + * @extends Source */ class ObjectSource extends Source { public function getField(FieldDefinitionNode|FieldDefinition $field): ObjectFieldSource { - return new ObjectFieldSource($this->getManipulator(), $this->getType(), $field); + return new ObjectFieldSource($this->getManipulator(), $this, $field); } } diff --git a/packages/graphql/src/Builder/Sources/Source.php b/packages/graphql/src/Builder/Sources/Source.php index 26634c9fc..be989267a 100644 --- a/packages/graphql/src/Builder/Sources/Source.php +++ b/packages/graphql/src/Builder/Sources/Source.php @@ -14,14 +14,17 @@ /** * @template TType of (TypeDefinitionNode&Node)|NamedTypeNode|ListTypeNode|NonNullTypeNode|Type + * @template TParent of TypeSource|null */ class Source implements TypeSource { /** - * @param TType $type + * @param TType $type + * @param TParent $parent */ public function __construct( private AstManipulator $manipulator, private TypeDefinitionNode|Node|Type $type, + private TypeSource|null $parent = null, ) { // empty } @@ -31,6 +34,13 @@ public function __construct( protected function getManipulator(): AstManipulator { return $this->manipulator; } + + /** + * @return TParent + */ + public function getParent(): ?TypeSource { + return $this->parent; + } // // diff --git a/packages/graphql/src/Builder/Traits/WithSource.php b/packages/graphql/src/Builder/Traits/WithSource.php index b2c285d8b..ee632a68e 100644 --- a/packages/graphql/src/Builder/Traits/WithSource.php +++ b/packages/graphql/src/Builder/Traits/WithSource.php @@ -8,29 +8,45 @@ use GraphQL\Language\AST\ObjectTypeDefinitionNode; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\InterfaceFieldArgumentSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\InterfaceFieldSource; +use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\InterfaceSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectFieldArgumentSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectFieldSource; +use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectSource; use LastDragon_ru\LaraASP\GraphQL\Utils\AstManipulator; trait WithSource { + /** + * @return ($type is InterfaceTypeDefinitionNode ? InterfaceSource : ObjectSource) + */ + protected function getTypeSource( + AstManipulator $manipulator, + ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode $type, + ): InterfaceSource|ObjectSource { + return $type instanceof InterfaceTypeDefinitionNode + ? new InterfaceSource($manipulator, $type) + : new ObjectSource($manipulator, $type); + } + + /** + * @return ($type is InterfaceTypeDefinitionNode ? InterfaceFieldSource : ObjectFieldSource) + */ protected function getFieldSource( AstManipulator $manipulator, ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode $type, FieldDefinitionNode $field, ): ObjectFieldSource|InterfaceFieldSource { - return $type instanceof InterfaceTypeDefinitionNode - ? new InterfaceFieldSource($manipulator, $type, $field) - : new ObjectFieldSource($manipulator, $type, $field); + return $this->getTypeSource($manipulator, $type)->getField($field); } + /** + * @return ($type is InterfaceTypeDefinitionNode ? InterfaceFieldArgumentSource : ObjectFieldArgumentSource) + */ protected function getFieldArgumentSource( AstManipulator $manipulator, ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode $type, FieldDefinitionNode $field, InputValueDefinitionNode $argument, ): ObjectFieldArgumentSource|InterfaceFieldArgumentSource { - return $type instanceof InterfaceTypeDefinitionNode - ? new InterfaceFieldArgumentSource($manipulator, $type, $field, $argument) - : new ObjectFieldArgumentSource($manipulator, $type, $field, $argument); + return $this->getFieldSource($manipulator, $type, $field)->getArgument($argument); } } diff --git a/packages/graphql/src/Stream/Directives/Directive.php b/packages/graphql/src/Stream/Directives/Directive.php index ed1e7747c..198701649 100644 --- a/packages/graphql/src/Stream/Directives/Directive.php +++ b/packages/graphql/src/Stream/Directives/Directive.php @@ -24,6 +24,7 @@ use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\InterfaceFieldSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectFieldArgumentSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectFieldSource; +use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Traits\WithManipulator; use LastDragon_ru\LaraASP\GraphQL\Builder\Traits\WithSource; use LastDragon_ru\LaraASP\GraphQL\Package; @@ -436,7 +437,7 @@ public function resolveField(FieldValue $fieldValue): callable { return function (mixed $root, array $args, GraphQLContext $context, ResolveInfo $info): StreamValue { // Offset $manipulator = $this->getAstManipulator(new DocumentAST()); - $source = new ObjectFieldSource($manipulator, $info->parentType, $info->fieldDefinition); + $source = (new ObjectSource($manipulator, $info->parentType))->getField($info->fieldDefinition); $offset = $this->getFieldValue(StreamOffsetDirective::class, $manipulator, $source, $info, $args); // Builder diff --git a/packages/graphql/src/Stream/Directives/DirectiveTest.php b/packages/graphql/src/Stream/Directives/DirectiveTest.php index 269bdbebc..c3acbce79 100644 --- a/packages/graphql/src/Stream/Directives/DirectiveTest.php +++ b/packages/graphql/src/Stream/Directives/DirectiveTest.php @@ -577,11 +577,11 @@ public function testGetResolverExplicit(array|null $expected, string $arguments) ]); $field = Parser::fieldDefinition('test: String'); - $source = new ObjectFieldSource( + $object = new ObjectSource( Mockery::mock(AstManipulator::class)->makePartial(), new ObjectType(['name' => 'Car', 'fields' => []]), - $field, ); + $source = $object->getField($field); $directive = Mockery::mock(Directive::class); $directive->shouldAllowMockingProtectedMethods(); $directive->makePartial(); @@ -1131,9 +1131,7 @@ public function getFieldArgumentValue(ResolveInfo $info, mixed $value): mixed { $value = $directive->getFieldValue( DirectiveTest_Directive::class, $manipulator, - new ObjectFieldSource( - $manipulator, - $object, + (new ObjectSource($manipulator, $object))->getField( Parser::fieldDefinition( 'test(d: Int @markerA, b: String @markerA @deprecated): String', ), @@ -1148,9 +1146,7 @@ public function getFieldArgumentValue(ResolveInfo $info, mixed $value): mixed { $value = $directive->getFieldValue( DirectiveTest_Directive::class, $manipulator, - new ObjectFieldSource( - $manipulator, - $object, + (new ObjectSource($manipulator, $object))->getField( Parser::fieldDefinition( 'test(a: String @markerA @deprecated, b: Int @markerB): String', ), @@ -1205,9 +1201,7 @@ public function getFieldValue( $directive->getFieldValue( DirectiveTest_Directive::class, $manipulator, - new ObjectFieldSource( - $manipulator, - $object, + (new ObjectSource($manipulator, $object))->getField( Parser::fieldDefinition( 'test(a: Int, b: String): String', ), @@ -1261,9 +1255,7 @@ public function getFieldValue( $directive->getFieldValue( $marker::class, $manipulator, - new ObjectFieldSource( - $manipulator, - $object, + (new ObjectSource($manipulator, $object))->getField( Parser::fieldDefinition( 'test(a: Int @marker, b: String @marker @deprecated): String', ), @@ -1523,11 +1515,10 @@ static function (): void { public static function dataProviderGetBuilderInfo(): array { $class = new DirectiveTest_Model(); $factory = static function (AstManipulator $manipulator): ObjectFieldSource { - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'ObjectA', 'fields' => []]), - Parser::fieldDefinition('test: String'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'ObjectA', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('test: String'), + ); }; return [ @@ -1589,11 +1580,10 @@ static function () use ($class): stdClass|self { */ public static function dataProviderGetBuilderInfoScoutBuilder(): array { $factory = static function (AstManipulator $manipulator): ObjectFieldSource { - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'ObjectA', 'fields' => []]), - Parser::fieldDefinition('test(search: String! @search): String'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'ObjectA', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('test(search: String! @search): String'), + ); }; return [ @@ -1682,11 +1672,10 @@ public static function dataProviderGetArgKey(): array { } GRAPHQL; $factory = static function (AstManipulator $manipulator): ObjectFieldSource { - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'ObjectA', 'fields' => []]), - Parser::fieldDefinition('test: String'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'ObjectA', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('test: String'), + ); }; return [ @@ -1707,11 +1696,10 @@ public static function dataProviderGetArgKey(): array { $schema, Parser::directive('@stream'), static function (AstManipulator $manipulator): ObjectFieldSource { - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'Object', 'fields' => []]), - Parser::fieldDefinition('test: ObjectA'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'Object', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('test: ObjectA'), + ); }, ], 'Invalid type' => [ @@ -1719,11 +1707,10 @@ static function (AstManipulator $manipulator): ObjectFieldSource { $schema, Parser::directive('@stream'), static function (AstManipulator $manipulator): ObjectFieldSource { - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'ObjectA', 'fields' => []]), - Parser::fieldDefinition('test: ObjectB'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'ObjectA', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('test: ObjectB'), + ); }, ], 'Converted' => [ @@ -1731,11 +1718,10 @@ static function (AstManipulator $manipulator): ObjectFieldSource { $schema, Parser::directive('@stream'), static function (AstManipulator $manipulator): ObjectFieldSource { - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'ObjectB', 'fields' => []]), - Parser::fieldDefinition('test: ObjectAsStream'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'ObjectB', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('test: ObjectAsStream'), + ); }, ], '@rename' => [ @@ -1743,11 +1729,10 @@ static function (AstManipulator $manipulator): ObjectFieldSource { $schema, Parser::directive('@stream'), static function (AstManipulator $manipulator): ObjectFieldSource { - return new ObjectFieldSource( - $manipulator, - new ObjectType(['name' => 'ObjectB', 'fields' => []]), - Parser::fieldDefinition('test: ObjectC'), - ); + return (new ObjectSource($manipulator, new ObjectType(['name' => 'ObjectB', 'fields' => []]))) + ->getField( + Parser::fieldDefinition('test: ObjectC'), + ); }, ], ];