Skip to content

Commit

Permalink
Merge pull request #25 from x-graphql/fix/nullable-variable-may-not-d…
Browse files Browse the repository at this point in the history
…eclare

fix: declare nullable variable
  • Loading branch information
vuongxuongminh authored Apr 28, 2024
2 parents baa82e6 + c585651 commit bedf9ff
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 29 deletions.
45 changes: 17 additions & 28 deletions src/Execution/DelegateResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,8 @@ public function resolve(): Promise
$fragments = $this->collectFragments($operationType, $operation->selectionSet);
$relations = $this->collectRelations($operationType, $operation->selectionSet, $fragments);

/// All selection set is clear, let collects using variables
$variables = $this->collectVariables($operation, $fragments);

$operation->variableDefinitions = $this->createVariableDefinitions($variables);

/// All selection set is clear, let resolve variables
$variables = $this->resolveVariables($operation, $fragments);
$promise = $this->delegateToExecute($subSchemaName, $operation, $fragments, $variables);

$promises[] = $promise->then(
Expand Down Expand Up @@ -317,18 +314,29 @@ private function collectRelations(

/**
* @param OperationDefinitionNode $operation
* @param FragmentDefinitionNode[] $fragments
* @param array<string, FragmentDefinitionNode> $fragments
* @return array<string, mixed>
* @throws \JsonException
*/
private function collectVariables(OperationDefinitionNode $operation, array $fragments): array
private function resolveVariables(OperationDefinitionNode $operation, array $fragments): array
{
$variables = [];
$names = [
...Variable::getVariablesInOperation($operation),
...Variable::getVariablesInFragments($fragments),
];

foreach ($names as $name) {
foreach ($this->rootOperation->variableDefinitions as $definition) {
/** @var VariableDefinitionNode $definition */
$name = $definition->variable->name->value;

if (!in_array($name, $names, true)) {
continue;
}

$operation->variableDefinitions[] = $definition->cloneDeep();

/// Nullable variable may not declare, so we need to check before get
if (array_key_exists($name, $this->variables)) {
$variables[$name] = $this->variables[$name];
}
Expand Down Expand Up @@ -451,10 +459,7 @@ private function delegateRelationQueries(
$operationType = $this->executionSchema->getOperationType($operation->operation);
$fragments = $this->collectFragments($operationType, $operation->selectionSet);
$relationsRelations = $this->collectRelations($operationType, $operation->selectionSet, $fragments);
$variables += $this->collectVariables($operation, $fragments);
$variableDefinitions = $this->createVariableDefinitions($variables)->merge($operation->variableDefinitions);

$operation->variableDefinitions = $variableDefinitions;
$variables += $this->resolveVariables($operation, $fragments);

return $this
->delegateToExecute($subSchemaName, $operation, $fragments, $variables)
Expand Down Expand Up @@ -734,22 +739,6 @@ private function createOperation(string $operation): OperationDefinitionNode
]);
}

private function createVariableDefinitions(array $variables): NodeList
{
$definitions = new NodeList([]);

foreach ($this->rootOperation->variableDefinitions as $definition) {
/** @var VariableDefinitionNode $definition */
$name = $definition->variable->name->value;

if (array_key_exists($name, $variables)) {
$definitions[] = $definition->cloneDeep();
}
}

return $definitions;
}

private function getUid(): string
{
static $uid = null;
Expand Down
19 changes: 18 additions & 1 deletion tests/IntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ public static function executionProvider(): array
]
]
],
'use null variable' => [
'nullable variable' => [
<<<'GQL'
query($code: ID) {
findPersonByLanguageCode(code: $code) {
Expand All @@ -445,6 +445,23 @@ public static function executionProvider(): array
]
]
],
],
'not declare nullable variable' => [
<<<'GQL'
query($code: ID) {
findPersonByLanguageCode(code: $code) {
name
}
}
GQL,
[],
[
'data' => [
'findPersonByLanguageCode' => [
'name' => 'John Doe unknown',
]
]
],
]
];
}
Expand Down

0 comments on commit bedf9ff

Please sign in to comment.