diff --git a/CHANGELOG.md b/CHANGELOG.md index 9179cab..2cb6b99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ ## [Unreleased] +## [0.2.2] - 2024-01-26 +### Added +- Having types and fields +- GroupType instead of anonymous declaration in GroupField +- UnionType + +### Changed +- Depracated GroupField::FIELD_COLUMN constant, use GroupType::FIELD_COLUMN instead + ## [0.2.1] - 2023-07-03 ### Added - Null and NotNull where comparators @@ -25,7 +34,8 @@ - Webonyx driver - Webonyx schema transformer -[Unreleased]: https://github.com/efabrica-team/graphql/compare/0.2.1...main +[Unreleased]: https://github.com/efabrica-team/graphql/compare/0.2.2...main +[0.2.2]: https://github.com/efabrica-team/graphql/compare/0.2.1...0.2.2 [0.2.1]: https://github.com/efabrica-team/graphql/compare/0.2.0...0.2.1 [0.2.0]: https://github.com/efabrica-team/graphql/compare/0.1.0...0.2.0 [0.1.0]: https://github.com/efabrica-team/graphql/compare/0.0.0...0.1.0 diff --git a/src/Schema/Custom/Arguments/ConditionsArgument.php b/src/Schema/Custom/Arguments/ConditionsArgument.php index 61f9ba9..0e91660 100644 --- a/src/Schema/Custom/Arguments/ConditionsArgument.php +++ b/src/Schema/Custom/Arguments/ConditionsArgument.php @@ -3,6 +3,8 @@ namespace Efabrica\GraphQL\Schema\Custom\Arguments; use Efabrica\GraphQL\Schema\Custom\Fields\GroupField; +use Efabrica\GraphQL\Schema\Custom\Fields\HavingAndField; +use Efabrica\GraphQL\Schema\Custom\Fields\HavingOrField; use Efabrica\GraphQL\Schema\Custom\Fields\WhereAndField; use Efabrica\GraphQL\Schema\Custom\Fields\WhereOrField; use Efabrica\GraphQL\Schema\Definition\Arguments\FieldArgument; @@ -20,6 +22,8 @@ public function __construct() ->setFields([ new WhereAndField(), new WhereOrField(), + new HavingAndField(), + new HavingOrField(), new GroupField(), ]) ); diff --git a/src/Schema/Custom/Fields/GroupField.php b/src/Schema/Custom/Fields/GroupField.php index 3190eac..a70ed35 100644 --- a/src/Schema/Custom/Fields/GroupField.php +++ b/src/Schema/Custom/Fields/GroupField.php @@ -2,24 +2,24 @@ namespace Efabrica\GraphQL\Schema\Custom\Fields; +use Efabrica\GraphQL\Schema\Custom\Types\GroupType; use Efabrica\GraphQL\Schema\Definition\Fields\InputObjectField; -use Efabrica\GraphQL\Schema\Definition\Types\InputObjectType; -use Efabrica\GraphQL\Schema\Definition\Types\Scalar\StringType; class GroupField extends InputObjectField { public const NAME = 'group'; - public const FIELD_COLUMN = 'column'; + /** + * TODO: remove in 0.3.0 + * @deprecated Use GroupType::FIELD_COLUMN instead + */ + public const FIELD_COLUMN = GroupType::FIELD_COLUMN; public function __construct() { parent::__construct( self::NAME, - (new InputObjectType('group_type')) - ->setFields([ - new InputObjectField(self::FIELD_COLUMN, new StringType()), - ]) + new GroupType() ); $this->setMulti() ->setNullable(); diff --git a/src/Schema/Custom/Fields/HavingAndField.php b/src/Schema/Custom/Fields/HavingAndField.php new file mode 100644 index 0000000..80a0054 --- /dev/null +++ b/src/Schema/Custom/Fields/HavingAndField.php @@ -0,0 +1,22 @@ +setMulti() + ->setNullable(); + } +} diff --git a/src/Schema/Custom/Fields/HavingOrField.php b/src/Schema/Custom/Fields/HavingOrField.php new file mode 100644 index 0000000..6085761 --- /dev/null +++ b/src/Schema/Custom/Fields/HavingOrField.php @@ -0,0 +1,22 @@ +setMulti() + ->setNullable(); + } +} diff --git a/src/Schema/Custom/Fields/WhereAndField.php b/src/Schema/Custom/Fields/WhereAndField.php index 42298cf..19d66d0 100644 --- a/src/Schema/Custom/Fields/WhereAndField.php +++ b/src/Schema/Custom/Fields/WhereAndField.php @@ -16,8 +16,7 @@ public function __construct() new WhereType() ); - $this->setName(self::NAME) - ->setMulti() + $this->setMulti() ->setNullable(); } } diff --git a/src/Schema/Custom/Fields/WhereOrField.php b/src/Schema/Custom/Fields/WhereOrField.php index 1d1b11f..d77229f 100644 --- a/src/Schema/Custom/Fields/WhereOrField.php +++ b/src/Schema/Custom/Fields/WhereOrField.php @@ -16,8 +16,7 @@ public function __construct() new WhereType() ); - $this->setName(self::NAME) - ->setMulti() + $this->setMulti() ->setNullable(); } } diff --git a/src/Schema/Custom/Types/GroupType.php b/src/Schema/Custom/Types/GroupType.php new file mode 100644 index 0000000..3ad8bbe --- /dev/null +++ b/src/Schema/Custom/Types/GroupType.php @@ -0,0 +1,23 @@ +setFields(fn() => [ + new InputObjectField(self::FIELD_COLUMN, new StringType()), + ]); + } +} diff --git a/src/Schema/Custom/Types/HavingType.php b/src/Schema/Custom/Types/HavingType.php new file mode 100644 index 0000000..046acb0 --- /dev/null +++ b/src/Schema/Custom/Types/HavingType.php @@ -0,0 +1,35 @@ +setFields(fn() => [ + new HavingAndField(), + new HavingOrField(), + (new InputObjectField(self::FIELD_COLUMN, new StringType())) + ->setNullable(), + (new InputObjectField(self::FIELD_VALUE, new StringType())) + ->setMulti() + ->setNullable(), + (new InputObjectField(self::FIELD_COMPARATOR, new WhereComparatorEnum())) + ->setDefaultValue(WhereComparatorEnum::EQUAL), + ]); + } +} diff --git a/src/Schema/Definition/Types/UnionType.php b/src/Schema/Definition/Types/UnionType.php new file mode 100644 index 0000000..eea6aeb --- /dev/null +++ b/src/Schema/Definition/Types/UnionType.php @@ -0,0 +1,65 @@ +objectTypesCallback === null) { + return $this->objectTypes; + } + + $objectTypes = []; + foreach (call_user_func($this->objectTypesCallback) as $type) { + $objectTypes[$type->getName()] = $type; + } + + return array_merge($objectTypes, $this->objectTypes); + } + + public function addObjectType(ObjectType $objectType): self + { + $this->objectTypes[$objectType->getName()] = $objectType; + return $this; + } + + /** + * @param ObjectType[]|callable $objectTypes + */ + public function setObjectTypes($objectTypes): self + { + if (is_callable($objectTypes)) { + $this->objectTypesCallback = $objectTypes; + } else { + $this->objectTypes = []; + foreach ($objectTypes as $objectType) { + $this->objectTypes[$objectType->getName()] = $objectType; + } + } + + return $this; + } + + public function getResolveType(): callable + { + return $this->resolveType; + } + + public function setResolveType(callable $resolveType): self + { + $this->resolveType = $resolveType; + return $this; + } +} diff --git a/src/Schema/Transformers/WebonyxSchemaTransformer.php b/src/Schema/Transformers/WebonyxSchemaTransformer.php index 13f8cbf..1a49b64 100644 --- a/src/Schema/Transformers/WebonyxSchemaTransformer.php +++ b/src/Schema/Transformers/WebonyxSchemaTransformer.php @@ -18,11 +18,13 @@ use Efabrica\GraphQL\Schema\Definition\Types\Scalar\ScalarType; use Efabrica\GraphQL\Schema\Definition\Types\Scalar\StringType; use Efabrica\GraphQL\Schema\Definition\Types\Type; +use Efabrica\GraphQL\Schema\Definition\Types\UnionType; use GraphQL\Type\Definition\EnumType as WebonyxEnumType; use GraphQL\Type\Definition\InputObjectType as WebonyxInputObjectType; use GraphQL\Type\Definition\ObjectType as WebonyxObjectType; use GraphQL\Type\Definition\ResolveInfo as WebonyxResolveInfo; use GraphQL\Type\Definition\Type as WebonyxType; +use GraphQL\Type\Definition\UnionType as WebonyxUnionType; use GraphQL\Type\Schema as WebonyxSchema; use GraphQL\Type\SchemaConfig as WebonyxSchemaConfig; use Throwable; @@ -89,6 +91,25 @@ private function transformType(Type $type): WebonyxType 'description' => $type->getDescription(), 'values' => $values, ]); + } elseif ($type instanceof UnionType) { + $transformedType = new WebonyxUnionType([ + 'name' => $type->getName(), + 'description' => $type->getDescription(), + 'types' => function () use ($type) { + $objectTypes = []; + foreach ($type->getObjectTypes() as $objectType) { + $objectTypes[] = $this->transformType($objectType); + } + return $objectTypes; + }, + 'resolveType' => function($value) use ($type): WebonyxObjectType { + $objectType = $this->transformType(call_user_func($type->getResolveType(), $value)); + if (!$objectType instanceof WebonyxObjectType) { + throw new SchemaTransformerException('Union resolveType must be instance of "' . WebonyxObjectType::class . '".'); + } + return $objectType; + }, + ]); } elseif ($type instanceof InputObjectType) { $transformedType = new WebonyxInputObjectType([ 'name' => $type->getName(),