diff --git a/packages/graphql/README.md b/packages/graphql/README.md index 3bf468cfd..7986a2f7a 100644 --- a/packages/graphql/README.md +++ b/packages/graphql/README.md @@ -91,7 +91,7 @@ Converts scalar into GraphQL Type. Similar to Lighthouse's `@scalar` directive, > > ```graphql > scalar JsonString -> @scalar( +> @type( > class: "LastDragon_ru\\LaraASP\\GraphQL\\Scalars\\JsonStringType" > ) > ``` diff --git a/packages/graphql/UPGRADE.md b/packages/graphql/UPGRADE.md index 08c8e50c9..6af134c1a 100644 --- a/packages/graphql/UPGRADE.md +++ b/packages/graphql/UPGRADE.md @@ -33,6 +33,12 @@ Please also see [changelog](https://github.com/LastDragon-ru/lara-asp/releases) > > Maybe a good idea to add test (at least) with `LastDragon_ru\LaraASP\GraphQL\Testing\GraphQLAssertions::assertGraphQLSchemaEquals()` assertion before the upgrade 🤗 +# Upgrade from v6 + +* [ ] The `\LastDragon_ru\LaraASP\GraphQL\Scalars\JsonStringType` is not implement `\LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeDefinition` anymore. To add the scalar into the Schema, you can use `@type`/`@scalar` directive, or create a custom implementation of `TypeDefinition` contract to use with `Builder`/`Manipulator`. + +* [ ] `\LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeDefinition::getTypeDefinition()` return type changed. + # Upgrade from v5 ## General diff --git a/packages/graphql/src/Builder/Contracts/TypeDefinition.php b/packages/graphql/src/Builder/Contracts/TypeDefinition.php index 52ce8f868..261972d38 100644 --- a/packages/graphql/src/Builder/Contracts/TypeDefinition.php +++ b/packages/graphql/src/Builder/Contracts/TypeDefinition.php @@ -7,7 +7,7 @@ use GraphQL\Type\Definition\NamedType; use GraphQL\Type\Definition\Type; use LastDragon_ru\LaraASP\GraphQL\Builder\Manipulator; -use LastDragon_ru\LaraASP\GraphQL\Utils\TypeReference; +use UnitEnum; interface TypeDefinition { /** @@ -18,15 +18,12 @@ public function getTypeName(TypeSource $source, Context $context): string; /** * Returns the type definition for given Source if possible. The name must be equal to `$name`. * - * @see TypeReference - * - * @return (TypeDefinitionNode&Node)|(Type&NamedType)|null Returning {@see Type} is deprecated, please use - * {@see TypeReference} instead. + * @return (TypeDefinitionNode&Node)|class-string<(Type&NamedType)|UnitEnum>|null */ public function getTypeDefinition( Manipulator $manipulator, TypeSource $source, Context $context, string $name, - ): TypeDefinitionNode|Type|null; + ): TypeDefinitionNode|string|null; } diff --git a/packages/graphql/src/Builder/Manipulator.php b/packages/graphql/src/Builder/Manipulator.php index 0ae5bb3c3..b28e4d493 100644 --- a/packages/graphql/src/Builder/Manipulator.php +++ b/packages/graphql/src/Builder/Manipulator.php @@ -23,7 +23,6 @@ use LastDragon_ru\LaraASP\GraphQL\Builder\Context\HandlerContextOperators; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Operator; -use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeDefinition; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeProvider; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Exceptions\FakeTypeDefinitionIsNotFake; @@ -35,7 +34,6 @@ use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\InterfaceSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\Source; -use LastDragon_ru\LaraASP\GraphQL\Package; use LastDragon_ru\LaraASP\GraphQL\Utils\AstManipulator; use LastDragon_ru\LaraASP\GraphQL\Utils\TypeReference; use Nuwave\Lighthouse\Schema\DirectiveLocator; @@ -46,7 +44,7 @@ use function array_unshift; use function count; use function implode; -use function trigger_deprecation; +use function is_string; class Manipulator extends AstManipulator implements TypeProvider { // @@ -67,21 +65,14 @@ public function getType(string $definition, TypeSource $source, Context $context // Create new $node = $instance->getTypeDefinition($this, $source, $context, $name); - if ($node instanceof Type && !($node instanceof TypeReference)) { - trigger_deprecation( - Package::Name, - '6.3.0', - 'Returning `%s` from `%s` is deprecated, please use `%s` instead.', - Type::class, - TypeDefinition::class.'::getTypeDefinition()', - TypeReference::class, - ); - } - if (!$node) { throw new TypeDefinitionImpossibleToCreateType($definition, $source, $context); } + if (is_string($node)) { + $node = new TypeReference($name, $node); + } + if ($name !== $this->getName($node)) { throw new TypeDefinitionInvalidTypeName($definition, $name, $this->getName($node), $context); } diff --git a/packages/graphql/src/Builder/Types/InputObject.php b/packages/graphql/src/Builder/Types/InputObject.php index 7a84019d3..8c4f324e0 100644 --- a/packages/graphql/src/Builder/Types/InputObject.php +++ b/packages/graphql/src/Builder/Types/InputObject.php @@ -53,16 +53,13 @@ abstract protected function getDescription( Context $context, ): string; - /** - * @inheritDoc - */ #[Override] public function getTypeDefinition( Manipulator $manipulator, TypeSource $source, Context $context, string $name, - ): TypeDefinitionNode|Type|null { + ): TypeDefinitionNode|string|null { // Source? $source = $manipulator->getTypeSource($source->getTypeDefinition()); diff --git a/packages/graphql/src/Scalars/JsonStringType.php b/packages/graphql/src/Scalars/JsonStringType.php index b8e28d642..859800a6c 100644 --- a/packages/graphql/src/Scalars/JsonStringType.php +++ b/packages/graphql/src/Scalars/JsonStringType.php @@ -8,22 +8,15 @@ use GraphQL\Language\AST\Node; use GraphQL\Language\AST\NodeKind; use GraphQL\Language\AST\StringValueNode; -use GraphQL\Language\AST\TypeDefinitionNode; use GraphQL\Type\Definition\StringType; -use GraphQL\Type\Definition\Type; use GraphQL\Utils\Utils; -use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; -use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeDefinition; -use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeSource; -use LastDragon_ru\LaraASP\GraphQL\Builder\Manipulator; -use LastDragon_ru\LaraASP\GraphQL\Utils\TypeReference; use Override; use function is_string; use function json_validate; use function sprintf; -class JsonStringType extends StringType implements TypeDefinition { +class JsonStringType extends StringType { public string $name = 'JsonString'; public ?string $description = 'Represents JSON string.'; @@ -83,22 +76,4 @@ protected function validate(mixed $value, string $error): string { return $value; } // - - // - // ========================================================================= - #[Override] - public function getTypeName(TypeSource $source, Context $context): string { - return $this->name(); - } - - #[Override] - public function getTypeDefinition( - Manipulator $manipulator, - TypeSource $source, - Context $context, - string $name, - ): TypeDefinitionNode|Type|null { - return new TypeReference($name, self::class); - } - // } diff --git a/packages/graphql/src/SearchBy/Directives/DirectiveTest.php b/packages/graphql/src/SearchBy/Directives/DirectiveTest.php index 36cb7b47b..2fe05f42b 100644 --- a/packages/graphql/src/SearchBy/Directives/DirectiveTest.php +++ b/packages/graphql/src/SearchBy/Directives/DirectiveTest.php @@ -4,7 +4,6 @@ use Closure; use Exception; -use GraphQL\Language\AST\Node; use GraphQL\Language\AST\TypeDefinitionNode; use GraphQL\Language\Parser; use GraphQL\Type\Definition\EnumType; @@ -1622,7 +1621,7 @@ public function getTypeDefinition( TypeSource $source, Context $context, string $name, - ): TypeDefinitionNode&Node { + ): TypeDefinitionNode|string|null { return Parser::inputObjectTypeDefinition( <<isObject()) { return null; diff --git a/packages/graphql/src/SearchBy/Types/Enumeration.php b/packages/graphql/src/SearchBy/Types/Enumeration.php index 0be834119..8e966e388 100644 --- a/packages/graphql/src/SearchBy/Types/Enumeration.php +++ b/packages/graphql/src/SearchBy/Types/Enumeration.php @@ -4,7 +4,6 @@ use GraphQL\Language\AST\TypeDefinitionNode; use GraphQL\Language\Parser; -use GraphQL\Type\Definition\Type; use LastDragon_ru\LaraASP\GraphQL\Builder\Context\HandlerContextBuilderInfo; use LastDragon_ru\LaraASP\GraphQL\Builder\Context\HandlerContextOperators; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; @@ -32,16 +31,13 @@ public function getTypeName(TypeSource $source, Context $context): string { return "{$directiveName}{$builderName}Enum{$typeName}{$nullable}"; } - /** - * @inheritDoc - */ #[Override] public function getTypeDefinition( Manipulator $manipulator, TypeSource $source, Context $context, string $name, - ): TypeDefinitionNode|Type|null { + ): TypeDefinitionNode|string|null { // Enum? if (!$source->isEnum()) { return null; diff --git a/packages/graphql/src/SearchBy/Types/Flag.php b/packages/graphql/src/SearchBy/Types/Flag.php index f8860a113..895f93406 100644 --- a/packages/graphql/src/SearchBy/Types/Flag.php +++ b/packages/graphql/src/SearchBy/Types/Flag.php @@ -3,14 +3,12 @@ namespace LastDragon_ru\LaraASP\GraphQL\SearchBy\Types; use GraphQL\Language\AST\TypeDefinitionNode; -use GraphQL\Type\Definition\Type; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeDefinition; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Enums\Flag as FlagEnum; use LastDragon_ru\LaraASP\GraphQL\Builder\Manipulator; use LastDragon_ru\LaraASP\GraphQL\SearchBy\Directives\Directive; -use LastDragon_ru\LaraASP\GraphQL\Utils\TypeReference; use Override; class Flag implements TypeDefinition { @@ -29,7 +27,7 @@ public function getTypeDefinition( TypeSource $source, Context $context, string $name, - ): TypeDefinitionNode|Type|null { - return new TypeReference($name, FlagEnum::class); + ): TypeDefinitionNode|string|null { + return FlagEnum::class; } } diff --git a/packages/graphql/src/SearchBy/Types/Range.php b/packages/graphql/src/SearchBy/Types/Range.php index e35c7cdb0..33c0bef34 100644 --- a/packages/graphql/src/SearchBy/Types/Range.php +++ b/packages/graphql/src/SearchBy/Types/Range.php @@ -4,7 +4,6 @@ use GraphQL\Language\AST\TypeDefinitionNode; use GraphQL\Language\Parser; -use GraphQL\Type\Definition\Type; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeDefinition; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeSource; @@ -31,7 +30,7 @@ public function getTypeDefinition( TypeSource $source, Context $context, string $name, - ): TypeDefinitionNode|Type|null { + ): TypeDefinitionNode|string|null { return Parser::inputObjectTypeDefinition( <<isScalar()) { return null; diff --git a/packages/graphql/src/SortBy/Directives/DirectiveTest/Implicit.expected.graphql b/packages/graphql/src/SortBy/Directives/DirectiveTest/Implicit.expected.graphql index 19386dcfe..76e14a553 100644 --- a/packages/graphql/src/SortBy/Directives/DirectiveTest/Implicit.expected.graphql +++ b/packages/graphql/src/SortBy/Directives/DirectiveTest/Implicit.expected.graphql @@ -523,7 +523,7 @@ pagination). """ scalar StreamOffset @type( - class: "LastDragon_ru\\LaraASP\\GraphQL\\Stream\\Types\\Offset" + class: "LastDragon_ru\\LaraASP\\GraphQL\\Stream\\Scalars\\Offset" ) type A { diff --git a/packages/graphql/src/SortBy/Types/Direction.php b/packages/graphql/src/SortBy/Types/Direction.php index 49b49f528..0fa835bda 100644 --- a/packages/graphql/src/SortBy/Types/Direction.php +++ b/packages/graphql/src/SortBy/Types/Direction.php @@ -3,14 +3,12 @@ namespace LastDragon_ru\LaraASP\GraphQL\SortBy\Types; use GraphQL\Language\AST\TypeDefinitionNode; -use GraphQL\Type\Definition\Type; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeDefinition; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Manipulator; use LastDragon_ru\LaraASP\GraphQL\SortBy\Directives\Directive; use LastDragon_ru\LaraASP\GraphQL\SortBy\Enums\Direction as DirectionEnum; -use LastDragon_ru\LaraASP\GraphQL\Utils\TypeReference; use Override; class Direction implements TypeDefinition { @@ -29,7 +27,7 @@ public function getTypeDefinition( TypeSource $source, Context $context, string $name, - ): TypeDefinitionNode|Type|null { - return new TypeReference($name, DirectionEnum::class); + ): TypeDefinitionNode|string|null { + return DirectionEnum::class; } } diff --git a/packages/graphql/src/SortBy/Types/Flag.php b/packages/graphql/src/SortBy/Types/Flag.php index cb8473b0f..aa2de62dc 100644 --- a/packages/graphql/src/SortBy/Types/Flag.php +++ b/packages/graphql/src/SortBy/Types/Flag.php @@ -3,14 +3,12 @@ namespace LastDragon_ru\LaraASP\GraphQL\SortBy\Types; use GraphQL\Language\AST\TypeDefinitionNode; -use GraphQL\Type\Definition\Type; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeDefinition; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Enums\Flag as FlagEnum; use LastDragon_ru\LaraASP\GraphQL\Builder\Manipulator; use LastDragon_ru\LaraASP\GraphQL\SortBy\Directives\Directive; -use LastDragon_ru\LaraASP\GraphQL\Utils\TypeReference; use Override; class Flag implements TypeDefinition { @@ -29,7 +27,7 @@ public function getTypeDefinition( TypeSource $source, Context $context, string $name, - ): TypeDefinitionNode|Type|null { - return new TypeReference($name, FlagEnum::class); + ): TypeDefinitionNode|string|null { + return FlagEnum::class; } } diff --git a/packages/graphql/src/Stream/Directives/DirectiveTest~schema-expected.graphql b/packages/graphql/src/Stream/Directives/DirectiveTest~schema-expected.graphql index 39acc84b2..bfa462a9f 100644 --- a/packages/graphql/src/Stream/Directives/DirectiveTest~schema-expected.graphql +++ b/packages/graphql/src/Stream/Directives/DirectiveTest~schema-expected.graphql @@ -303,7 +303,7 @@ pagination). """ scalar StreamOffset @type( - class: "LastDragon_ru\\LaraASP\\GraphQL\\Stream\\Types\\Offset" + class: "LastDragon_ru\\LaraASP\\GraphQL\\Stream\\Scalars\\Offset" ) type Query diff --git a/packages/graphql/src/Stream/Directives/DirectiveTest~scout-expected.graphql b/packages/graphql/src/Stream/Directives/DirectiveTest~scout-expected.graphql index 27d1d2046..df4bf13e3 100644 --- a/packages/graphql/src/Stream/Directives/DirectiveTest~scout-expected.graphql +++ b/packages/graphql/src/Stream/Directives/DirectiveTest~scout-expected.graphql @@ -232,7 +232,7 @@ pagination). """ scalar StreamOffset @type( - class: "LastDragon_ru\\LaraASP\\GraphQL\\Stream\\Types\\Offset" + class: "LastDragon_ru\\LaraASP\\GraphQL\\Stream\\Scalars\\Offset" ) type Query diff --git a/packages/graphql/src/Stream/Scalars/Offset.php b/packages/graphql/src/Stream/Scalars/Offset.php new file mode 100644 index 000000000..f57132d83 --- /dev/null +++ b/packages/graphql/src/Stream/Scalars/Offset.php @@ -0,0 +1,169 @@ + + // ========================================================================= + protected function getEncrypter(): StringEncrypter { + return Container::getInstance()->make(StringEncrypter::class); + } + + protected function getSerializer(): Serializer { + return Container::getInstance()->make(Serializer::class); + } + // + + // + // ========================================================================= + /** + * @return string|int<0, max> + */ + #[Override] + public function serialize(mixed $value): string|int { + $value = $this->validate($value, InvariantViolation::class); + + if ($value instanceof StreamOffset) { + $value = $this->getSerializer()->serialize($value, 'json'); + $value = $this->encrypt($value); + } + + return $value; + } + + /** + * @return StreamOffset|int<0, max> + */ + #[Override] + public function parseValue(mixed $value): StreamOffset|int { + if (is_string($value)) { + try { + $value = $this->decrypt($value); + $value = $this->getSerializer()->deserialize(StreamOffset::class, $value, 'json'); + } catch (Exception) { + throw new Error('The cursor is not valid.'); + } + } else { + $value = $this->validate($value, Error::class); + } + + return $value; + } + + /** + * @inheritDoc + * @return StreamOffset|int<0, max> + */ + #[Override] + public function parseLiteral(Node $valueNode, array $variables = null): StreamOffset|int { + $value = null; + + if ($valueNode instanceof StringValueNode) { + $value = $this->parseValue($valueNode->value); + } elseif ($valueNode instanceof IntValueNode) { + $value = filter_var($valueNode->value, FILTER_VALIDATE_INT); + $value = $this->parseValue($value); + } else { + throw new Error( + sprintf( + 'The `%s`/`%s` value expected, `%s` given.', + NodeKind::STRING, + NodeKind::INT, + $valueNode->kind, + ), + ); + } + + return $value; + } + + /** + * @param class-string $error + * + * @phpstan-assert StreamOffset|int<0, max> $value + */ + protected function validate(mixed $value, string $error): StreamOffset|int { + if ($value instanceof StreamOffset) { + // ok + } elseif (is_int($value)) { + if ($value < 0) { + throw new $error('The offset must be greater or equal to 0.'); + } + } else { + throw new $error( + sprintf( + 'The valid cursor/offset expected, `%s` given.', + Utils::printSafe($value), + ), + ); + } + + return $value; + } + + protected function encrypt(string $value): string { + return $this->getEncrypter()->encryptString($value); + } + + protected function decrypt(string $value): string { + return Cast::toString($this->getEncrypter()->decryptString($value)); + } + // + + // + // ========================================================================= + #[Override] + public function getTypeName(TypeSource $source, Context $context): string { + return $this->name(); + } + + #[Override] + public function getTypeDefinition( + Manipulator $manipulator, + TypeSource $source, + Context $context, + string $name, + ): TypeDefinitionNode|string|null { + return self::class; + } + // +} diff --git a/packages/graphql/src/Stream/Types/OffsetTest.php b/packages/graphql/src/Stream/Scalars/OffsetTest.php similarity index 98% rename from packages/graphql/src/Stream/Types/OffsetTest.php rename to packages/graphql/src/Stream/Scalars/OffsetTest.php index 0d4e3c7d6..d0e03f710 100644 --- a/packages/graphql/src/Stream/Types/OffsetTest.php +++ b/packages/graphql/src/Stream/Scalars/OffsetTest.php @@ -1,6 +1,6 @@ getType(Offset::class, $source, $context); return Parser::objectTypeDefinition( diff --git a/packages/graphql/src/Stream/Types/Offset.php b/packages/graphql/src/Stream/Types/Offset.php index fbf23d27e..2f5009ef1 100644 --- a/packages/graphql/src/Stream/Types/Offset.php +++ b/packages/graphql/src/Stream/Types/Offset.php @@ -2,160 +2,19 @@ namespace LastDragon_ru\LaraASP\GraphQL\Stream\Types; -use Exception; -use GraphQL\Error\Error; -use GraphQL\Error\InvariantViolation; -use GraphQL\Language\AST\IntValueNode; -use GraphQL\Language\AST\Node; -use GraphQL\Language\AST\NodeKind; -use GraphQL\Language\AST\StringValueNode; use GraphQL\Language\AST\TypeDefinitionNode; -use GraphQL\Type\Definition\ScalarType; -use GraphQL\Type\Definition\Type; -use GraphQL\Utils\Utils; -use Illuminate\Container\Container; -use Illuminate\Contracts\Encryption\StringEncrypter; -use LastDragon_ru\LaraASP\Core\Utils\Cast; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeDefinition; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Manipulator; use LastDragon_ru\LaraASP\GraphQL\Stream\Directives\Directive; -use LastDragon_ru\LaraASP\GraphQL\Stream\Offset as StreamOffset; -use LastDragon_ru\LaraASP\GraphQL\Utils\TypeReference; -use LastDragon_ru\LaraASP\Serializer\Contracts\Serializer; +use LastDragon_ru\LaraASP\GraphQL\Stream\Scalars\Offset as OffsetScalar; use Override; -use function filter_var; -use function is_int; -use function is_string; -use function sprintf; - -use const FILTER_VALIDATE_INT; - -class Offset extends ScalarType implements TypeDefinition { - public string $name = Directive::Name.'Offset'; - public ?string $description = <<<'DESCRIPTION' - Represents a offset for the `@stream` directive. The value can be a - positive `Int` or a `String`. The `Int` value represents the offset - (zero-based) to navigate to any position within the stream (= offset - pagination). And the `String` value represents the cursor and allows - navigation only to the previous/current/next pages (= cursor - pagination). - DESCRIPTION; - - // - // ========================================================================= - protected function getEncrypter(): StringEncrypter { - return Container::getInstance()->make(StringEncrypter::class); - } - - protected function getSerializer(): Serializer { - return Container::getInstance()->make(Serializer::class); - } - // - - // - // ========================================================================= - /** - * @return string|int<0, max> - */ - #[Override] - public function serialize(mixed $value): string|int { - $value = $this->validate($value, InvariantViolation::class); - - if ($value instanceof StreamOffset) { - $value = $this->getSerializer()->serialize($value, 'json'); - $value = $this->encrypt($value); - } - - return $value; - } - - /** - * @return StreamOffset|int<0, max> - */ - #[Override] - public function parseValue(mixed $value): StreamOffset|int { - if (is_string($value)) { - try { - $value = $this->decrypt($value); - $value = $this->getSerializer()->deserialize(StreamOffset::class, $value, 'json'); - } catch (Exception) { - throw new Error('The cursor is not valid.'); - } - } else { - $value = $this->validate($value, Error::class); - } - - return $value; - } - - /** - * @inheritDoc - * @return StreamOffset|int<0, max> - */ - #[Override] - public function parseLiteral(Node $valueNode, array $variables = null): StreamOffset|int { - $value = null; - - if ($valueNode instanceof StringValueNode) { - $value = $this->parseValue($valueNode->value); - } elseif ($valueNode instanceof IntValueNode) { - $value = filter_var($valueNode->value, FILTER_VALIDATE_INT); - $value = $this->parseValue($value); - } else { - throw new Error( - sprintf( - 'The `%s`/`%s` value expected, `%s` given.', - NodeKind::STRING, - NodeKind::INT, - $valueNode->kind, - ), - ); - } - - return $value; - } - - /** - * @param class-string $error - * - * @phpstan-assert StreamOffset|int<0, max> $value - */ - protected function validate(mixed $value, string $error): StreamOffset|int { - if ($value instanceof StreamOffset) { - // ok - } elseif (is_int($value)) { - if ($value < 0) { - throw new $error('The offset must be greater or equal to 0.'); - } - } else { - throw new $error( - sprintf( - 'The valid cursor/offset expected, `%s` given.', - Utils::printSafe($value), - ), - ); - } - - return $value; - } - - protected function encrypt(string $value): string { - return $this->getEncrypter()->encryptString($value); - } - - protected function decrypt(string $value): string { - return Cast::toString($this->getEncrypter()->decryptString($value)); - } - // - - // - // ========================================================================= +class Offset implements TypeDefinition { #[Override] public function getTypeName(TypeSource $source, Context $context): string { - return $this->name(); + return Directive::Name.'Offset'; } #[Override] @@ -164,8 +23,8 @@ public function getTypeDefinition( TypeSource $source, Context $context, string $name, - ): TypeDefinitionNode|Type|null { - return new TypeReference($name, self::class); + ): TypeDefinitionNode|string|null { + return OffsetScalar::class; } // } diff --git a/packages/graphql/src/Stream/Types/Stream.php b/packages/graphql/src/Stream/Types/Stream.php index c7145c2b5..12d692694 100644 --- a/packages/graphql/src/Stream/Types/Stream.php +++ b/packages/graphql/src/Stream/Types/Stream.php @@ -4,7 +4,6 @@ use GraphQL\Language\AST\TypeDefinitionNode; use GraphQL\Language\Parser; -use GraphQL\Type\Definition\Type; use Illuminate\Support\Str; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeDefinition; @@ -41,7 +40,7 @@ public function getTypeDefinition( TypeSource $source, Context $context, string $name, - ): TypeDefinitionNode|Type|null { + ): TypeDefinitionNode|string|null { $type = $source->getTypeName(); $navigation = $manipulator->getType(Navigation::class, $source, $context); diff --git a/packages/graphql/src/Utils/AstManipulator.php b/packages/graphql/src/Utils/AstManipulator.php index 0aa5d51ba..e680726a1 100644 --- a/packages/graphql/src/Utils/AstManipulator.php +++ b/packages/graphql/src/Utils/AstManipulator.php @@ -37,7 +37,6 @@ use GraphQL\Type\Definition\NonNull; use GraphQL\Type\Definition\NullableType; use GraphQL\Type\Definition\ObjectType; -use GraphQL\Type\Definition\PhpEnumType; use GraphQL\Type\Definition\ScalarType; use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\UnionType; @@ -51,7 +50,6 @@ use LastDragon_ru\LaraASP\GraphQL\Exceptions\TypeDefinitionAlreadyDefined; use LastDragon_ru\LaraASP\GraphQL\Exceptions\TypeDefinitionUnknown; use LastDragon_ru\LaraASP\GraphQL\Exceptions\TypeUnexpected; -use LastDragon_ru\LaraASP\GraphQL\Package; use LastDragon_ru\LaraASP\GraphQL\Stream\Directives\Directive as StreamDirective; use Nuwave\Lighthouse\Pagination\PaginateDirective; use Nuwave\Lighthouse\Schema\AST\ASTHelper; @@ -71,7 +69,6 @@ use function mb_strlen; use function mb_substr; use function sprintf; -use function trigger_deprecation; use function trim; use const JSON_THROW_ON_ERROR; @@ -281,13 +278,13 @@ public function getTypeDefinition( } /** - * @template TDefinition of (TypeDefinitionNode&Node)|(Type&NamedType) + * @template TDefinition of (TypeDefinitionNode&Node)|TypeReference * - * @param TDefinition $definition Passing {@see Type} is deprecated, please use {@see TypeReference} instead. + * @param TDefinition $definition * * @return TDefinition */ - public function addTypeDefinition(TypeDefinitionNode|Type $definition): TypeDefinitionNode|Type { + public function addTypeDefinition(TypeDefinitionNode|TypeReference $definition): TypeDefinitionNode|TypeReference { $name = $this->getName($definition); if ($this->isTypeDefinitionExists($name)) { @@ -307,44 +304,6 @@ public function addTypeDefinition(TypeDefinitionNode|Type $definition): TypeDefi ); $this->getDocument()->setTypeDefinition($node); - } elseif ($definition instanceof ScalarType) { - trigger_deprecation( - Package::Name, - '6.3.0', - 'Passing `%s` into `%s` is deprecated, please use `%s` instead.', - ScalarType::class, - __METHOD__, - TypeReference::class, - ); - - $class = json_encode($definition::class, JSON_THROW_ON_ERROR); - $scalar = Parser::scalarTypeDefinition( - <<getDocument()->setTypeDefinition($scalar); - } elseif ($definition instanceof PhpEnumType) { - trigger_deprecation( - Package::Name, - '6.3.0', - 'Passing `%s` into `%s` is deprecated, please use `%s` instead.', - PhpEnumType::class, - __METHOD__, - TypeReference::class, - ); - - $directive = DirectiveLocator::directiveName(TypeDirective::class); - $class = PhpEnumTypeHelper::getEnumClass($definition); - $class = json_encode($class, JSON_THROW_ON_ERROR); - $scalar = Parser::scalarTypeDefinition( - <<getDocument()->setTypeDefinition($scalar); } else { // Types added while AST transformation will be lost if the Schema // is cached. Not yet sure how to solve it... Any ideas? @@ -536,10 +495,10 @@ public function getTypeName( } /** - * @param InputValueDefinitionNode|(TypeDefinitionNode&Node)|FieldDefinitionNode|InputObjectField|FieldDefinition|Argument|ArgumentNode|Type $node + * @param InputValueDefinitionNode|(TypeDefinitionNode&Node)|FieldDefinitionNode|InputObjectField|FieldDefinition|Argument|ArgumentNode|Type|TypeReference $node */ public function getName( - InputValueDefinitionNode|TypeDefinitionNode|FieldDefinitionNode|InputObjectField|FieldDefinition|Argument|ArgumentNode|Type $node, + InputValueDefinitionNode|TypeDefinitionNode|FieldDefinitionNode|InputObjectField|FieldDefinition|Argument|ArgumentNode|Type|TypeReference $node, ): string { if ($node instanceof TypeDefinitionNode) { $node = $node->getName(); @@ -547,6 +506,7 @@ public function getName( $node instanceof InputValueDefinitionNode || $node instanceof FieldDefinitionNode || $node instanceof ArgumentNode + || $node instanceof TypeReference ) { $node = $node->name; } else { diff --git a/packages/graphql/src/Utils/TypeReference.php b/packages/graphql/src/Utils/TypeReference.php index 4180ec351..b833b294e 100644 --- a/packages/graphql/src/Utils/TypeReference.php +++ b/packages/graphql/src/Utils/TypeReference.php @@ -2,19 +2,11 @@ namespace LastDragon_ru\LaraASP\GraphQL\Utils; -use GraphQL\Language\AST\Node; use GraphQL\Type\Definition\NamedType; use GraphQL\Type\Definition\Type; -use LogicException; -use Override; use UnitEnum; -/** - * Please note that {@see Type} and {@see NamedType} are used only to be - * compatible with existing API and will be removed in the next major version - * (without any BC mark). - */ -class TypeReference extends Type implements NamedType { +class TypeReference { /** * @param class-string<(Type&NamedType)|UnitEnum> $type */ @@ -24,68 +16,4 @@ public function __construct( ) { // empty } - - /** - * @internal - */ - #[Override] - public function name(): string { - return $this->name; - } - - /** - * @internal - */ - #[Override] - public function assertValid(): void { - $this->methodShouldNotBeUsed(); - } - - /** - * @internal - */ - #[Override] - public function isBuiltInType(): bool { - $this->methodShouldNotBeUsed(); - } - - /** - * @internal - */ - #[Override] - public function description(): ?string { - $this->methodShouldNotBeUsed(); - } - - /** - * @internal - * @inheritDoc - */ - #[Override] - public function astNode(): ?Node { - $this->methodShouldNotBeUsed(); - } - - /** - * @internal - * @inheritDoc - */ - #[Override] - public function extensionASTNodes(): array { - $this->methodShouldNotBeUsed(); - } - - /** - * @internal - */ - #[Override] - public function toString(): string { - $this->methodShouldNotBeUsed(); - } - - private function methodShouldNotBeUsed(): never { - throw new LogicException( - 'Method exists only for compatibility with existing API and MUST NOT BE USED.', - ); - } } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index b731a9534..d352fa961 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -45,11 +45,6 @@ parameters: count: 1 path: packages/graphql/src/Testing/Package/Models/Image.php - - - message: "#^Method LastDragon_ru\\\\LaraASP\\\\GraphQL\\\\Utils\\\\AstManipulator\\:\\:addTypeDefinition\\(\\) should return TDefinition of \\(GraphQL\\\\Language\\\\AST\\\\Node&GraphQL\\\\Language\\\\AST\\\\TypeDefinitionNode\\)\\|\\(GraphQL\\\\Type\\\\Definition\\\\NamedType&GraphQL\\\\Type\\\\Definition\\\\Type\\) but returns GraphQL\\\\Type\\\\Definition\\\\PhpEnumType\\|GraphQL\\\\Type\\\\Definition\\\\ScalarType\\|LastDragon_ru\\\\LaraASP\\\\GraphQL\\\\Utils\\\\TypeReference\\|TDefinition of GraphQL\\\\Language\\\\AST\\\\Node&GraphQL\\\\Language\\\\AST\\\\TypeDefinitionNode\\.$#" - count: 1 - path: packages/graphql/src/Utils/AstManipulator.php - - message: "#^Parameter \\#2 \\.\\.\\.\\$configs of method LastDragon_ru\\\\LaraASP\\\\Core\\\\Utils\\\\ConfigMerger\\:\\:merge\\(\\) expects array, mixed given\\.$#" count: 1