Skip to content

Commit

Permalink
Make args mapper optional
Browse files Browse the repository at this point in the history
  • Loading branch information
spawnia authored Oct 25, 2024
1 parent c3a36a2 commit 995a174
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 20 deletions.
12 changes: 12 additions & 0 deletions docs/class-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
This is the primary facade for fulfilling GraphQL operations.
See [related documentation](executing-queries.md).

@phpstan-import-type ArgsMapper from Executor
@phpstan-import-type FieldResolver from Executor

@see \GraphQL\Tests\GraphQLTest
Expand Down Expand Up @@ -164,6 +165,17 @@ static function getStandardValidationRules(): array
static function setDefaultFieldResolver(callable $fn): void
```

```php
/**
* Set default args mapper implementation.
*
* @phpstan-param ArgsMapper $fn
*
* @api
*/
static function setDefaultArgsMapper(callable $fn): void
```

## GraphQL\Type\Definition\Type

Registry of standard GraphQL types and base class for all other types.
Expand Down
2 changes: 1 addition & 1 deletion docs/error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ This will make each error entry look like this:
'extensions' => [
'debugMessage' => 'Actual exception message',
'trace' => [
/* Formatted original exception trace */
// Formatted original exception trace
],
],
]
Expand Down
5 changes: 0 additions & 5 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
parameters:
ignoreErrors:
-
message: "#^SplObjectStorage\\<GraphQL\\\\Type\\\\Definition\\\\ObjectType, SplObjectStorage\\<ArrayObject\\<int, GraphQL\\\\Language\\\\AST\\\\FieldNode\\>, ArrayObject\\<string, ArrayObject\\<int, GraphQL\\\\Language\\\\AST\\\\FieldNode\\>\\>\\>\\> does not accept SplObjectStorage\\<ArrayObject\\<int, GraphQL\\\\Language\\\\AST\\\\FieldNode\\>, ArrayObject\\<string, ArrayObject\\<int, GraphQL\\\\Language\\\\AST\\\\FieldNode\\>\\>\\>\\|SplObjectStorage\\<object, mixed\\>\\.$#"
count: 1
path: src/Executor/ReferenceExecutor.php

-
message: "#^Unable to resolve the template type TCloneable in call to method static method GraphQL\\\\Language\\\\AST\\\\Node\\:\\:cloneValue\\(\\)$#"
count: 1
Expand Down
10 changes: 8 additions & 2 deletions src/Executor/Executor.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,25 @@ public static function setDefaultFieldResolver(callable $fieldResolver): void
self::$defaultFieldResolver = $fieldResolver;
}

/** @phpstan-return ArgsMapper */
public static function getDefaultArgsMapper(): callable
{
return self::$defaultArgsMapper;
}

/** @phpstan-param ArgsMapper $argsMapper */
public static function setDefaultArgsMapper(callable $argsMapper): void
{
self::$defaultArgsMapper = $argsMapper;
}

public static function getPromiseAdapter(): PromiseAdapter
public static function getDefaultPromiseAdapter(): PromiseAdapter
{
return self::$defaultPromiseAdapter ??= new SyncPromiseAdapter();
}

/** Set a custom default promise adapter. */
public static function setPromiseAdapter(?PromiseAdapter $defaultPromiseAdapter = null): void
public static function setDefaultPromiseAdapter(?PromiseAdapter $defaultPromiseAdapter = null): void
{
self::$defaultPromiseAdapter = $defaultPromiseAdapter;
}
Expand Down
18 changes: 12 additions & 6 deletions src/Executor/ReferenceExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,12 @@ class ReferenceExecutor implements ExecutorImplementation
*/
protected \SplObjectStorage $subFieldCache;

/** @var \SplObjectStorage<FieldDefinition, \SplObjectStorage<FieldNode, mixed>> */
/**
* @var \SplObjectStorage<
* FieldDefinition,
* \SplObjectStorage<FieldNode, mixed>
* >
*/
protected \SplObjectStorage $fieldArgsCache;

protected function __construct(ExecutionContext $context)
Expand Down Expand Up @@ -94,7 +99,7 @@ public static function create(
array $variableValues,
?string $operationName,
callable $fieldResolver,
callable $argsMapper
?callable $argsMapper = null // TODO make non-optional in next major release
): ExecutorImplementation {
$exeContext = static::buildExecutionContext(
$schema,
Expand All @@ -104,7 +109,7 @@ public static function create(
$variableValues,
$operationName,
$fieldResolver,
$argsMapper,
$argsMapper ?? Executor::getDefaultArgsMapper(),
$promiseAdapter,
);

Expand All @@ -128,8 +133,8 @@ public function doExecute(): Promise
}

/**
* Constructs an ExecutionContext object from the arguments passed to
* execute, which we will pass throughout the other execution methods.
* Constructs an ExecutionContext object from the arguments passed to execute,
* which we will pass throughout the other execution methods.
*
* @param mixed $rootValue
* @param mixed $contextValue
Expand Down Expand Up @@ -741,7 +746,7 @@ protected function resolveFieldValueOrError(
try {
// Build a map of arguments from the field.arguments AST, using the
// variables scope to fulfill any variable references.
/** @phpstan-ignore-next-line ignored because no way to tell phpstan what are generics of SplObjectStorage without assign it to var first */
// @phpstan-ignore-next-line generics of SplObjectStorage are not inferred from empty instantiation
$this->fieldArgsCache[$fieldDef] ??= new \SplObjectStorage();

$args = $this->fieldArgsCache[$fieldDef][$fieldNode] ??= $argsMapper(Values::getArgumentValues(
Expand Down Expand Up @@ -1331,6 +1336,7 @@ protected function collectAndExecuteSubfields(
*/
protected function collectSubFields(ObjectType $returnType, \ArrayObject $fieldNodes): \ArrayObject
{
// @phpstan-ignore-next-line generics of SplObjectStorage are not inferred from empty instantiation
$returnTypeCache = $this->subFieldCache[$returnType] ??= new \SplObjectStorage();

if (! isset($returnTypeCache[$fieldNodes])) {
Expand Down
13 changes: 13 additions & 0 deletions src/GraphQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* This is the primary facade for fulfilling GraphQL operations.
* See [related documentation](executing-queries.md).
*
* @phpstan-import-type ArgsMapper from Executor
* @phpstan-import-type FieldResolver from Executor
*
* @see \GraphQL\Tests\GraphQLTest
Expand Down Expand Up @@ -243,4 +244,16 @@ public static function setDefaultFieldResolver(callable $fn): void
{
Executor::setDefaultFieldResolver($fn);
}

/**
* Set default args mapper implementation.
*
* @phpstan-param ArgsMapper $fn
*
* @api
*/
public static function setDefaultArgsMapper(callable $fn): void
{
Executor::setDefaultArgsMapper($fn);
}
}
4 changes: 2 additions & 2 deletions src/Server/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ public function validateOperationParams(OperationParams $params): array
*/
public function executeOperation(ServerConfig $config, OperationParams $op)
{
$promiseAdapter = $config->getPromiseAdapter() ?? Executor::getPromiseAdapter();
$promiseAdapter = $config->getPromiseAdapter() ?? Executor::getDefaultPromiseAdapter();
$result = $this->promiseToExecuteOperation($promiseAdapter, $config, $op);

if ($promiseAdapter instanceof SyncPromiseAdapter) {
Expand All @@ -222,7 +222,7 @@ public function executeOperation(ServerConfig $config, OperationParams $op)
*/
public function executeBatch(ServerConfig $config, array $operations)
{
$promiseAdapter = $config->getPromiseAdapter() ?? Executor::getPromiseAdapter();
$promiseAdapter = $config->getPromiseAdapter() ?? Executor::getDefaultPromiseAdapter();

$result = [];
foreach ($operations as $operation) {
Expand Down
6 changes: 3 additions & 3 deletions tests/Executor/ExecutorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ final class ExecutorTest extends TestCase

public function tearDown(): void
{
Executor::setPromiseAdapter(null);
Executor::setDefaultPromiseAdapter(null);
}

// Execute: Handles basic execution tasks
Expand Down Expand Up @@ -398,8 +398,8 @@ public function testArgsMapper(): void
]),
]);
$result = Executor::execute($schema, $docAst);
self::assertEquals(1, $mapperCalledCount);
self::assertEquals(3, $resolverCalledCount);
self::assertSame(1, $mapperCalledCount);
self::assertSame(3, $resolverCalledCount);
self::assertCount(0, $result->errors);
}

Expand Down
2 changes: 1 addition & 1 deletion tests/Language/VisitorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ private function checkVisitorFnArgs(DocumentNode $ast, array $args, bool $isEdit
if ($parent instanceof NodeList) {
self::assertEquals($node, $parent[$key]);
} else {
/** @phpstan-ignore-next-line */
// @phpstan-ignore-next-line dynamic property access
self::assertEquals($node, $parent->{$key});
}

Expand Down

0 comments on commit 995a174

Please sign in to comment.