From 104eff54fa9a66f4855a67b9725a652bdee85862 Mon Sep 17 00:00:00 2001
From: Aleksei Lebedev <1329824+LastDragon-ru@users.noreply.github.com>
Date: Thu, 2 May 2024 11:36:42 +0400
Subject: [PATCH] `@stream` `Offset` scalar extracted from type definition.
---
.../DirectiveTest/Implicit.expected.graphql | 2 +-
.../DirectiveTest/Implicit.expected.graphql | 2 +-
.../DirectiveTest~schema-expected.graphql | 2 +-
.../DirectiveTest~scout-expected.graphql | 2 +-
.../graphql/src/Stream/Scalars/Offset.php | 169 ++++++++++++++++++
.../Stream/{Types => Scalars}/OffsetTest.php | 2 +-
packages/graphql/src/Stream/Types/Offset.php | 147 +--------------
7 files changed, 178 insertions(+), 148 deletions(-)
create mode 100644 packages/graphql/src/Stream/Scalars/Offset.php
rename packages/graphql/src/Stream/{Types => Scalars}/OffsetTest.php (98%)
diff --git a/packages/graphql/src/SearchBy/Directives/DirectiveTest/Implicit.expected.graphql b/packages/graphql/src/SearchBy/Directives/DirectiveTest/Implicit.expected.graphql
index 976e80d80..b2f14d1ea 100644
--- a/packages/graphql/src/SearchBy/Directives/DirectiveTest/Implicit.expected.graphql
+++ b/packages/graphql/src/SearchBy/Directives/DirectiveTest/Implicit.expected.graphql
@@ -1075,7 +1075,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/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/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 @@
- // =========================================================================
- 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]
@@ -163,7 +24,7 @@ public function getTypeDefinition(
Context $context,
string $name,
): TypeDefinitionNode|string|null {
- return self::class;
+ return OffsetScalar::class;
}
//
}