Skip to content

Commit

Permalink
refactor(graphql): Operators (#133)
Browse files Browse the repository at this point in the history
  • Loading branch information
LastDragon-ru authored Feb 23, 2024
2 parents e25b59f + 1c26ad3 commit fbaaab7
Show file tree
Hide file tree
Showing 39 changed files with 801 additions and 817 deletions.
36 changes: 36 additions & 0 deletions packages/core/src/Utils/Cast.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,72 @@ public static function toInt(mixed $value): int {
return $value;
}

public static function toIntNullable(mixed $value): ?int {
assert($value === null || is_int($value));

return $value;
}

public static function toFloat(mixed $value): float {
assert(is_float($value));

return $value;
}

public static function toFloatNullable(mixed $value): ?float {
assert($value === null || is_float($value));

return $value;
}

public static function toString(mixed $value): string {
assert(is_string($value));

return $value;
}

public static function toStringNullable(mixed $value): ?string {
assert($value === null || is_string($value));

return $value;
}

public static function toScalar(mixed $value): int|float|string|bool {
assert(is_scalar($value));

return $value;
}

public static function toScalarNullable(mixed $value): int|float|string|bool|null {
assert($value === null || is_scalar($value));

return $value;
}

public static function toNumber(mixed $value): int|float {
assert(is_int($value) || is_float($value));

return $value;
}

public static function toNumberNullable(mixed $value): int|float|null {
assert($value === null || is_int($value) || is_float($value));

return $value;
}

public static function toBool(mixed $value): bool {
assert(is_bool($value));

return $value;
}

public static function toBoolNullable(mixed $value): ?bool {
assert($value === null || is_bool($value));

return $value;
}

public static function toStringable(mixed $value): Stringable|string {
assert(is_string($value) || $value instanceof Stringable);

Expand Down
14 changes: 14 additions & 0 deletions packages/graphql/UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ Please also see [changelog](https://github.com/LastDragon-ru/lara-asp/releases)

* [ ] `enum SearchByTypeFlag { yes }` => `enum SearchByTypeFlag { Yes }`. 🤝

* [ ] `@searchByOperators` => `@searchByExtendOperators`. 🤝

* [ ] `@searchByOperatorRelation` => `@searchByOperatorRelationship` (and class too; generated types will be named as `SearchByRelationship*` instead of `SearchByComplex*`).

* [ ] `LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators::Condition` => `LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators::Object`.
Expand Down Expand Up @@ -139,6 +141,8 @@ Please also see [changelog](https://github.com/LastDragon-ru/lara-asp/releases)

This section is actual only if you are extending the package. Please review and update (listed the most significant changes only):

* [ ] `LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Operator` must explicitly implement concrete `LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Scope` (used to filter available directive-operators, previously was required implicitly).

* [ ] `LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Handler`

* [ ] `LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Operator`
Expand All @@ -151,6 +155,8 @@ This section is actual only if you are extending the package. Please review and

* [ ] `LastDragon_ru\LaraASP\GraphQL\Builder\Exceptions\Client\ConditionTooManyProperties` => `LastDragon_ru\LaraASP\GraphQL\Builder\Exceptions\Client\ConditionTooManyFields`

* [ ] `LastDragon_ru\LaraASP\GraphQL\Builder\Exceptions\TypeUnknown` removed

* [ ] `LastDragon_ru\LaraASP\GraphQL\Builder\Property` => `LastDragon_ru\LaraASP\GraphQL\Builder\Field`

* [ ] `LastDragon_ru\LaraASP\GraphQL\Builder\Manipulator`
Expand All @@ -163,10 +169,18 @@ This section is actual only if you are extending the package. Please review and

* [ ] `getPlaceholderTypeDefinitionNode()` removed => `LastDragon_ru\LaraASP\GraphQL\Utils\AstManipulator::getOriginType()`

* [ ] `getTypeOperators()`/`getOperator()` removed. To get operators the `LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context` should be used instead

```php
$context->get(LastDragon_ru\LaraASP\GraphQL\Builder\Context\HandlerContextOperators::class)?->value
```

* [ ] `LastDragon_ru\LaraASP\GraphQL\Builder\Directives\HandlerDirective`

* [ ] `LastDragon_ru\LaraASP\GraphQL\Builder\Directives\PropertyDirective` removed

* [ ] `LastDragon_ru\LaraASP\GraphQL\Builder\Operators`

* [ ] `LastDragon_ru\LaraASP\GraphQL\Builder\Sources\*`

* [ ] `LastDragon_ru\LaraASP\GraphQL\Builder\Traits\PropertyOperator` => `LastDragon_ru\LaraASP\GraphQL\Builder\Traits\HandlerOperator`
Expand Down
28 changes: 24 additions & 4 deletions packages/graphql/docs/Directives/@searchBy.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,32 @@ The package also defines a few own types in addition to the standard GraphQL typ

```graphql
scalar MyScalar
@searchByOperators(type: "MyScalar") # Re-use operators for `MyScalar` from config
@searchByOperators(type: "Int") # Re-use operators from `Int` from schema
@searchByOperatorEqual # Package operator
@myOperator # Custom operator
@searchByExtendOperators # Re-use operators for `MyScalar` from config
@searchByExtendOperators(type: "MyScalar") # same
@searchByExtendOperators(type: "Int") # Re-use operators from `Int` from schema
@searchByOperatorEqual # Add package operator
@myOperator # Add custom operator
```

[include:exec]: <../../../../dev/artisan dev:directive @searchByExtendOperators>
[//]: # (start: fb9508c1688c78899393b1119463a14ebcc2c0872316ca676b2945a296312230)
[//]: # (warning: Generated automatically. Do not edit.)

```graphql
"""
Extends the list of operators by the operators from the specified
`type` or from the config if `null`.
"""
directive @searchByExtendOperators(
type: String
)
on
| ENUM
| SCALAR
```

[//]: # (end: fb9508c1688c78899393b1119463a14ebcc2c0872316ca676b2945a296312230)

### Schema

```php
Expand Down
13 changes: 13 additions & 0 deletions packages/graphql/src/Builder/Context/HandlerContextOperators.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php declare(strict_types = 1);

namespace LastDragon_ru\LaraASP\GraphQL\Builder\Context;

use LastDragon_ru\LaraASP\GraphQL\Builder\Operators;

class HandlerContextOperators {
public function __construct(
public readonly Operators $value,
) {
// empty
}
}
3 changes: 3 additions & 0 deletions packages/graphql/src/Builder/Contracts/Operator.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
use Nuwave\Lighthouse\Execution\Arguments\Argument;
use Nuwave\Lighthouse\Support\Contracts\Directive;

/**
* Operator must also implement individual {@see Scope}.
*/
interface Operator extends Directive {
/**
* Must be a valid GraphQL Object Field name.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php declare(strict_types = 1);

namespace LastDragon_ru\LaraASP\GraphQL\Builder\Directives;

use GraphQL\Language\DirectiveLocation;
use LastDragon_ru\LaraASP\Core\Utils\Cast;
use Nuwave\Lighthouse\Schema\DirectiveLocator;
use Nuwave\Lighthouse\Schema\Directives\BaseDirective;
use Override;

use function array_unique;
use function implode;

abstract class ExtendOperatorsDirective extends BaseDirective {
public function __construct() {
// empty
}

#[Override]
public static function definition(): string {
$name = DirectiveLocator::directiveName(static::class);
$locations = implode(' | ', array_unique(static::getDirectiveLocations()));

return <<<GRAPHQL
"""
Extends the list of operators by the operators from the specified
`type` or from the config if `null`.
"""
directive @{$name}(type: String) on {$locations}
GRAPHQL;
}

/**
* @return non-empty-list<string>
*/
protected static function getDirectiveLocations(): array {
return [
DirectiveLocation::SCALAR,
DirectiveLocation::ENUM,
];
}

public function getType(): ?string {
return Cast::toStringNullable($this->directiveArgValue('type'));
}
}
21 changes: 5 additions & 16 deletions packages/graphql/src/Builder/Directives/HandlerDirective.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
use LastDragon_ru\LaraASP\GraphQL\Builder\Context;
use LastDragon_ru\LaraASP\GraphQL\Builder\Context\HandlerContextBuilderInfo;
use LastDragon_ru\LaraASP\GraphQL\Builder\Context\HandlerContextImplicit;
use LastDragon_ru\LaraASP\GraphQL\Builder\Context\HandlerContextOperators;
use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context as ContextContract;
use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Enhancer;
use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Handler;
use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Operator;
use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Scope;
use LastDragon_ru\LaraASP\GraphQL\Builder\Exceptions\Client\ConditionEmpty;
use LastDragon_ru\LaraASP\GraphQL\Builder\Exceptions\Client\ConditionTooManyFields;
use LastDragon_ru\LaraASP\GraphQL\Builder\Exceptions\Client\ConditionTooManyOperators;
Expand Down Expand Up @@ -55,23 +55,11 @@ abstract class HandlerDirective extends BaseDirective implements Handler, Enhanc
use WithSource;

public function __construct(
private ArgumentFactory $factory,
protected readonly ArgumentFactory $argumentFactory,
) {
// empty
}

// <editor-fold desc="Getters / Setters">
// =========================================================================
/**
* @return class-string<Scope>
*/
abstract public static function getScope(): string;

protected function getFactory(): ArgumentFactory {
return $this->factory;
}
// </editor-fold>

// <editor-fold desc="Handle">
// =========================================================================
/**
Expand Down Expand Up @@ -104,7 +92,7 @@ protected function handleAnyBuilder(
): object {
if ($value !== null && $this->definitionNode instanceof InputValueDefinitionNode) {
$argument = !($value instanceof Argument)
? $this->getFactory()->getArgument($this->definitionNode, $value)
? $this->argumentFactory->getArgument($this->definitionNode, $value)
: $value;
$builder = $this->enhance($builder, $argument, $field, $context);
}
Expand Down Expand Up @@ -287,7 +275,8 @@ protected function getArgumentTypeDefinitionNode(
string $operator,
): ListTypeNode|NamedTypeNode|NonNullTypeNode|null {
// Supported?
$operator = $manipulator->getOperator($operator, static::getScope(), $argument, $context);
$provider = $context->get(HandlerContextOperators::class)?->value;
$operator = $provider?->getOperator($manipulator, $operator, $argument, $context);

if (!$operator) {
return null;
Expand Down
24 changes: 7 additions & 17 deletions packages/graphql/src/Builder/Directives/OperatorsDirective.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,18 @@

namespace LastDragon_ru\LaraASP\GraphQL\Builder\Directives;

use GraphQL\Language\DirectiveLocation;
use Nuwave\Lighthouse\Schema\DirectiveLocator;
use Nuwave\Lighthouse\Schema\Directives\BaseDirective;
use Override;

use function array_unique;
use function assert;
use function implode;
use function is_string;

abstract class OperatorsDirective extends BaseDirective {
public function __construct() {
// empty
}

/**
* @deprecated 5.6.0 Use {@see ExtendOperatorsDirective} instead.
*/
abstract class OperatorsDirective extends ExtendOperatorsDirective {
#[Override]
public static function definition(): string {
$name = DirectiveLocator::directiveName(static::class);
Expand All @@ -25,21 +22,14 @@ public static function definition(): string {
return <<<GRAPHQL
"""
Extends the list of operators by the operators from the specified `type`.
The directive is deprecated!
"""
directive @{$name}(type: String!) on {$locations}
GRAPHQL;
}

/**
* @return non-empty-list<string>
*/
protected static function getDirectiveLocations(): array {
return [
DirectiveLocation::SCALAR,
DirectiveLocation::ENUM,
];
}

#[Override]
public function getType(): string {
$type = $this->directiveArgValue('type');

Expand Down
32 changes: 0 additions & 32 deletions packages/graphql/src/Builder/Exceptions/TypeUnknown.php

This file was deleted.

Loading

0 comments on commit fbaaab7

Please sign in to comment.