mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-22 12:56:05 +03:00
commit
1417a43697
@ -14,7 +14,7 @@
|
|||||||
"ext-mbstring": "*"
|
"ext-mbstring": "*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"doctrine/coding-standard": "^4.0",
|
"doctrine/coding-standard": "^5.0",
|
||||||
"phpbench/phpbench": "^0.14.0",
|
"phpbench/phpbench": "^0.14.0",
|
||||||
"phpstan/phpstan": "^0.10.3",
|
"phpstan/phpstan": "^0.10.3",
|
||||||
"phpstan/phpstan-phpunit": "^0.10.0",
|
"phpstan/phpstan-phpunit": "^0.10.0",
|
||||||
|
@ -4,11 +4,14 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL;
|
namespace GraphQL;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Executor\Promise\Adapter\SyncPromise;
|
use GraphQL\Executor\Promise\Adapter\SyncPromise;
|
||||||
|
use SplQueue;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
class Deferred
|
class Deferred
|
||||||
{
|
{
|
||||||
/** @var \SplQueue */
|
/** @var SplQueue */
|
||||||
private static $queue;
|
private static $queue;
|
||||||
|
|
||||||
/** @var callable */
|
/** @var callable */
|
||||||
@ -19,7 +22,7 @@ class Deferred
|
|||||||
|
|
||||||
public static function getQueue()
|
public static function getQueue()
|
||||||
{
|
{
|
||||||
return self::$queue ?: self::$queue = new \SplQueue();
|
return self::$queue ?: self::$queue = new SplQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function runQueue()
|
public static function runQueue()
|
||||||
@ -49,9 +52,9 @@ class Deferred
|
|||||||
try {
|
try {
|
||||||
$cb = $this->callback;
|
$cb = $this->callback;
|
||||||
$this->promise->resolve($cb());
|
$this->promise->resolve($cb());
|
||||||
} catch (\Exception $e) {
|
} catch (Exception $e) {
|
||||||
$this->promise->reject($e);
|
$this->promise->reject($e);
|
||||||
} catch (\Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
$this->promise->reject($e);
|
$this->promise->reject($e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,9 @@ interface ClientAware
|
|||||||
/**
|
/**
|
||||||
* Returns true when exception message is safe to be displayed to a client.
|
* Returns true when exception message is safe to be displayed to a client.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return bool
|
* @return bool
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function isClientSafe();
|
public function isClientSafe();
|
||||||
|
|
||||||
@ -27,8 +28,9 @@ interface ClientAware
|
|||||||
*
|
*
|
||||||
* Value "graphql" is reserved for errors produced by query parsing or validation, do not use it.
|
* Value "graphql" is reserved for errors produced by query parsing or validation, do not use it.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return string
|
* @return string
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getCategory();
|
public function getCategory();
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,13 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Error;
|
namespace GraphQL\Error;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Language\AST\Node;
|
use GraphQL\Language\AST\Node;
|
||||||
use GraphQL\Language\Source;
|
use GraphQL\Language\Source;
|
||||||
use GraphQL\Language\SourceLocation;
|
use GraphQL\Language\SourceLocation;
|
||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
|
use JsonSerializable;
|
||||||
|
use Throwable;
|
||||||
use Traversable;
|
use Traversable;
|
||||||
use function array_filter;
|
use function array_filter;
|
||||||
use function array_map;
|
use function array_map;
|
||||||
@ -28,7 +31,7 @@ use function iterator_to_array;
|
|||||||
* Class extends standard PHP `\Exception`, so all standard methods of base `\Exception` class
|
* Class extends standard PHP `\Exception`, so all standard methods of base `\Exception` class
|
||||||
* are available in addition to those listed below.
|
* are available in addition to those listed below.
|
||||||
*/
|
*/
|
||||||
class Error extends \Exception implements \JsonSerializable, ClientAware
|
class Error extends Exception implements JsonSerializable, ClientAware
|
||||||
{
|
{
|
||||||
const CATEGORY_GRAPHQL = 'graphql';
|
const CATEGORY_GRAPHQL = 'graphql';
|
||||||
const CATEGORY_INTERNAL = 'internal';
|
const CATEGORY_INTERNAL = 'internal';
|
||||||
@ -85,7 +88,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
* @param Node|Node[]|Traversable|null $nodes
|
* @param Node|Node[]|Traversable|null $nodes
|
||||||
* @param mixed[]|null $positions
|
* @param mixed[]|null $positions
|
||||||
* @param mixed[]|null $path
|
* @param mixed[]|null $path
|
||||||
* @param \Throwable $previous
|
* @param Throwable $previous
|
||||||
* @param mixed[] $extensions
|
* @param mixed[] $extensions
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
@ -100,7 +103,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
parent::__construct($message, 0, $previous);
|
parent::__construct($message, 0, $previous);
|
||||||
|
|
||||||
// Compute list of blame nodes.
|
// Compute list of blame nodes.
|
||||||
if ($nodes instanceof \Traversable) {
|
if ($nodes instanceof Traversable) {
|
||||||
$nodes = iterator_to_array($nodes);
|
$nodes = iterator_to_array($nodes);
|
||||||
} elseif ($nodes && ! is_array($nodes)) {
|
} elseif ($nodes && ! is_array($nodes)) {
|
||||||
$nodes = [$nodes];
|
$nodes = [$nodes];
|
||||||
@ -136,6 +139,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
* @param mixed $error
|
* @param mixed $error
|
||||||
* @param Node[]|null $nodes
|
* @param Node[]|null $nodes
|
||||||
* @param mixed[]|null $path
|
* @param mixed[]|null $path
|
||||||
|
*
|
||||||
* @return Error
|
* @return Error
|
||||||
*/
|
*/
|
||||||
public static function createLocatedError($error, $nodes = null, $path = null)
|
public static function createLocatedError($error, $nodes = null, $path = null)
|
||||||
@ -159,7 +163,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
$source = $error->source;
|
$source = $error->source;
|
||||||
$positions = $error->positions;
|
$positions = $error->positions;
|
||||||
$extensions = $error->extensions;
|
$extensions = $error->extensions;
|
||||||
} elseif ($error instanceof \Exception || $error instanceof \Throwable) {
|
} elseif ($error instanceof Exception || $error instanceof Throwable) {
|
||||||
$message = $error->getMessage();
|
$message = $error->getMessage();
|
||||||
$originalError = $error;
|
$originalError = $error;
|
||||||
} else {
|
} else {
|
||||||
@ -222,7 +226,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
{
|
{
|
||||||
if ($this->positions === null && ! empty($this->nodes)) {
|
if ($this->positions === null && ! empty($this->nodes)) {
|
||||||
$positions = array_map(
|
$positions = array_map(
|
||||||
function ($node) {
|
static function ($node) {
|
||||||
return isset($node->loc) ? $node->loc->start : null;
|
return isset($node->loc) ? $node->loc->start : null;
|
||||||
},
|
},
|
||||||
$this->nodes
|
$this->nodes
|
||||||
@ -230,7 +234,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
|
|
||||||
$this->positions = array_filter(
|
$this->positions = array_filter(
|
||||||
$positions,
|
$positions,
|
||||||
function ($p) {
|
static function ($p) {
|
||||||
return $p !== null;
|
return $p !== null;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -250,8 +254,9 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
* point out to field mentioned in multiple fragments. Errors during execution include a
|
* point out to field mentioned in multiple fragments. Errors during execution include a
|
||||||
* single location, the field which produced the error.
|
* single location, the field which produced the error.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return SourceLocation[]
|
* @return SourceLocation[]
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getLocations()
|
public function getLocations()
|
||||||
{
|
{
|
||||||
@ -262,7 +267,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
|
|
||||||
if ($positions && $source) {
|
if ($positions && $source) {
|
||||||
$this->locations = array_map(
|
$this->locations = array_map(
|
||||||
function ($pos) use ($source) {
|
static function ($pos) use ($source) {
|
||||||
return $source->getLocation($pos);
|
return $source->getLocation($pos);
|
||||||
},
|
},
|
||||||
$positions
|
$positions
|
||||||
@ -270,7 +275,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
} elseif ($nodes) {
|
} elseif ($nodes) {
|
||||||
$this->locations = array_filter(
|
$this->locations = array_filter(
|
||||||
array_map(
|
array_map(
|
||||||
function ($node) {
|
static function ($node) {
|
||||||
if ($node->loc && $node->loc->source) {
|
if ($node->loc && $node->loc->source) {
|
||||||
return $node->loc->source->getLocation($node->loc->start);
|
return $node->loc->source->getLocation($node->loc->start);
|
||||||
}
|
}
|
||||||
@ -298,8 +303,9 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
* Returns an array describing the path from the root value to the field which produced this error.
|
* Returns an array describing the path from the root value to the field which produced this error.
|
||||||
* Only included for execution errors.
|
* Only included for execution errors.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return mixed[]|null
|
* @return mixed[]|null
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getPath()
|
public function getPath()
|
||||||
{
|
{
|
||||||
@ -318,6 +324,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
* Returns array representation of error suitable for serialization
|
* Returns array representation of error suitable for serialization
|
||||||
*
|
*
|
||||||
* @deprecated Use FormattedError::createFromException() instead
|
* @deprecated Use FormattedError::createFromException() instead
|
||||||
|
*
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
*/
|
*/
|
||||||
public function toSerializableArray()
|
public function toSerializableArray()
|
||||||
@ -328,7 +335,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
|
|
||||||
$locations = Utils::map(
|
$locations = Utils::map(
|
||||||
$this->getLocations(),
|
$this->getLocations(),
|
||||||
function (SourceLocation $loc) {
|
static function (SourceLocation $loc) {
|
||||||
return $loc->toSerializableArray();
|
return $loc->toSerializableArray();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -348,7 +355,9 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify data which should be serialized to JSON
|
* Specify data which should be serialized to JSON
|
||||||
|
*
|
||||||
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
|
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
|
||||||
|
*
|
||||||
* @return mixed data which can be serialized by <b>json_encode</b>,
|
* @return mixed data which can be serialized by <b>json_encode</b>,
|
||||||
* which is a value of any type other than a resource.
|
* which is a value of any type other than a resource.
|
||||||
*/
|
*/
|
||||||
|
@ -4,12 +4,16 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Error;
|
namespace GraphQL\Error;
|
||||||
|
|
||||||
|
use Countable;
|
||||||
|
use ErrorException;
|
||||||
|
use Exception;
|
||||||
use GraphQL\Language\AST\Node;
|
use GraphQL\Language\AST\Node;
|
||||||
use GraphQL\Language\Source;
|
use GraphQL\Language\Source;
|
||||||
use GraphQL\Language\SourceLocation;
|
use GraphQL\Language\SourceLocation;
|
||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
use GraphQL\Type\Definition\WrappingType;
|
use GraphQL\Type\Definition\WrappingType;
|
||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
|
use Throwable;
|
||||||
use function addcslashes;
|
use function addcslashes;
|
||||||
use function array_filter;
|
use function array_filter;
|
||||||
use function array_intersect_key;
|
use function array_intersect_key;
|
||||||
@ -45,8 +49,9 @@ class FormattedError
|
|||||||
* Set default error message for internal errors formatted using createFormattedError().
|
* Set default error message for internal errors formatted using createFormattedError().
|
||||||
* This value can be overridden by passing 3rd argument to `createFormattedError()`.
|
* This value can be overridden by passing 3rd argument to `createFormattedError()`.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param string $msg
|
* @param string $msg
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function setInternalErrorMessage($msg)
|
public static function setInternalErrorMessage($msg)
|
||||||
{
|
{
|
||||||
@ -132,6 +137,7 @@ class FormattedError
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $len
|
* @param int $len
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private static function whitespace($len)
|
private static function whitespace($len)
|
||||||
@ -141,6 +147,7 @@ class FormattedError
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $len
|
* @param int $len
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private static function lpad($len, $str)
|
private static function lpad($len, $str)
|
||||||
@ -157,17 +164,20 @@ class FormattedError
|
|||||||
*
|
*
|
||||||
* For a list of available debug flags see GraphQL\Error\Debug constants.
|
* For a list of available debug flags see GraphQL\Error\Debug constants.
|
||||||
*
|
*
|
||||||
* @api
|
* @param Throwable $e
|
||||||
* @param \Throwable $e
|
|
||||||
* @param bool|int $debug
|
* @param bool|int $debug
|
||||||
* @param string $internalErrorMessage
|
* @param string $internalErrorMessage
|
||||||
|
*
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
* @throws \Throwable
|
*
|
||||||
|
* @throws Throwable
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function createFromException($e, $debug = false, $internalErrorMessage = null)
|
public static function createFromException($e, $debug = false, $internalErrorMessage = null)
|
||||||
{
|
{
|
||||||
Utils::invariant(
|
Utils::invariant(
|
||||||
$e instanceof \Exception || $e instanceof \Throwable,
|
$e instanceof Exception || $e instanceof Throwable,
|
||||||
'Expected exception, got %s',
|
'Expected exception, got %s',
|
||||||
Utils::getVariableType($e)
|
Utils::getVariableType($e)
|
||||||
);
|
);
|
||||||
@ -189,7 +199,7 @@ class FormattedError
|
|||||||
if ($e instanceof Error) {
|
if ($e instanceof Error) {
|
||||||
$locations = Utils::map(
|
$locations = Utils::map(
|
||||||
$e->getLocations(),
|
$e->getLocations(),
|
||||||
function (SourceLocation $loc) {
|
static function (SourceLocation $loc) {
|
||||||
return $loc->toSerializableArray();
|
return $loc->toSerializableArray();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -216,10 +226,12 @@ class FormattedError
|
|||||||
* (see GraphQL\Error\Debug for available flags)
|
* (see GraphQL\Error\Debug for available flags)
|
||||||
*
|
*
|
||||||
* @param mixed[] $formattedError
|
* @param mixed[] $formattedError
|
||||||
* @param \Throwable $e
|
* @param Throwable $e
|
||||||
* @param bool $debug
|
* @param bool $debug
|
||||||
|
*
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
* @throws \Throwable
|
*
|
||||||
|
* @throws Throwable
|
||||||
*/
|
*/
|
||||||
public static function addDebugEntries(array $formattedError, $e, $debug)
|
public static function addDebugEntries(array $formattedError, $e, $debug)
|
||||||
{
|
{
|
||||||
@ -228,7 +240,7 @@ class FormattedError
|
|||||||
}
|
}
|
||||||
|
|
||||||
Utils::invariant(
|
Utils::invariant(
|
||||||
$e instanceof \Exception || $e instanceof \Throwable,
|
$e instanceof Exception || $e instanceof Throwable,
|
||||||
'Expected exception, got %s',
|
'Expected exception, got %s',
|
||||||
Utils::getVariableType($e)
|
Utils::getVariableType($e)
|
||||||
);
|
);
|
||||||
@ -259,7 +271,7 @@ class FormattedError
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($debug & Debug::INCLUDE_TRACE) {
|
if ($debug & Debug::INCLUDE_TRACE) {
|
||||||
if ($e instanceof \ErrorException || $e instanceof \Error) {
|
if ($e instanceof ErrorException || $e instanceof \Error) {
|
||||||
$formattedError += [
|
$formattedError += [
|
||||||
'file' => $e->getFile(),
|
'file' => $e->getFile(),
|
||||||
'line' => $e->getLine(),
|
'line' => $e->getLine(),
|
||||||
@ -282,15 +294,16 @@ class FormattedError
|
|||||||
* If initial formatter is not set, FormattedError::createFromException is used
|
* If initial formatter is not set, FormattedError::createFromException is used
|
||||||
*
|
*
|
||||||
* @param bool $debug
|
* @param bool $debug
|
||||||
* @return callable|\Closure
|
*
|
||||||
|
* @return callable|callable
|
||||||
*/
|
*/
|
||||||
public static function prepareFormatter(?callable $formatter = null, $debug)
|
public static function prepareFormatter(?callable $formatter = null, $debug)
|
||||||
{
|
{
|
||||||
$formatter = $formatter ?: function ($e) {
|
$formatter = $formatter ?: static function ($e) {
|
||||||
return FormattedError::createFromException($e);
|
return FormattedError::createFromException($e);
|
||||||
};
|
};
|
||||||
if ($debug) {
|
if ($debug) {
|
||||||
$formatter = function ($e) use ($formatter, $debug) {
|
$formatter = static function ($e) use ($formatter, $debug) {
|
||||||
return FormattedError::addDebugEntries($formatter($e), $e, $debug);
|
return FormattedError::addDebugEntries($formatter($e), $e, $debug);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -301,9 +314,11 @@ class FormattedError
|
|||||||
/**
|
/**
|
||||||
* Returns error trace as serializable array
|
* Returns error trace as serializable array
|
||||||
*
|
*
|
||||||
* @api
|
* @param Throwable $error
|
||||||
* @param \Throwable $error
|
*
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function toSafeTrace($error)
|
public static function toSafeTrace($error)
|
||||||
{
|
{
|
||||||
@ -319,12 +334,12 @@ class FormattedError
|
|||||||
}
|
}
|
||||||
|
|
||||||
return array_map(
|
return array_map(
|
||||||
function ($err) {
|
static function ($err) {
|
||||||
$safeErr = array_intersect_key($err, ['file' => true, 'line' => true]);
|
$safeErr = array_intersect_key($err, ['file' => true, 'line' => true]);
|
||||||
|
|
||||||
if (isset($err['function'])) {
|
if (isset($err['function'])) {
|
||||||
$func = $err['function'];
|
$func = $err['function'];
|
||||||
$args = ! empty($err['args']) ? array_map([__CLASS__, 'printVar'], $err['args']) : [];
|
$args = ! empty($err['args']) ? array_map([self::class, 'printVar'], $err['args']) : [];
|
||||||
$funcStr = $func . '(' . implode(', ', $args) . ')';
|
$funcStr = $func . '(' . implode(', ', $args) . ')';
|
||||||
|
|
||||||
if (isset($err['class'])) {
|
if (isset($err['class'])) {
|
||||||
@ -342,6 +357,7 @@ class FormattedError
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $var
|
* @param mixed $var
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function printVar($var)
|
public static function printVar($var)
|
||||||
@ -356,7 +372,7 @@ class FormattedError
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_object($var)) {
|
if (is_object($var)) {
|
||||||
return 'instance of ' . get_class($var) . ($var instanceof \Countable ? '(' . count($var) . ')' : '');
|
return 'instance of ' . get_class($var) . ($var instanceof Countable ? '(' . count($var) . ')' : '');
|
||||||
}
|
}
|
||||||
if (is_array($var)) {
|
if (is_array($var)) {
|
||||||
return 'array(' . count($var) . ')';
|
return 'array(' . count($var) . ')';
|
||||||
@ -382,8 +398,10 @@ class FormattedError
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated as of v0.8.0
|
* @deprecated as of v0.8.0
|
||||||
|
*
|
||||||
* @param string $error
|
* @param string $error
|
||||||
* @param SourceLocation[] $locations
|
* @param SourceLocation[] $locations
|
||||||
|
*
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
*/
|
*/
|
||||||
public static function create($error, array $locations = [])
|
public static function create($error, array $locations = [])
|
||||||
@ -392,7 +410,7 @@ class FormattedError
|
|||||||
|
|
||||||
if (! empty($locations)) {
|
if (! empty($locations)) {
|
||||||
$formatted['locations'] = array_map(
|
$formatted['locations'] = array_map(
|
||||||
function ($loc) {
|
static function ($loc) {
|
||||||
return $loc->toArray();
|
return $loc->toArray();
|
||||||
},
|
},
|
||||||
$locations
|
$locations
|
||||||
@ -404,9 +422,10 @@ class FormattedError
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated as of v0.10.0, use general purpose method createFromException() instead
|
* @deprecated as of v0.10.0, use general purpose method createFromException() instead
|
||||||
|
*
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
*/
|
*/
|
||||||
public static function createFromPHPError(\ErrorException $e)
|
public static function createFromPHPError(ErrorException $e)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'message' => $e->getMessage(),
|
'message' => $e->getMessage(),
|
||||||
|
@ -4,6 +4,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Error;
|
namespace GraphQL\Error;
|
||||||
|
|
||||||
|
use LogicException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class InvariantVoilation
|
* Class InvariantVoilation
|
||||||
*
|
*
|
||||||
@ -11,6 +13,6 @@ namespace GraphQL\Error;
|
|||||||
* This exception should not inherit base Error exception as it is raised when there is an error somewhere in
|
* This exception should not inherit base Error exception as it is raised when there is an error somewhere in
|
||||||
* user-land code
|
* user-land code
|
||||||
*/
|
*/
|
||||||
class InvariantViolation extends \LogicException
|
class InvariantViolation extends LogicException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,14 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Error;
|
namespace GraphQL\Error;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class UserError
|
* Class UserError
|
||||||
*
|
*
|
||||||
* Error caused by actions of GraphQL clients. Can be safely displayed to a client...
|
* Error caused by actions of GraphQL clients. Can be safely displayed to a client...
|
||||||
*/
|
*/
|
||||||
class UserError extends \RuntimeException implements ClientAware
|
class UserError extends RuntimeException implements ClientAware
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
|
@ -50,8 +50,9 @@ final class Warning
|
|||||||
*
|
*
|
||||||
* When passing true - suppresses all warnings.
|
* When passing true - suppresses all warnings.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param bool|int $suppress
|
* @param bool|int $suppress
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function suppress($suppress = true)
|
public static function suppress($suppress = true)
|
||||||
{
|
{
|
||||||
@ -74,8 +75,9 @@ final class Warning
|
|||||||
*
|
*
|
||||||
* When passing true - re-enables all warnings.
|
* When passing true - re-enables all warnings.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param bool|int $enable
|
* @param bool|int $enable
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function enable($enable = true)
|
public static function enable($enable = true)
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,7 @@ namespace GraphQL\Executor;
|
|||||||
|
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
use GraphQL\Error\FormattedError;
|
use GraphQL\Error\FormattedError;
|
||||||
|
use JsonSerializable;
|
||||||
use function array_map;
|
use function array_map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,7 +17,7 @@ use function array_map;
|
|||||||
* Could be converted to [spec-compliant](https://facebook.github.io/graphql/#sec-Response-Format)
|
* Could be converted to [spec-compliant](https://facebook.github.io/graphql/#sec-Response-Format)
|
||||||
* serializable array using `toArray()`
|
* serializable array using `toArray()`
|
||||||
*/
|
*/
|
||||||
class ExecutionResult implements \JsonSerializable
|
class ExecutionResult implements JsonSerializable
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Data collected from resolvers during query execution
|
* Data collected from resolvers during query execution
|
||||||
@ -77,8 +78,9 @@ class ExecutionResult implements \JsonSerializable
|
|||||||
* // ... other keys
|
* // ... other keys
|
||||||
* );
|
* );
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return self
|
* @return self
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setErrorFormatter(callable $errorFormatter)
|
public function setErrorFormatter(callable $errorFormatter)
|
||||||
{
|
{
|
||||||
@ -97,8 +99,9 @@ class ExecutionResult implements \JsonSerializable
|
|||||||
* return array_map($formatter, $errors);
|
* return array_map($formatter, $errors);
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return self
|
* @return self
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setErrorsHandler(callable $handler)
|
public function setErrorsHandler(callable $handler)
|
||||||
{
|
{
|
||||||
@ -125,16 +128,18 @@ class ExecutionResult implements \JsonSerializable
|
|||||||
* $debug argument must be either bool (only adds "debugMessage" to result) or sum of flags from
|
* $debug argument must be either bool (only adds "debugMessage" to result) or sum of flags from
|
||||||
* GraphQL\Error\Debug
|
* GraphQL\Error\Debug
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param bool|int $debug
|
* @param bool|int $debug
|
||||||
|
*
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function toArray($debug = false)
|
public function toArray($debug = false)
|
||||||
{
|
{
|
||||||
$result = [];
|
$result = [];
|
||||||
|
|
||||||
if (! empty($this->errors)) {
|
if (! empty($this->errors)) {
|
||||||
$errorsHandler = $this->errorsHandler ?: function (array $errors, callable $formatter) {
|
$errorsHandler = $this->errorsHandler ?: static function (array $errors, callable $formatter) {
|
||||||
return array_map($formatter, $errors);
|
return array_map($formatter, $errors);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,7 +4,9 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Executor;
|
namespace GraphQL\Executor;
|
||||||
|
|
||||||
|
use ArrayAccess;
|
||||||
use ArrayObject;
|
use ArrayObject;
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
use GraphQL\Error\InvariantViolation;
|
use GraphQL\Error\InvariantViolation;
|
||||||
use GraphQL\Error\Warning;
|
use GraphQL\Error\Warning;
|
||||||
@ -33,12 +35,18 @@ use GraphQL\Type\Introspection;
|
|||||||
use GraphQL\Type\Schema;
|
use GraphQL\Type\Schema;
|
||||||
use GraphQL\Utils\TypeInfo;
|
use GraphQL\Utils\TypeInfo;
|
||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
|
use RuntimeException;
|
||||||
|
use SplObjectStorage;
|
||||||
|
use stdClass;
|
||||||
|
use Throwable;
|
||||||
|
use Traversable;
|
||||||
use function array_keys;
|
use function array_keys;
|
||||||
use function array_merge;
|
use function array_merge;
|
||||||
use function array_reduce;
|
use function array_reduce;
|
||||||
use function array_values;
|
use function array_values;
|
||||||
use function get_class;
|
use function get_class;
|
||||||
use function is_array;
|
use function is_array;
|
||||||
|
use function is_callable;
|
||||||
use function is_object;
|
use function is_object;
|
||||||
use function is_string;
|
use function is_string;
|
||||||
use function sprintf;
|
use function sprintf;
|
||||||
@ -52,7 +60,7 @@ class Executor
|
|||||||
private static $UNDEFINED;
|
private static $UNDEFINED;
|
||||||
|
|
||||||
/** @var callable|string[] */
|
/** @var callable|string[] */
|
||||||
private static $defaultFieldResolver = [__CLASS__, 'defaultFieldResolver'];
|
private static $defaultFieldResolver = [self::class, 'defaultFieldResolver'];
|
||||||
|
|
||||||
/** @var PromiseAdapter */
|
/** @var PromiseAdapter */
|
||||||
private static $promiseAdapter;
|
private static $promiseAdapter;
|
||||||
@ -60,7 +68,7 @@ class Executor
|
|||||||
/** @var ExecutionContext */
|
/** @var ExecutionContext */
|
||||||
private $exeContext;
|
private $exeContext;
|
||||||
|
|
||||||
/** @var \SplObjectStorage */
|
/** @var SplObjectStorage */
|
||||||
private $subFieldCache;
|
private $subFieldCache;
|
||||||
|
|
||||||
private function __construct(ExecutionContext $context)
|
private function __construct(ExecutionContext $context)
|
||||||
@ -70,13 +78,13 @@ class Executor
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->exeContext = $context;
|
$this->exeContext = $context;
|
||||||
$this->subFieldCache = new \SplObjectStorage();
|
$this->subFieldCache = new SplObjectStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom default resolve function
|
* Custom default resolve function
|
||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function setDefaultFieldResolver(callable $fn)
|
public static function setDefaultFieldResolver(callable $fn)
|
||||||
{
|
{
|
||||||
@ -89,13 +97,14 @@ class Executor
|
|||||||
* Always returns ExecutionResult and never throws. All errors which occur during operation
|
* Always returns ExecutionResult and never throws. All errors which occur during operation
|
||||||
* execution are collected in `$result->errors`.
|
* execution are collected in `$result->errors`.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param mixed|null $rootValue
|
* @param mixed|null $rootValue
|
||||||
* @param mixed[]|null $contextValue
|
* @param mixed[]|null $contextValue
|
||||||
* @param mixed[]|\ArrayAccess|null $variableValues
|
* @param mixed[]|ArrayAccess|null $variableValues
|
||||||
* @param string|null $operationName
|
* @param string|null $operationName
|
||||||
*
|
*
|
||||||
* @return ExecutionResult|Promise
|
* @return ExecutionResult|Promise
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function execute(
|
public static function execute(
|
||||||
Schema $schema,
|
Schema $schema,
|
||||||
@ -146,12 +155,14 @@ class Executor
|
|||||||
*
|
*
|
||||||
* Useful for async PHP platforms.
|
* Useful for async PHP platforms.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param mixed[]|null $rootValue
|
* @param mixed[]|null $rootValue
|
||||||
* @param mixed[]|null $contextValue
|
* @param mixed[]|null $contextValue
|
||||||
* @param mixed[]|null $variableValues
|
* @param mixed[]|null $variableValues
|
||||||
* @param string|null $operationName
|
* @param string|null $operationName
|
||||||
|
*
|
||||||
* @return Promise
|
* @return Promise
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function promiseToExecute(
|
public static function promiseToExecute(
|
||||||
PromiseAdapter $promiseAdapter,
|
PromiseAdapter $promiseAdapter,
|
||||||
@ -189,7 +200,7 @@ class Executor
|
|||||||
*
|
*
|
||||||
* @param mixed[] $rootValue
|
* @param mixed[] $rootValue
|
||||||
* @param mixed[] $contextValue
|
* @param mixed[] $contextValue
|
||||||
* @param mixed[]|\Traversable $rawVariableValues
|
* @param mixed[]|Traversable $rawVariableValues
|
||||||
* @param string|null $operationName
|
* @param string|null $operationName
|
||||||
*
|
*
|
||||||
* @return ExecutionContext|Error[]
|
* @return ExecutionContext|Error[]
|
||||||
@ -297,7 +308,8 @@ class Executor
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed|null|Promise $data
|
* @param mixed|Promise|null $data
|
||||||
|
*
|
||||||
* @return ExecutionResult|Promise
|
* @return ExecutionResult|Promise
|
||||||
*/
|
*/
|
||||||
private function buildResponse($data)
|
private function buildResponse($data)
|
||||||
@ -317,12 +329,13 @@ class Executor
|
|||||||
* Implements the "Evaluating operations" section of the spec.
|
* Implements the "Evaluating operations" section of the spec.
|
||||||
*
|
*
|
||||||
* @param mixed[] $rootValue
|
* @param mixed[] $rootValue
|
||||||
* @return Promise|\stdClass|mixed[]
|
*
|
||||||
|
* @return Promise|stdClass|mixed[]
|
||||||
*/
|
*/
|
||||||
private function executeOperation(OperationDefinitionNode $operation, $rootValue)
|
private function executeOperation(OperationDefinitionNode $operation, $rootValue)
|
||||||
{
|
{
|
||||||
$type = $this->getOperationRootType($this->exeContext->schema, $operation);
|
$type = $this->getOperationRootType($this->exeContext->schema, $operation);
|
||||||
$fields = $this->collectFields($type, $operation->selectionSet, new \ArrayObject(), new \ArrayObject());
|
$fields = $this->collectFields($type, $operation->selectionSet, new ArrayObject(), new ArrayObject());
|
||||||
|
|
||||||
$path = [];
|
$path = [];
|
||||||
|
|
||||||
@ -357,6 +370,7 @@ class Executor
|
|||||||
* Extracts the root type of the operation from the schema.
|
* Extracts the root type of the operation from the schema.
|
||||||
*
|
*
|
||||||
* @return ObjectType
|
* @return ObjectType
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
private function getOperationRootType(Schema $schema, OperationDefinitionNode $operation)
|
private function getOperationRootType(Schema $schema, OperationDefinitionNode $operation)
|
||||||
@ -411,7 +425,7 @@ class Executor
|
|||||||
* @param ArrayObject $fields
|
* @param ArrayObject $fields
|
||||||
* @param ArrayObject $visitedFragmentNames
|
* @param ArrayObject $visitedFragmentNames
|
||||||
*
|
*
|
||||||
* @return \ArrayObject
|
* @return ArrayObject
|
||||||
*/
|
*/
|
||||||
private function collectFields(
|
private function collectFields(
|
||||||
ObjectType $runtimeType,
|
ObjectType $runtimeType,
|
||||||
@ -428,7 +442,7 @@ class Executor
|
|||||||
}
|
}
|
||||||
$name = self::getFieldEntryKey($selection);
|
$name = self::getFieldEntryKey($selection);
|
||||||
if (! isset($fields[$name])) {
|
if (! isset($fields[$name])) {
|
||||||
$fields[$name] = new \ArrayObject();
|
$fields[$name] = new ArrayObject();
|
||||||
}
|
}
|
||||||
$fields[$name][] = $selection;
|
$fields[$name][] = $selection;
|
||||||
break;
|
break;
|
||||||
@ -475,6 +489,7 @@ class Executor
|
|||||||
* directives, where @skip has higher precedence than @include.
|
* directives, where @skip has higher precedence than @include.
|
||||||
*
|
*
|
||||||
* @param FragmentSpreadNode|FieldNode|InlineFragmentNode $node
|
* @param FragmentSpreadNode|FieldNode|InlineFragmentNode $node
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private function shouldIncludeNode($node)
|
private function shouldIncludeNode($node)
|
||||||
@ -521,6 +536,7 @@ class Executor
|
|||||||
* Determines if a fragment is applicable to the given type.
|
* Determines if a fragment is applicable to the given type.
|
||||||
*
|
*
|
||||||
* @param FragmentDefinitionNode|InlineFragmentNode $fragment
|
* @param FragmentDefinitionNode|InlineFragmentNode $fragment
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private function doesFragmentConditionMatch(
|
private function doesFragmentConditionMatch(
|
||||||
@ -551,7 +567,8 @@ class Executor
|
|||||||
* @param mixed[] $sourceValue
|
* @param mixed[] $sourceValue
|
||||||
* @param mixed[] $path
|
* @param mixed[] $path
|
||||||
* @param ArrayObject $fields
|
* @param ArrayObject $fields
|
||||||
* @return Promise|\stdClass|mixed[]
|
*
|
||||||
|
* @return Promise|stdClass|mixed[]
|
||||||
*/
|
*/
|
||||||
private function executeFieldsSerially(ObjectType $parentType, $sourceValue, $path, $fields)
|
private function executeFieldsSerially(ObjectType $parentType, $sourceValue, $path, $fields)
|
||||||
{
|
{
|
||||||
@ -567,7 +584,7 @@ class Executor
|
|||||||
}
|
}
|
||||||
$promise = $this->getPromise($result);
|
$promise = $this->getPromise($result);
|
||||||
if ($promise) {
|
if ($promise) {
|
||||||
return $promise->then(function ($resolvedResult) use ($responseName, $results) {
|
return $promise->then(static function ($resolvedResult) use ($responseName, $results) {
|
||||||
$results[$responseName] = $resolvedResult;
|
$results[$responseName] = $resolvedResult;
|
||||||
return $results;
|
return $results;
|
||||||
});
|
});
|
||||||
@ -578,7 +595,7 @@ class Executor
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
if ($this->isPromise($result)) {
|
if ($this->isPromise($result)) {
|
||||||
return $result->then(function ($resolvedResults) {
|
return $result->then(static function ($resolvedResults) {
|
||||||
return self::fixResultsIfEmptyArray($resolvedResults);
|
return self::fixResultsIfEmptyArray($resolvedResults);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -595,7 +612,7 @@ class Executor
|
|||||||
* @param FieldNode[] $fieldNodes
|
* @param FieldNode[] $fieldNodes
|
||||||
* @param mixed[] $path
|
* @param mixed[] $path
|
||||||
*
|
*
|
||||||
* @return mixed[]|\Exception|mixed|null
|
* @return mixed[]|Exception|mixed|null
|
||||||
*/
|
*/
|
||||||
private function resolveField(ObjectType $parentType, $source, $fieldNodes, $path)
|
private function resolveField(ObjectType $parentType, $source, $fieldNodes, $path)
|
||||||
{
|
{
|
||||||
@ -705,7 +722,8 @@ class Executor
|
|||||||
* @param mixed $source
|
* @param mixed $source
|
||||||
* @param mixed $context
|
* @param mixed $context
|
||||||
* @param ResolveInfo $info
|
* @param ResolveInfo $info
|
||||||
* @return \Throwable|Promise|mixed
|
*
|
||||||
|
* @return Throwable|Promise|mixed
|
||||||
*/
|
*/
|
||||||
private function resolveOrError($fieldDef, $fieldNode, $resolveFn, $source, $context, $info)
|
private function resolveOrError($fieldDef, $fieldNode, $resolveFn, $source, $context, $info)
|
||||||
{
|
{
|
||||||
@ -719,9 +737,9 @@ class Executor
|
|||||||
);
|
);
|
||||||
|
|
||||||
return $resolveFn($source, $args, $context, $info);
|
return $resolveFn($source, $args, $context, $info);
|
||||||
} catch (\Exception $error) {
|
} catch (Exception $error) {
|
||||||
return $error;
|
return $error;
|
||||||
} catch (\Throwable $error) {
|
} catch (Throwable $error) {
|
||||||
return $error;
|
return $error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -733,6 +751,7 @@ class Executor
|
|||||||
* @param FieldNode[] $fieldNodes
|
* @param FieldNode[] $fieldNodes
|
||||||
* @param string[] $path
|
* @param string[] $path
|
||||||
* @param mixed $result
|
* @param mixed $result
|
||||||
|
*
|
||||||
* @return mixed[]|Promise|null
|
* @return mixed[]|Promise|null
|
||||||
*/
|
*/
|
||||||
private function completeValueCatchingError(
|
private function completeValueCatchingError(
|
||||||
@ -796,7 +815,9 @@ class Executor
|
|||||||
* @param FieldNode[] $fieldNodes
|
* @param FieldNode[] $fieldNodes
|
||||||
* @param string[] $path
|
* @param string[] $path
|
||||||
* @param mixed $result
|
* @param mixed $result
|
||||||
|
*
|
||||||
* @return mixed[]|mixed|Promise|null
|
* @return mixed[]|mixed|Promise|null
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public function completeValueWithLocatedError(
|
public function completeValueWithLocatedError(
|
||||||
@ -829,9 +850,9 @@ class Executor
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $completed;
|
return $completed;
|
||||||
} catch (\Exception $error) {
|
} catch (Exception $error) {
|
||||||
throw Error::createLocatedError($error, $fieldNodes, $path);
|
throw Error::createLocatedError($error, $fieldNodes, $path);
|
||||||
} catch (\Throwable $error) {
|
} catch (Throwable $error) {
|
||||||
throw Error::createLocatedError($error, $fieldNodes, $path);
|
throw Error::createLocatedError($error, $fieldNodes, $path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -860,9 +881,11 @@ class Executor
|
|||||||
* @param FieldNode[] $fieldNodes
|
* @param FieldNode[] $fieldNodes
|
||||||
* @param string[] $path
|
* @param string[] $path
|
||||||
* @param mixed $result
|
* @param mixed $result
|
||||||
|
*
|
||||||
* @return mixed[]|mixed|Promise|null
|
* @return mixed[]|mixed|Promise|null
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
* @throws \Throwable
|
* @throws Throwable
|
||||||
*/
|
*/
|
||||||
private function completeValue(
|
private function completeValue(
|
||||||
Type $returnType,
|
Type $returnType,
|
||||||
@ -880,7 +903,7 @@ class Executor
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($result instanceof \Exception || $result instanceof \Throwable) {
|
if ($result instanceof Exception || $result instanceof Throwable) {
|
||||||
throw $result;
|
throw $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -949,11 +972,12 @@ class Executor
|
|||||||
return $this->completeObjectValue($returnType, $fieldNodes, $info, $path, $result);
|
return $this->completeObjectValue($returnType, $fieldNodes, $info, $path, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new \RuntimeException(sprintf('Cannot complete value of unexpected type "%s".', $returnType));
|
throw new RuntimeException(sprintf('Cannot complete value of unexpected type "%s".', $returnType));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private function isPromise($value)
|
private function isPromise($value)
|
||||||
@ -966,6 +990,7 @@ class Executor
|
|||||||
* otherwise returns null.
|
* otherwise returns null.
|
||||||
*
|
*
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return Promise|null
|
* @return Promise|null
|
||||||
*/
|
*/
|
||||||
private function getPromise($value)
|
private function getPromise($value)
|
||||||
@ -998,14 +1023,15 @@ class Executor
|
|||||||
*
|
*
|
||||||
* @param mixed[] $values
|
* @param mixed[] $values
|
||||||
* @param Promise|mixed|null $initialValue
|
* @param Promise|mixed|null $initialValue
|
||||||
|
*
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
*/
|
*/
|
||||||
private function promiseReduce(array $values, \Closure $callback, $initialValue)
|
private function promiseReduce(array $values, callable $callback, $initialValue)
|
||||||
{
|
{
|
||||||
return array_reduce($values, function ($previous, $value) use ($callback) {
|
return array_reduce($values, function ($previous, $value) use ($callback) {
|
||||||
$promise = $this->getPromise($previous);
|
$promise = $this->getPromise($previous);
|
||||||
if ($promise) {
|
if ($promise) {
|
||||||
return $promise->then(function ($resolved) use ($callback, $value) {
|
return $promise->then(static function ($resolved) use ($callback, $value) {
|
||||||
return $callback($resolved, $value);
|
return $callback($resolved, $value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1020,14 +1046,16 @@ class Executor
|
|||||||
* @param FieldNode[] $fieldNodes
|
* @param FieldNode[] $fieldNodes
|
||||||
* @param mixed[] $path
|
* @param mixed[] $path
|
||||||
* @param mixed $result
|
* @param mixed $result
|
||||||
|
*
|
||||||
* @return mixed[]|Promise
|
* @return mixed[]|Promise
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private function completeListValue(ListOfType $returnType, $fieldNodes, ResolveInfo $info, $path, &$result)
|
private function completeListValue(ListOfType $returnType, $fieldNodes, ResolveInfo $info, $path, &$result)
|
||||||
{
|
{
|
||||||
$itemType = $returnType->getWrappedType();
|
$itemType = $returnType->getWrappedType();
|
||||||
Utils::invariant(
|
Utils::invariant(
|
||||||
is_array($result) || $result instanceof \Traversable,
|
is_array($result) || $result instanceof Traversable,
|
||||||
'User Error: expected iterable, but did not find one for field ' . $info->parentType . '.' . $info->fieldName . '.'
|
'User Error: expected iterable, but did not find one for field ' . $info->parentType . '.' . $info->fieldName . '.'
|
||||||
);
|
);
|
||||||
$containsPromise = false;
|
$containsPromise = false;
|
||||||
@ -1051,20 +1079,22 @@ class Executor
|
|||||||
* Complete a Scalar or Enum by serializing to a valid value, throwing if serialization is not possible.
|
* Complete a Scalar or Enum by serializing to a valid value, throwing if serialization is not possible.
|
||||||
*
|
*
|
||||||
* @param mixed $result
|
* @param mixed $result
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private function completeLeafValue(LeafType $returnType, &$result)
|
private function completeLeafValue(LeafType $returnType, &$result)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return $returnType->serialize($result);
|
return $returnType->serialize($result);
|
||||||
} catch (\Exception $error) {
|
} catch (Exception $error) {
|
||||||
throw new InvariantViolation(
|
throw new InvariantViolation(
|
||||||
'Expected a value of type "' . Utils::printSafe($returnType) . '" but received: ' . Utils::printSafe($result),
|
'Expected a value of type "' . Utils::printSafe($returnType) . '" but received: ' . Utils::printSafe($result),
|
||||||
0,
|
0,
|
||||||
$error
|
$error
|
||||||
);
|
);
|
||||||
} catch (\Throwable $error) {
|
} catch (Throwable $error) {
|
||||||
throw new InvariantViolation(
|
throw new InvariantViolation(
|
||||||
'Expected a value of type "' . Utils::printSafe($returnType) . '" but received: ' . Utils::printSafe($result),
|
'Expected a value of type "' . Utils::printSafe($returnType) . '" but received: ' . Utils::printSafe($result),
|
||||||
0,
|
0,
|
||||||
@ -1080,7 +1110,9 @@ class Executor
|
|||||||
* @param FieldNode[] $fieldNodes
|
* @param FieldNode[] $fieldNodes
|
||||||
* @param mixed[] $path
|
* @param mixed[] $path
|
||||||
* @param mixed[] $result
|
* @param mixed[] $result
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
private function completeAbstractValue(AbstractType $returnType, $fieldNodes, ResolveInfo $info, $path, &$result)
|
private function completeAbstractValue(AbstractType $returnType, $fieldNodes, ResolveInfo $info, $path, &$result)
|
||||||
@ -1142,6 +1174,7 @@ class Executor
|
|||||||
*
|
*
|
||||||
* @param mixed|null $value
|
* @param mixed|null $value
|
||||||
* @param mixed|null $context
|
* @param mixed|null $context
|
||||||
|
*
|
||||||
* @return ObjectType|Promise|null
|
* @return ObjectType|Promise|null
|
||||||
*/
|
*/
|
||||||
private function defaultTypeResolver($value, $context, ResolveInfo $info, AbstractType $abstractType)
|
private function defaultTypeResolver($value, $context, ResolveInfo $info, AbstractType $abstractType)
|
||||||
@ -1190,7 +1223,7 @@ class Executor
|
|||||||
|
|
||||||
if (! empty($promisedIsTypeOfResults)) {
|
if (! empty($promisedIsTypeOfResults)) {
|
||||||
return $this->exeContext->promises->all($promisedIsTypeOfResults)
|
return $this->exeContext->promises->all($promisedIsTypeOfResults)
|
||||||
->then(function ($isTypeOfResults) use ($possibleTypes) {
|
->then(static function ($isTypeOfResults) use ($possibleTypes) {
|
||||||
foreach ($isTypeOfResults as $index => $result) {
|
foreach ($isTypeOfResults as $index => $result) {
|
||||||
if ($result) {
|
if ($result) {
|
||||||
return $possibleTypes[$index];
|
return $possibleTypes[$index];
|
||||||
@ -1210,7 +1243,9 @@ class Executor
|
|||||||
* @param FieldNode[] $fieldNodes
|
* @param FieldNode[] $fieldNodes
|
||||||
* @param mixed[] $path
|
* @param mixed[] $path
|
||||||
* @param mixed $result
|
* @param mixed $result
|
||||||
* @return mixed[]|Promise|\stdClass
|
*
|
||||||
|
* @return mixed[]|Promise|stdClass
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
private function completeObjectValue(ObjectType $returnType, $fieldNodes, ResolveInfo $info, $path, &$result)
|
private function completeObjectValue(ObjectType $returnType, $fieldNodes, ResolveInfo $info, $path, &$result)
|
||||||
@ -1260,6 +1295,7 @@ class Executor
|
|||||||
/**
|
/**
|
||||||
* @param mixed[] $result
|
* @param mixed[] $result
|
||||||
* @param FieldNode[] $fieldNodes
|
* @param FieldNode[] $fieldNodes
|
||||||
|
*
|
||||||
* @return Error
|
* @return Error
|
||||||
*/
|
*/
|
||||||
private function invalidReturnTypeError(
|
private function invalidReturnTypeError(
|
||||||
@ -1277,7 +1313,9 @@ class Executor
|
|||||||
* @param FieldNode[] $fieldNodes
|
* @param FieldNode[] $fieldNodes
|
||||||
* @param mixed[] $path
|
* @param mixed[] $path
|
||||||
* @param mixed[] $result
|
* @param mixed[] $result
|
||||||
* @return mixed[]|Promise|\stdClass
|
*
|
||||||
|
* @return mixed[]|Promise|stdClass
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
private function collectAndExecuteSubfields(
|
private function collectAndExecuteSubfields(
|
||||||
@ -1294,12 +1332,12 @@ class Executor
|
|||||||
private function collectSubFields(ObjectType $returnType, $fieldNodes) : ArrayObject
|
private function collectSubFields(ObjectType $returnType, $fieldNodes) : ArrayObject
|
||||||
{
|
{
|
||||||
if (! isset($this->subFieldCache[$returnType])) {
|
if (! isset($this->subFieldCache[$returnType])) {
|
||||||
$this->subFieldCache[$returnType] = new \SplObjectStorage();
|
$this->subFieldCache[$returnType] = new SplObjectStorage();
|
||||||
}
|
}
|
||||||
if (! isset($this->subFieldCache[$returnType][$fieldNodes])) {
|
if (! isset($this->subFieldCache[$returnType][$fieldNodes])) {
|
||||||
// Collect sub-fields to execute to complete this value.
|
// Collect sub-fields to execute to complete this value.
|
||||||
$subFieldNodes = new \ArrayObject();
|
$subFieldNodes = new ArrayObject();
|
||||||
$visitedFragmentNames = new \ArrayObject();
|
$visitedFragmentNames = new ArrayObject();
|
||||||
|
|
||||||
foreach ($fieldNodes as $fieldNode) {
|
foreach ($fieldNodes as $fieldNode) {
|
||||||
if (! isset($fieldNode->selectionSet)) {
|
if (! isset($fieldNode->selectionSet)) {
|
||||||
@ -1325,7 +1363,8 @@ class Executor
|
|||||||
* @param mixed|null $source
|
* @param mixed|null $source
|
||||||
* @param mixed[] $path
|
* @param mixed[] $path
|
||||||
* @param ArrayObject $fields
|
* @param ArrayObject $fields
|
||||||
* @return Promise|\stdClass|mixed[]
|
*
|
||||||
|
* @return Promise|stdClass|mixed[]
|
||||||
*/
|
*/
|
||||||
private function executeFields(ObjectType $parentType, $source, $path, $fields)
|
private function executeFields(ObjectType $parentType, $source, $path, $fields)
|
||||||
{
|
{
|
||||||
@ -1361,12 +1400,13 @@ class Executor
|
|||||||
* @see https://github.com/webonyx/graphql-php/issues/59
|
* @see https://github.com/webonyx/graphql-php/issues/59
|
||||||
*
|
*
|
||||||
* @param mixed[] $results
|
* @param mixed[] $results
|
||||||
* @return \stdClass|mixed[]
|
*
|
||||||
|
* @return stdClass|mixed[]
|
||||||
*/
|
*/
|
||||||
private static function fixResultsIfEmptyArray($results)
|
private static function fixResultsIfEmptyArray($results)
|
||||||
{
|
{
|
||||||
if ($results === []) {
|
if ($results === []) {
|
||||||
return new \stdClass();
|
return new stdClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $results;
|
return $results;
|
||||||
@ -1380,6 +1420,7 @@ class Executor
|
|||||||
* any promises.
|
* any promises.
|
||||||
*
|
*
|
||||||
* @param (string|Promise)[] $assoc
|
* @param (string|Promise)[] $assoc
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
private function promiseForAssocArray(array $assoc)
|
private function promiseForAssocArray(array $assoc)
|
||||||
@ -1389,7 +1430,7 @@ class Executor
|
|||||||
|
|
||||||
$promise = $this->exeContext->promises->all($valuesAndPromises);
|
$promise = $this->exeContext->promises->all($valuesAndPromises);
|
||||||
|
|
||||||
return $promise->then(function ($values) use ($keys) {
|
return $promise->then(static function ($values) use ($keys) {
|
||||||
$resolvedResults = [];
|
$resolvedResults = [];
|
||||||
foreach ($values as $i => $value) {
|
foreach ($values as $i => $value) {
|
||||||
$resolvedResults[$keys[$i]] = $value;
|
$resolvedResults[$keys[$i]] = $value;
|
||||||
@ -1403,6 +1444,7 @@ class Executor
|
|||||||
* @param string|ObjectType|null $runtimeTypeOrName
|
* @param string|ObjectType|null $runtimeTypeOrName
|
||||||
* @param FieldNode[] $fieldNodes
|
* @param FieldNode[] $fieldNodes
|
||||||
* @param mixed $result
|
* @param mixed $result
|
||||||
|
*
|
||||||
* @return ObjectType
|
* @return ObjectType
|
||||||
*/
|
*/
|
||||||
private function ensureValidRuntimeType(
|
private function ensureValidRuntimeType(
|
||||||
@ -1471,7 +1513,7 @@ class Executor
|
|||||||
$fieldName = $info->fieldName;
|
$fieldName = $info->fieldName;
|
||||||
$property = null;
|
$property = null;
|
||||||
|
|
||||||
if (is_array($source) || $source instanceof \ArrayAccess) {
|
if (is_array($source) || $source instanceof ArrayAccess) {
|
||||||
if (isset($source[$fieldName])) {
|
if (isset($source[$fieldName])) {
|
||||||
$property = $source[$fieldName];
|
$property = $source[$fieldName];
|
||||||
}
|
}
|
||||||
@ -1481,6 +1523,6 @@ class Executor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $property instanceof \Closure ? $property($source, $args, $context, $info) : $property;
|
return is_callable($property) ? $property($source, $args, $context, $info) : $property;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,12 +80,12 @@ class ReactPromiseAdapter implements PromiseAdapter
|
|||||||
// TODO: rework with generators when PHP minimum required version is changed to 5.5+
|
// TODO: rework with generators when PHP minimum required version is changed to 5.5+
|
||||||
$promisesOrValues = Utils::map(
|
$promisesOrValues = Utils::map(
|
||||||
$promisesOrValues,
|
$promisesOrValues,
|
||||||
function ($item) {
|
static function ($item) {
|
||||||
return $item instanceof Promise ? $item->adoptedPromise : $item;
|
return $item instanceof Promise ? $item->adoptedPromise : $item;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
$promise = all($promisesOrValues)->then(function ($values) use ($promisesOrValues) {
|
$promise = all($promisesOrValues)->then(static function ($values) use ($promisesOrValues) {
|
||||||
$orderedResults = [];
|
$orderedResults = [];
|
||||||
|
|
||||||
foreach ($promisesOrValues as $key => $value) {
|
foreach ($promisesOrValues as $key => $value) {
|
||||||
|
@ -4,8 +4,10 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Executor\Promise\Adapter;
|
namespace GraphQL\Executor\Promise\Adapter;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Executor\ExecutionResult;
|
use GraphQL\Executor\ExecutionResult;
|
||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
|
use SplQueue;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
use function is_object;
|
use function is_object;
|
||||||
use function method_exists;
|
use function method_exists;
|
||||||
@ -22,7 +24,7 @@ class SyncPromise
|
|||||||
const FULFILLED = 'fulfilled';
|
const FULFILLED = 'fulfilled';
|
||||||
const REJECTED = 'rejected';
|
const REJECTED = 'rejected';
|
||||||
|
|
||||||
/** @var \SplQueue */
|
/** @var SplQueue */
|
||||||
public static $queue;
|
public static $queue;
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
@ -33,6 +35,7 @@ class SyncPromise
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Promises created in `then` method of this promise and awaiting for resolution of this promise
|
* Promises created in `then` method of this promise and awaiting for resolution of this promise
|
||||||
|
*
|
||||||
* @var mixed[][]
|
* @var mixed[][]
|
||||||
*/
|
*/
|
||||||
private $waiting = [];
|
private $waiting = [];
|
||||||
@ -51,7 +54,7 @@ class SyncPromise
|
|||||||
switch ($this->state) {
|
switch ($this->state) {
|
||||||
case self::PENDING:
|
case self::PENDING:
|
||||||
if ($value === $this) {
|
if ($value === $this) {
|
||||||
throw new \Exception('Cannot resolve promise with self');
|
throw new Exception('Cannot resolve promise with self');
|
||||||
}
|
}
|
||||||
if (is_object($value) && method_exists($value, 'then')) {
|
if (is_object($value) && method_exists($value, 'then')) {
|
||||||
$value->then(
|
$value->then(
|
||||||
@ -72,11 +75,11 @@ class SyncPromise
|
|||||||
break;
|
break;
|
||||||
case self::FULFILLED:
|
case self::FULFILLED:
|
||||||
if ($this->result !== $value) {
|
if ($this->result !== $value) {
|
||||||
throw new \Exception('Cannot change value of fulfilled promise');
|
throw new Exception('Cannot change value of fulfilled promise');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case self::REJECTED:
|
case self::REJECTED:
|
||||||
throw new \Exception('Cannot resolve rejected promise');
|
throw new Exception('Cannot resolve rejected promise');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -84,8 +87,8 @@ class SyncPromise
|
|||||||
|
|
||||||
public function reject($reason)
|
public function reject($reason)
|
||||||
{
|
{
|
||||||
if (! $reason instanceof \Exception && ! $reason instanceof \Throwable) {
|
if (! $reason instanceof Exception && ! $reason instanceof Throwable) {
|
||||||
throw new \Exception('SyncPromise::reject() has to be called with an instance of \Throwable');
|
throw new Exception('SyncPromise::reject() has to be called with an instance of \Throwable');
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($this->state) {
|
switch ($this->state) {
|
||||||
@ -96,11 +99,11 @@ class SyncPromise
|
|||||||
break;
|
break;
|
||||||
case self::REJECTED:
|
case self::REJECTED:
|
||||||
if ($reason !== $this->result) {
|
if ($reason !== $this->result) {
|
||||||
throw new \Exception('Cannot change rejection reason');
|
throw new Exception('Cannot change rejection reason');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case self::FULFILLED:
|
case self::FULFILLED:
|
||||||
throw new \Exception('Cannot reject fulfilled promise');
|
throw new Exception('Cannot reject fulfilled promise');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -116,14 +119,14 @@ class SyncPromise
|
|||||||
foreach ($this->waiting as $descriptor) {
|
foreach ($this->waiting as $descriptor) {
|
||||||
self::getQueue()->enqueue(function () use ($descriptor) {
|
self::getQueue()->enqueue(function () use ($descriptor) {
|
||||||
/** @var $promise self */
|
/** @var $promise self */
|
||||||
list($promise, $onFulfilled, $onRejected) = $descriptor;
|
[$promise, $onFulfilled, $onRejected] = $descriptor;
|
||||||
|
|
||||||
if ($this->state === self::FULFILLED) {
|
if ($this->state === self::FULFILLED) {
|
||||||
try {
|
try {
|
||||||
$promise->resolve($onFulfilled ? $onFulfilled($this->result) : $this->result);
|
$promise->resolve($onFulfilled ? $onFulfilled($this->result) : $this->result);
|
||||||
} catch (\Exception $e) {
|
} catch (Exception $e) {
|
||||||
$promise->reject($e);
|
$promise->reject($e);
|
||||||
} catch (\Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
$promise->reject($e);
|
$promise->reject($e);
|
||||||
}
|
}
|
||||||
} elseif ($this->state === self::REJECTED) {
|
} elseif ($this->state === self::REJECTED) {
|
||||||
@ -133,9 +136,9 @@ class SyncPromise
|
|||||||
} else {
|
} else {
|
||||||
$promise->reject($this->result);
|
$promise->reject($this->result);
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (Exception $e) {
|
||||||
$promise->reject($e);
|
$promise->reject($e);
|
||||||
} catch (\Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
$promise->reject($e);
|
$promise->reject($e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,7 +149,7 @@ class SyncPromise
|
|||||||
|
|
||||||
public static function getQueue()
|
public static function getQueue()
|
||||||
{
|
{
|
||||||
return self::$queue ?: self::$queue = new \SplQueue();
|
return self::$queue ?: self::$queue = new SplQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function then(?callable $onFulfilled = null, ?callable $onRejected = null)
|
public function then(?callable $onFulfilled = null, ?callable $onRejected = null)
|
||||||
|
@ -4,12 +4,14 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Executor\Promise\Adapter;
|
namespace GraphQL\Executor\Promise\Adapter;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Deferred;
|
use GraphQL\Deferred;
|
||||||
use GraphQL\Error\InvariantViolation;
|
use GraphQL\Error\InvariantViolation;
|
||||||
use GraphQL\Executor\ExecutionResult;
|
use GraphQL\Executor\ExecutionResult;
|
||||||
use GraphQL\Executor\Promise\Promise;
|
use GraphQL\Executor\Promise\Promise;
|
||||||
use GraphQL\Executor\Promise\PromiseAdapter;
|
use GraphQL\Executor\Promise\PromiseAdapter;
|
||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
|
use Throwable;
|
||||||
use function count;
|
use function count;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,9 +69,9 @@ class SyncPromiseAdapter implements PromiseAdapter
|
|||||||
'reject',
|
'reject',
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
} catch (\Exception $e) {
|
} catch (Exception $e) {
|
||||||
$promise->reject($e);
|
$promise->reject($e);
|
||||||
} catch (\Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
$promise->reject($e);
|
$promise->reject($e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +113,7 @@ class SyncPromiseAdapter implements PromiseAdapter
|
|||||||
if ($promiseOrValue instanceof Promise) {
|
if ($promiseOrValue instanceof Promise) {
|
||||||
$result[$index] = null;
|
$result[$index] = null;
|
||||||
$promiseOrValue->then(
|
$promiseOrValue->then(
|
||||||
function ($value) use ($index, &$count, $total, &$result, $all) {
|
static function ($value) use ($index, &$count, $total, &$result, $all) {
|
||||||
$result[$index] = $value;
|
$result[$index] = $value;
|
||||||
$count++;
|
$count++;
|
||||||
if ($count < $total) {
|
if ($count < $total) {
|
||||||
@ -167,7 +169,6 @@ class SyncPromiseAdapter implements PromiseAdapter
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute just before starting to run promise completion
|
* Execute just before starting to run promise completion
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
protected function beforeWait(Promise $promise)
|
protected function beforeWait(Promise $promise)
|
||||||
{
|
{
|
||||||
@ -175,7 +176,6 @@ class SyncPromiseAdapter implements PromiseAdapter
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute while running promise completion
|
* Execute while running promise completion
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
protected function onWait(Promise $promise)
|
protected function onWait(Promise $promise)
|
||||||
{
|
{
|
||||||
|
@ -24,14 +24,13 @@ class Promise
|
|||||||
*/
|
*/
|
||||||
public function __construct($adoptedPromise, PromiseAdapter $adapter)
|
public function __construct($adoptedPromise, PromiseAdapter $adapter)
|
||||||
{
|
{
|
||||||
Utils::invariant(! $adoptedPromise instanceof self, 'Expecting promise from adapted system, got ' . __CLASS__);
|
Utils::invariant(! $adoptedPromise instanceof self, 'Expecting promise from adapted system, got ' . self::class);
|
||||||
|
|
||||||
$this->adapter = $adapter;
|
$this->adapter = $adapter;
|
||||||
$this->adoptedPromise = $adoptedPromise;
|
$this->adoptedPromise = $adoptedPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @return Promise
|
* @return Promise
|
||||||
*/
|
*/
|
||||||
public function then(?callable $onFulfilled = null, ?callable $onRejected = null)
|
public function then(?callable $onFulfilled = null, ?callable $onRejected = null)
|
||||||
|
@ -4,6 +4,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Executor\Promise;
|
namespace GraphQL\Executor\Promise;
|
||||||
|
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a means for integration of async PHP platforms ([related docs](data-fetching.md#async-php))
|
* Provides a means for integration of async PHP platforms ([related docs](data-fetching.md#async-php))
|
||||||
*/
|
*/
|
||||||
@ -12,18 +14,22 @@ interface PromiseAdapter
|
|||||||
/**
|
/**
|
||||||
* Return true if the value is a promise or a deferred of the underlying platform
|
* Return true if the value is a promise or a deferred of the underlying platform
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function isThenable($value);
|
public function isThenable($value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts thenable of the underlying platform into GraphQL\Executor\Promise\Promise instance
|
* Converts thenable of the underlying platform into GraphQL\Executor\Promise\Promise instance
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param object $thenable
|
* @param object $thenable
|
||||||
|
*
|
||||||
* @return Promise
|
* @return Promise
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function convertThenable($thenable);
|
public function convertThenable($thenable);
|
||||||
|
|
||||||
@ -31,9 +37,9 @@ interface PromiseAdapter
|
|||||||
* Accepts our Promise wrapper, extracts adopted promise out of it and executes actual `then` logic described
|
* Accepts our Promise wrapper, extracts adopted promise out of it and executes actual `then` logic described
|
||||||
* in Promises/A+ specs. Then returns new wrapped instance of GraphQL\Executor\Promise\Promise.
|
* in Promises/A+ specs. Then returns new wrapped instance of GraphQL\Executor\Promise\Promise.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
*
|
|
||||||
* @return Promise
|
* @return Promise
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function then(Promise $promise, ?callable $onFulfilled = null, ?callable $onRejected = null);
|
public function then(Promise $promise, ?callable $onFulfilled = null, ?callable $onRejected = null);
|
||||||
|
|
||||||
@ -43,17 +49,20 @@ interface PromiseAdapter
|
|||||||
* Expected resolver signature:
|
* Expected resolver signature:
|
||||||
* function(callable $resolve, callable $reject)
|
* function(callable $resolve, callable $reject)
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return Promise
|
* @return Promise
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function create(callable $resolver);
|
public function create(callable $resolver);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a fulfilled Promise for a value if the value is not a promise.
|
* Creates a fulfilled Promise for a value if the value is not a promise.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return Promise
|
* @return Promise
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function createFulfilled($value = null);
|
public function createFulfilled($value = null);
|
||||||
|
|
||||||
@ -61,9 +70,11 @@ interface PromiseAdapter
|
|||||||
* Creates a rejected promise for a reason if the reason is not a promise. If
|
* Creates a rejected promise for a reason if the reason is not a promise. If
|
||||||
* the provided reason is a promise, then it is returned as-is.
|
* the provided reason is a promise, then it is returned as-is.
|
||||||
*
|
*
|
||||||
* @api
|
* @param Throwable $reason
|
||||||
* @param \Throwable $reason
|
*
|
||||||
* @return Promise
|
* @return Promise
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function createRejected($reason);
|
public function createRejected($reason);
|
||||||
|
|
||||||
@ -71,9 +82,11 @@ interface PromiseAdapter
|
|||||||
* Given an array of promises (or values), returns a promise that is fulfilled when all the
|
* Given an array of promises (or values), returns a promise that is fulfilled when all the
|
||||||
* items in the array are fulfilled.
|
* items in the array are fulfilled.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param Promise[]|mixed[] $promisesOrValues Promises or values.
|
* @param Promise[]|mixed[] $promisesOrValues Promises or values.
|
||||||
|
*
|
||||||
* @return Promise
|
* @return Promise
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function all(array $promisesOrValues);
|
public function all(array $promisesOrValues);
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ use GraphQL\Utils\AST;
|
|||||||
use GraphQL\Utils\TypeInfo;
|
use GraphQL\Utils\TypeInfo;
|
||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
use GraphQL\Utils\Value;
|
use GraphQL\Utils\Value;
|
||||||
|
use stdClass;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
use function array_map;
|
use function array_map;
|
||||||
@ -41,6 +42,7 @@ class Values
|
|||||||
*
|
*
|
||||||
* @param VariableDefinitionNode[] $varDefNodes
|
* @param VariableDefinitionNode[] $varDefNodes
|
||||||
* @param mixed[] $inputs
|
* @param mixed[] $inputs
|
||||||
|
*
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
*/
|
*/
|
||||||
public static function getVariableValues(Schema $schema, $varDefNodes, array $inputs)
|
public static function getVariableValues(Schema $schema, $varDefNodes, array $inputs)
|
||||||
@ -125,7 +127,7 @@ class Values
|
|||||||
if (isset($node->directives) && $node->directives instanceof NodeList) {
|
if (isset($node->directives) && $node->directives instanceof NodeList) {
|
||||||
$directiveNode = Utils::find(
|
$directiveNode = Utils::find(
|
||||||
$node->directives,
|
$node->directives,
|
||||||
function (DirectiveNode $directive) use ($directiveDef) {
|
static function (DirectiveNode $directive) use ($directiveDef) {
|
||||||
return $directive->name->value === $directiveDef->name;
|
return $directive->name->value === $directiveDef->name;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -145,7 +147,9 @@ class Values
|
|||||||
* @param FieldDefinition|Directive $def
|
* @param FieldDefinition|Directive $def
|
||||||
* @param FieldNode|DirectiveNode $node
|
* @param FieldNode|DirectiveNode $node
|
||||||
* @param mixed[] $variableValues
|
* @param mixed[] $variableValues
|
||||||
|
*
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public static function getArgumentValues($def, $node, $variableValues = null)
|
public static function getArgumentValues($def, $node, $variableValues = null)
|
||||||
@ -162,7 +166,7 @@ class Values
|
|||||||
/** @var ArgumentNode[] $argNodeMap */
|
/** @var ArgumentNode[] $argNodeMap */
|
||||||
$argNodeMap = $argNodes ? Utils::keyMap(
|
$argNodeMap = $argNodes ? Utils::keyMap(
|
||||||
$argNodes,
|
$argNodes,
|
||||||
function (ArgumentNode $arg) {
|
static function (ArgumentNode $arg) {
|
||||||
return $arg->name->value;
|
return $arg->name->value;
|
||||||
}
|
}
|
||||||
) : [];
|
) : [];
|
||||||
@ -223,17 +227,20 @@ class Values
|
|||||||
* @deprecated as of 8.0 (Moved to \GraphQL\Utils\AST::valueFromAST)
|
* @deprecated as of 8.0 (Moved to \GraphQL\Utils\AST::valueFromAST)
|
||||||
*
|
*
|
||||||
* @param ValueNode $valueNode
|
* @param ValueNode $valueNode
|
||||||
* @param null $variables
|
* @param mixed[]|null $variables
|
||||||
* @return mixed[]|null|\stdClass
|
*
|
||||||
|
* @return mixed[]|stdClass|null
|
||||||
*/
|
*/
|
||||||
public static function valueFromAST($valueNode, InputType $type, $variables = null)
|
public static function valueFromAST($valueNode, InputType $type, ?array $variables = null)
|
||||||
{
|
{
|
||||||
return AST::valueFromAST($valueNode, $type, $variables);
|
return AST::valueFromAST($valueNode, $type, $variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated as of 0.12 (Use coerceValue() directly for richer information)
|
* @deprecated as of 0.12 (Use coerceValue() directly for richer information)
|
||||||
|
*
|
||||||
* @param mixed[] $value
|
* @param mixed[] $value
|
||||||
|
*
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
public static function isValidPHPValue($value, InputType $type)
|
public static function isValidPHPValue($value, InputType $type)
|
||||||
@ -242,7 +249,7 @@ class Values
|
|||||||
|
|
||||||
return $errors
|
return $errors
|
||||||
? array_map(
|
? array_map(
|
||||||
function (Throwable $error) {
|
static function (Throwable $error) {
|
||||||
return $error->getMessage();
|
return $error->getMessage();
|
||||||
},
|
},
|
||||||
$errors
|
$errors
|
||||||
|
@ -64,12 +64,13 @@ class GraphQL
|
|||||||
* Empty array would allow to skip query validation (may be convenient for persisted
|
* Empty array would allow to skip query validation (may be convenient for persisted
|
||||||
* queries which are validated before persisting and assumed valid during execution)
|
* queries which are validated before persisting and assumed valid during execution)
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param string|DocumentNode $source
|
* @param string|DocumentNode $source
|
||||||
* @param mixed $rootValue
|
* @param mixed $rootValue
|
||||||
* @param mixed $context
|
* @param mixed $context
|
||||||
* @param mixed[]|null $variableValues
|
* @param mixed[]|null $variableValues
|
||||||
* @param ValidationRule[] $validationRules
|
* @param ValidationRule[] $validationRules
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function executeQuery(
|
public static function executeQuery(
|
||||||
SchemaType $schema,
|
SchemaType $schema,
|
||||||
@ -102,12 +103,13 @@ class GraphQL
|
|||||||
* Same as executeQuery(), but requires PromiseAdapter and always returns a Promise.
|
* Same as executeQuery(), but requires PromiseAdapter and always returns a Promise.
|
||||||
* Useful for Async PHP platforms.
|
* Useful for Async PHP platforms.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param string|DocumentNode $source
|
* @param string|DocumentNode $source
|
||||||
* @param mixed $rootValue
|
* @param mixed $rootValue
|
||||||
* @param mixed $context
|
* @param mixed $context
|
||||||
* @param mixed[]|null $variableValues
|
* @param mixed[]|null $variableValues
|
||||||
* @param ValidationRule[]|null $validationRules
|
* @param ValidationRule[]|null $validationRules
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function promiseToExecute(
|
public static function promiseToExecute(
|
||||||
PromiseAdapter $promiseAdapter,
|
PromiseAdapter $promiseAdapter,
|
||||||
@ -174,6 +176,7 @@ class GraphQL
|
|||||||
* @param mixed $rootValue
|
* @param mixed $rootValue
|
||||||
* @param mixed $contextValue
|
* @param mixed $contextValue
|
||||||
* @param mixed[]|null $variableValues
|
* @param mixed[]|null $variableValues
|
||||||
|
*
|
||||||
* @return Promise|mixed[]
|
* @return Promise|mixed[]
|
||||||
*/
|
*/
|
||||||
public static function execute(
|
public static function execute(
|
||||||
@ -203,7 +206,7 @@ class GraphQL
|
|||||||
if ($promiseAdapter instanceof SyncPromiseAdapter) {
|
if ($promiseAdapter instanceof SyncPromiseAdapter) {
|
||||||
$result = $promiseAdapter->wait($result)->toArray();
|
$result = $promiseAdapter->wait($result)->toArray();
|
||||||
} else {
|
} else {
|
||||||
$result = $result->then(function (ExecutionResult $r) {
|
$result = $result->then(static function (ExecutionResult $r) {
|
||||||
return $r->toArray();
|
return $r->toArray();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -255,8 +258,9 @@ class GraphQL
|
|||||||
/**
|
/**
|
||||||
* Returns directives defined in GraphQL spec
|
* Returns directives defined in GraphQL spec
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return Directive[]
|
* @return Directive[]
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function getStandardDirectives() : array
|
public static function getStandardDirectives() : array
|
||||||
{
|
{
|
||||||
@ -266,8 +270,9 @@ class GraphQL
|
|||||||
/**
|
/**
|
||||||
* Returns types defined in GraphQL spec
|
* Returns types defined in GraphQL spec
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return Type[]
|
* @return Type[]
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function getStandardTypes() : array
|
public static function getStandardTypes() : array
|
||||||
{
|
{
|
||||||
@ -277,8 +282,9 @@ class GraphQL
|
|||||||
/**
|
/**
|
||||||
* Returns standard validation rules implementing GraphQL spec
|
* Returns standard validation rules implementing GraphQL spec
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return ValidationRule[]
|
* @return ValidationRule[]
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function getStandardValidationRules() : array
|
public static function getStandardValidationRules() : array
|
||||||
{
|
{
|
||||||
@ -299,6 +305,7 @@ class GraphQL
|
|||||||
* Returns directives defined in GraphQL spec
|
* Returns directives defined in GraphQL spec
|
||||||
*
|
*
|
||||||
* @deprecated Renamed to getStandardDirectives
|
* @deprecated Renamed to getStandardDirectives
|
||||||
|
*
|
||||||
* @return Directive[]
|
* @return Directive[]
|
||||||
*/
|
*/
|
||||||
public static function getInternalDirectives() : array
|
public static function getInternalDirectives() : array
|
||||||
|
@ -15,7 +15,7 @@ class EnumTypeDefinitionNode extends Node implements TypeDefinitionNode
|
|||||||
/** @var DirectiveNode[] */
|
/** @var DirectiveNode[] */
|
||||||
public $directives;
|
public $directives;
|
||||||
|
|
||||||
/** @var EnumValueDefinitionNode[]|null|NodeList */
|
/** @var EnumValueDefinitionNode[]|NodeList|null */
|
||||||
public $values;
|
public $values;
|
||||||
|
|
||||||
/** @var StringValueNode|null */
|
/** @var StringValueNode|null */
|
||||||
|
@ -51,6 +51,7 @@ class Location
|
|||||||
/**
|
/**
|
||||||
* @param int $start
|
* @param int $start
|
||||||
* @param int $end
|
* @param int $end
|
||||||
|
*
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
public static function create($start, $end)
|
public static function create($start, $end)
|
||||||
|
@ -61,6 +61,7 @@ abstract class Node
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string|NodeList|Location|Node|(Node|NodeList|Location)[] $value
|
* @param string|NodeList|Location|Node|(Node|NodeList|Location)[] $value
|
||||||
|
*
|
||||||
* @return string|NodeList|Location|Node
|
* @return string|NodeList|Location|Node
|
||||||
*/
|
*/
|
||||||
private function cloneValue($value)
|
private function cloneValue($value)
|
||||||
@ -94,6 +95,7 @@ abstract class Node
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $recursive
|
* @param bool $recursive
|
||||||
|
*
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
*/
|
*/
|
||||||
public function toArray($recursive = false)
|
public function toArray($recursive = false)
|
||||||
|
@ -4,19 +4,24 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Language\AST;
|
namespace GraphQL\Language\AST;
|
||||||
|
|
||||||
|
use ArrayAccess;
|
||||||
|
use Countable;
|
||||||
|
use Generator;
|
||||||
use GraphQL\Utils\AST;
|
use GraphQL\Utils\AST;
|
||||||
|
use IteratorAggregate;
|
||||||
use function array_merge;
|
use function array_merge;
|
||||||
use function array_splice;
|
use function array_splice;
|
||||||
use function count;
|
use function count;
|
||||||
use function is_array;
|
use function is_array;
|
||||||
|
|
||||||
class NodeList implements \ArrayAccess, \IteratorAggregate, \Countable
|
class NodeList implements ArrayAccess, IteratorAggregate, Countable
|
||||||
{
|
{
|
||||||
/** @var Node[]|mixed[] */
|
/** @var Node[]|mixed[] */
|
||||||
private $nodes;
|
private $nodes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Node[]|mixed[] $nodes
|
* @param Node[]|mixed[] $nodes
|
||||||
|
*
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
public static function create(array $nodes)
|
public static function create(array $nodes)
|
||||||
@ -25,7 +30,6 @@ class NodeList implements \ArrayAccess, \IteratorAggregate, \Countable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param Node[]|mixed[] $nodes
|
* @param Node[]|mixed[] $nodes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $nodes)
|
public function __construct(array $nodes)
|
||||||
@ -35,6 +39,7 @@ class NodeList implements \ArrayAccess, \IteratorAggregate, \Countable
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $offset
|
* @param mixed $offset
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function offsetExists($offset)
|
public function offsetExists($offset)
|
||||||
@ -44,6 +49,7 @@ class NodeList implements \ArrayAccess, \IteratorAggregate, \Countable
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $offset
|
* @param mixed $offset
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function offsetGet($offset)
|
public function offsetGet($offset)
|
||||||
@ -81,6 +87,7 @@ class NodeList implements \ArrayAccess, \IteratorAggregate, \Countable
|
|||||||
* @param int $offset
|
* @param int $offset
|
||||||
* @param int $length
|
* @param int $length
|
||||||
* @param mixed $replacement
|
* @param mixed $replacement
|
||||||
|
*
|
||||||
* @return NodeList
|
* @return NodeList
|
||||||
*/
|
*/
|
||||||
public function splice($offset, $length, $replacement = null)
|
public function splice($offset, $length, $replacement = null)
|
||||||
@ -90,6 +97,7 @@ class NodeList implements \ArrayAccess, \IteratorAggregate, \Countable
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param NodeList|Node[] $list
|
* @param NodeList|Node[] $list
|
||||||
|
*
|
||||||
* @return NodeList
|
* @return NodeList
|
||||||
*/
|
*/
|
||||||
public function merge($list)
|
public function merge($list)
|
||||||
@ -101,7 +109,7 @@ class NodeList implements \ArrayAccess, \IteratorAggregate, \Countable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \Generator
|
* @return Generator
|
||||||
*/
|
*/
|
||||||
public function getIterator()
|
public function getIterator()
|
||||||
{
|
{
|
||||||
|
@ -55,6 +55,7 @@ class DirectiveLocation
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name
|
* @param string $name
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function has($name)
|
public static function has($name)
|
||||||
|
@ -93,9 +93,7 @@ class Lexer
|
|||||||
public function advance()
|
public function advance()
|
||||||
{
|
{
|
||||||
$this->lastToken = $this->token;
|
$this->lastToken = $this->token;
|
||||||
$token = $this->token = $this->lookahead();
|
return $this->token = $this->lookahead();
|
||||||
|
|
||||||
return $token;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function lookahead()
|
public function lookahead()
|
||||||
@ -112,6 +110,7 @@ class Lexer
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Token
|
* @return Token
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function readToken(Token $prev)
|
private function readToken(Token $prev)
|
||||||
@ -129,7 +128,7 @@ class Lexer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read next char and advance string cursor:
|
// Read next char and advance string cursor:
|
||||||
list (, $code, $bytes) = $this->readChar(true);
|
[, $code, $bytes] = $this->readChar(true);
|
||||||
|
|
||||||
// SourceCharacter
|
// SourceCharacter
|
||||||
if ($code < 0x0020 && $code !== 0x0009 && $code !== 0x000A && $code !== 0x000D) {
|
if ($code < 0x0020 && $code !== 0x0009 && $code !== 0x000A && $code !== 0x000D) {
|
||||||
@ -156,8 +155,8 @@ class Lexer
|
|||||||
case 41: // )
|
case 41: // )
|
||||||
return new Token(Token::PAREN_R, $position, $position + 1, $line, $col, $prev);
|
return new Token(Token::PAREN_R, $position, $position + 1, $line, $col, $prev);
|
||||||
case 46: // .
|
case 46: // .
|
||||||
list (, $charCode1) = $this->readChar(true);
|
[, $charCode1] = $this->readChar(true);
|
||||||
list (, $charCode2) = $this->readChar(true);
|
[, $charCode2] = $this->readChar(true);
|
||||||
|
|
||||||
if ($charCode1 === 46 && $charCode2 === 46) {
|
if ($charCode1 === 46 && $charCode2 === 46) {
|
||||||
return new Token(Token::SPREAD, $position, $position + 3, $line, $col, $prev);
|
return new Token(Token::SPREAD, $position, $position + 3, $line, $col, $prev);
|
||||||
@ -254,8 +253,8 @@ class Lexer
|
|||||||
->readNumber($line, $col, $prev);
|
->readNumber($line, $col, $prev);
|
||||||
// "
|
// "
|
||||||
case 34:
|
case 34:
|
||||||
list(, $nextCode) = $this->readChar();
|
[, $nextCode] = $this->readChar();
|
||||||
list(, $nextNextCode) = $this->moveStringCursor(1, 1)->readChar();
|
[, $nextNextCode] = $this->moveStringCursor(1, 1)->readChar();
|
||||||
|
|
||||||
if ($nextCode === 34 && $nextNextCode === 34) {
|
if ($nextCode === 34 && $nextNextCode === 34) {
|
||||||
return $this->moveStringCursor(-2, (-1 * $bytes) - 1)
|
return $this->moveStringCursor(-2, (-1 * $bytes) - 1)
|
||||||
@ -284,13 +283,14 @@ class Lexer
|
|||||||
*
|
*
|
||||||
* @param int $line
|
* @param int $line
|
||||||
* @param int $col
|
* @param int $col
|
||||||
|
*
|
||||||
* @return Token
|
* @return Token
|
||||||
*/
|
*/
|
||||||
private function readName($line, $col, Token $prev)
|
private function readName($line, $col, Token $prev)
|
||||||
{
|
{
|
||||||
$value = '';
|
$value = '';
|
||||||
$start = $this->position;
|
$start = $this->position;
|
||||||
list ($char, $code) = $this->readChar();
|
[$char, $code] = $this->readChar();
|
||||||
|
|
||||||
while ($code && (
|
while ($code && (
|
||||||
$code === 95 || // _
|
$code === 95 || // _
|
||||||
@ -299,7 +299,7 @@ class Lexer
|
|||||||
$code >= 97 && $code <= 122 // a-z
|
$code >= 97 && $code <= 122 // a-z
|
||||||
)) {
|
)) {
|
||||||
$value .= $char;
|
$value .= $char;
|
||||||
list ($char, $code) = $this->moveStringCursor(1, 1)->readChar();
|
[$char, $code] = $this->moveStringCursor(1, 1)->readChar();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Token(
|
return new Token(
|
||||||
@ -322,26 +322,28 @@ class Lexer
|
|||||||
*
|
*
|
||||||
* @param int $line
|
* @param int $line
|
||||||
* @param int $col
|
* @param int $col
|
||||||
|
*
|
||||||
* @return Token
|
* @return Token
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function readNumber($line, $col, Token $prev)
|
private function readNumber($line, $col, Token $prev)
|
||||||
{
|
{
|
||||||
$value = '';
|
$value = '';
|
||||||
$start = $this->position;
|
$start = $this->position;
|
||||||
list ($char, $code) = $this->readChar();
|
[$char, $code] = $this->readChar();
|
||||||
|
|
||||||
$isFloat = false;
|
$isFloat = false;
|
||||||
|
|
||||||
if ($code === 45) { // -
|
if ($code === 45) { // -
|
||||||
$value .= $char;
|
$value .= $char;
|
||||||
list ($char, $code) = $this->moveStringCursor(1, 1)->readChar();
|
[$char, $code] = $this->moveStringCursor(1, 1)->readChar();
|
||||||
}
|
}
|
||||||
|
|
||||||
// guard against leading zero's
|
// guard against leading zero's
|
||||||
if ($code === 48) { // 0
|
if ($code === 48) { // 0
|
||||||
$value .= $char;
|
$value .= $char;
|
||||||
list ($char, $code) = $this->moveStringCursor(1, 1)->readChar();
|
[$char, $code] = $this->moveStringCursor(1, 1)->readChar();
|
||||||
|
|
||||||
if ($code >= 48 && $code <= 57) {
|
if ($code >= 48 && $code <= 57) {
|
||||||
throw new SyntaxError(
|
throw new SyntaxError(
|
||||||
@ -352,7 +354,7 @@ class Lexer
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$value .= $this->readDigits();
|
$value .= $this->readDigits();
|
||||||
list ($char, $code) = $this->readChar();
|
[$char, $code] = $this->readChar();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($code === 46) { // .
|
if ($code === 46) { // .
|
||||||
@ -361,13 +363,13 @@ class Lexer
|
|||||||
|
|
||||||
$value .= $char;
|
$value .= $char;
|
||||||
$value .= $this->readDigits();
|
$value .= $this->readDigits();
|
||||||
list ($char, $code) = $this->readChar();
|
[$char, $code] = $this->readChar();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($code === 69 || $code === 101) { // E e
|
if ($code === 69 || $code === 101) { // E e
|
||||||
$isFloat = true;
|
$isFloat = true;
|
||||||
$value .= $char;
|
$value .= $char;
|
||||||
list ($char, $code) = $this->moveStringCursor(1, 1)->readChar();
|
[$char, $code] = $this->moveStringCursor(1, 1)->readChar();
|
||||||
|
|
||||||
if ($code === 43 || $code === 45) { // + -
|
if ($code === 43 || $code === 45) { // + -
|
||||||
$value .= $char;
|
$value .= $char;
|
||||||
@ -392,14 +394,14 @@ class Lexer
|
|||||||
*/
|
*/
|
||||||
private function readDigits()
|
private function readDigits()
|
||||||
{
|
{
|
||||||
list ($char, $code) = $this->readChar();
|
[$char, $code] = $this->readChar();
|
||||||
|
|
||||||
if ($code >= 48 && $code <= 57) { // 0 - 9
|
if ($code >= 48 && $code <= 57) { // 0 - 9
|
||||||
$value = '';
|
$value = '';
|
||||||
|
|
||||||
do {
|
do {
|
||||||
$value .= $char;
|
$value .= $char;
|
||||||
list ($char, $code) = $this->moveStringCursor(1, 1)->readChar();
|
[$char, $code] = $this->moveStringCursor(1, 1)->readChar();
|
||||||
} while ($code >= 48 && $code <= 57); // 0 - 9
|
} while ($code >= 48 && $code <= 57); // 0 - 9
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
@ -419,7 +421,9 @@ class Lexer
|
|||||||
/**
|
/**
|
||||||
* @param int $line
|
* @param int $line
|
||||||
* @param int $col
|
* @param int $col
|
||||||
|
*
|
||||||
* @return Token
|
* @return Token
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function readString($line, $col, Token $prev)
|
private function readString($line, $col, Token $prev)
|
||||||
@ -459,7 +463,7 @@ class Lexer
|
|||||||
|
|
||||||
if ($code === 92) { // \
|
if ($code === 92) { // \
|
||||||
$value .= $chunk;
|
$value .= $chunk;
|
||||||
list (, $code) = $this->readChar(true);
|
[, $code] = $this->readChar(true);
|
||||||
|
|
||||||
switch ($code) {
|
switch ($code) {
|
||||||
case 34:
|
case 34:
|
||||||
@ -488,7 +492,7 @@ class Lexer
|
|||||||
break;
|
break;
|
||||||
case 117:
|
case 117:
|
||||||
$position = $this->position;
|
$position = $this->position;
|
||||||
list ($hex) = $this->readChars(4, true);
|
[$hex] = $this->readChars(4, true);
|
||||||
if (! preg_match('/[0-9a-fA-F]{4}/', $hex)) {
|
if (! preg_match('/[0-9a-fA-F]{4}/', $hex)) {
|
||||||
throw new SyntaxError(
|
throw new SyntaxError(
|
||||||
$this->source,
|
$this->source,
|
||||||
@ -512,7 +516,7 @@ class Lexer
|
|||||||
$chunk .= $char;
|
$chunk .= $char;
|
||||||
}
|
}
|
||||||
|
|
||||||
list ($char, $code, $bytes) = $this->readChar();
|
[$char, $code, $bytes] = $this->readChar();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new SyntaxError(
|
throw new SyntaxError(
|
||||||
@ -532,7 +536,7 @@ class Lexer
|
|||||||
$start = $this->position;
|
$start = $this->position;
|
||||||
|
|
||||||
// Skip leading quotes and read first string char:
|
// Skip leading quotes and read first string char:
|
||||||
list ($char, $code, $bytes) = $this->moveStringCursor(3, 3)->readChar();
|
[$char, $code, $bytes] = $this->moveStringCursor(3, 3)->readChar();
|
||||||
|
|
||||||
$chunk = '';
|
$chunk = '';
|
||||||
$value = '';
|
$value = '';
|
||||||
@ -541,8 +545,8 @@ class Lexer
|
|||||||
// Closing Triple-Quote (""")
|
// Closing Triple-Quote (""")
|
||||||
if ($code === 34) {
|
if ($code === 34) {
|
||||||
// Move 2 quotes
|
// Move 2 quotes
|
||||||
list(, $nextCode) = $this->moveStringCursor(1, 1)->readChar();
|
[, $nextCode] = $this->moveStringCursor(1, 1)->readChar();
|
||||||
list(, $nextNextCode) = $this->moveStringCursor(1, 1)->readChar();
|
[, $nextNextCode] = $this->moveStringCursor(1, 1)->readChar();
|
||||||
|
|
||||||
if ($nextCode === 34 && $nextNextCode === 34) {
|
if ($nextCode === 34 && $nextNextCode === 34) {
|
||||||
$value .= $chunk;
|
$value .= $chunk;
|
||||||
@ -567,9 +571,9 @@ class Lexer
|
|||||||
$this->assertValidBlockStringCharacterCode($code, $this->position);
|
$this->assertValidBlockStringCharacterCode($code, $this->position);
|
||||||
$this->moveStringCursor(1, $bytes);
|
$this->moveStringCursor(1, $bytes);
|
||||||
|
|
||||||
list(, $nextCode) = $this->readChar();
|
[, $nextCode] = $this->readChar();
|
||||||
list(, $nextNextCode) = $this->moveStringCursor(1, 1)->readChar();
|
[, $nextNextCode] = $this->moveStringCursor(1, 1)->readChar();
|
||||||
list(, $nextNextNextCode) = $this->moveStringCursor(1, 1)->readChar();
|
[, $nextNextNextCode] = $this->moveStringCursor(1, 1)->readChar();
|
||||||
|
|
||||||
// Escape Triple-Quote (\""")
|
// Escape Triple-Quote (\""")
|
||||||
if ($code === 92 &&
|
if ($code === 92 &&
|
||||||
@ -585,7 +589,7 @@ class Lexer
|
|||||||
$chunk .= $char;
|
$chunk .= $char;
|
||||||
}
|
}
|
||||||
|
|
||||||
list ($char, $code, $bytes) = $this->readChar();
|
[$char, $code, $bytes] = $this->readChar();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new SyntaxError(
|
throw new SyntaxError(
|
||||||
@ -626,7 +630,7 @@ class Lexer
|
|||||||
private function positionAfterWhitespace()
|
private function positionAfterWhitespace()
|
||||||
{
|
{
|
||||||
while ($this->position < $this->source->length) {
|
while ($this->position < $this->source->length) {
|
||||||
list(, $code, $bytes) = $this->readChar();
|
[, $code, $bytes] = $this->readChar();
|
||||||
|
|
||||||
// Skip whitespace
|
// Skip whitespace
|
||||||
// tab | space | comma | BOM
|
// tab | space | comma | BOM
|
||||||
@ -637,7 +641,7 @@ class Lexer
|
|||||||
$this->line++;
|
$this->line++;
|
||||||
$this->lineStart = $this->position;
|
$this->lineStart = $this->position;
|
||||||
} elseif ($code === 13) { // carriage return
|
} elseif ($code === 13) { // carriage return
|
||||||
list(, $nextCode, $nextBytes) = $this->moveStringCursor(1, $bytes)->readChar();
|
[, $nextCode, $nextBytes] = $this->moveStringCursor(1, $bytes)->readChar();
|
||||||
|
|
||||||
if ($nextCode === 10) { // lf after cr
|
if ($nextCode === 10) { // lf after cr
|
||||||
$this->moveStringCursor(1, $nextBytes);
|
$this->moveStringCursor(1, $nextBytes);
|
||||||
@ -657,6 +661,7 @@ class Lexer
|
|||||||
*
|
*
|
||||||
* @param int $line
|
* @param int $line
|
||||||
* @param int $col
|
* @param int $col
|
||||||
|
*
|
||||||
* @return Token
|
* @return Token
|
||||||
*/
|
*/
|
||||||
private function readComment($line, $col, Token $prev)
|
private function readComment($line, $col, Token $prev)
|
||||||
@ -666,7 +671,7 @@ class Lexer
|
|||||||
$bytes = 1;
|
$bytes = 1;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
list ($char, $code, $bytes) = $this->moveStringCursor(1, $bytes)->readChar();
|
[$char, $code, $bytes] = $this->moveStringCursor(1, $bytes)->readChar();
|
||||||
$value .= $char;
|
$value .= $char;
|
||||||
} while ($code &&
|
} while ($code &&
|
||||||
// SourceCharacter but not LineTerminator
|
// SourceCharacter but not LineTerminator
|
||||||
@ -689,6 +694,7 @@ class Lexer
|
|||||||
*
|
*
|
||||||
* @param bool $advance
|
* @param bool $advance
|
||||||
* @param int $byteStreamPosition
|
* @param int $byteStreamPosition
|
||||||
|
*
|
||||||
* @return (string|int)[]
|
* @return (string|int)[]
|
||||||
*/
|
*/
|
||||||
private function readChar($advance = false, $byteStreamPosition = null)
|
private function readChar($advance = false, $byteStreamPosition = null)
|
||||||
@ -736,6 +742,7 @@ class Lexer
|
|||||||
* @param int $charCount
|
* @param int $charCount
|
||||||
* @param bool $advance
|
* @param bool $advance
|
||||||
* @param null $byteStreamPosition
|
* @param null $byteStreamPosition
|
||||||
|
*
|
||||||
* @return (string|int)[]
|
* @return (string|int)[]
|
||||||
*/
|
*/
|
||||||
private function readChars($charCount, $advance = false, $byteStreamPosition = null)
|
private function readChars($charCount, $advance = false, $byteStreamPosition = null)
|
||||||
@ -745,7 +752,7 @@ class Lexer
|
|||||||
$byteOffset = $byteStreamPosition ?: $this->byteStreamPosition;
|
$byteOffset = $byteStreamPosition ?: $this->byteStreamPosition;
|
||||||
|
|
||||||
for ($i = 0; $i < $charCount; $i++) {
|
for ($i = 0; $i < $charCount; $i++) {
|
||||||
list ($char, $code, $bytes) = $this->readChar(false, $byteOffset);
|
[$char, $code, $bytes] = $this->readChar(false, $byteOffset);
|
||||||
$totalBytes += $bytes;
|
$totalBytes += $bytes;
|
||||||
$byteOffset += $bytes;
|
$byteOffset += $bytes;
|
||||||
$result .= $char;
|
$result .= $char;
|
||||||
@ -762,6 +769,7 @@ class Lexer
|
|||||||
*
|
*
|
||||||
* @param int $positionOffset
|
* @param int $positionOffset
|
||||||
* @param int $byteStreamOffset
|
* @param int $byteStreamOffset
|
||||||
|
*
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
private function moveStringCursor($positionOffset, $byteStreamOffset)
|
private function moveStringCursor($positionOffset, $byteStreamOffset)
|
||||||
|
@ -102,11 +102,14 @@ class Parser
|
|||||||
* Note: this feature is experimental and may change or be removed in the
|
* Note: this feature is experimental and may change or be removed in the
|
||||||
* future.)
|
* future.)
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param Source|string $source
|
* @param Source|string $source
|
||||||
* @param bool[] $options
|
* @param bool[] $options
|
||||||
|
*
|
||||||
* @return DocumentNode
|
* @return DocumentNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function parse($source, array $options = [])
|
public static function parse($source, array $options = [])
|
||||||
{
|
{
|
||||||
@ -126,10 +129,12 @@ class Parser
|
|||||||
*
|
*
|
||||||
* Consider providing the results to the utility function: `GraphQL\Utils\AST::valueFromAST()`.
|
* Consider providing the results to the utility function: `GraphQL\Utils\AST::valueFromAST()`.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param Source|string $source
|
* @param Source|string $source
|
||||||
* @param bool[] $options
|
* @param bool[] $options
|
||||||
|
*
|
||||||
* @return BooleanValueNode|EnumValueNode|FloatValueNode|IntValueNode|ListValueNode|ObjectValueNode|StringValueNode|VariableNode
|
* @return BooleanValueNode|EnumValueNode|FloatValueNode|IntValueNode|ListValueNode|ObjectValueNode|StringValueNode|VariableNode
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function parseValue($source, array $options = [])
|
public static function parseValue($source, array $options = [])
|
||||||
{
|
{
|
||||||
@ -152,10 +157,12 @@ class Parser
|
|||||||
*
|
*
|
||||||
* Consider providing the results to the utility function: `GraphQL\Utils\AST::typeFromAST()`.
|
* Consider providing the results to the utility function: `GraphQL\Utils\AST::typeFromAST()`.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param Source|string $source
|
* @param Source|string $source
|
||||||
* @param bool[] $options
|
* @param bool[] $options
|
||||||
|
*
|
||||||
* @return ListTypeNode|NameNode|NonNullTypeNode
|
* @return ListTypeNode|NameNode|NonNullTypeNode
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function parseType($source, array $options = [])
|
public static function parseType($source, array $options = [])
|
||||||
{
|
{
|
||||||
@ -172,7 +179,6 @@ class Parser
|
|||||||
private $lexer;
|
private $lexer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param bool[] $options
|
* @param bool[] $options
|
||||||
*/
|
*/
|
||||||
public function __construct(Source $source, array $options = [])
|
public function __construct(Source $source, array $options = [])
|
||||||
@ -199,6 +205,7 @@ class Parser
|
|||||||
* Determines if the next token is of a given kind
|
* Determines if the next token is of a given kind
|
||||||
*
|
*
|
||||||
* @param string $kind
|
* @param string $kind
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private function peek($kind)
|
private function peek($kind)
|
||||||
@ -211,6 +218,7 @@ class Parser
|
|||||||
* the parser. Otherwise, do not change the parser state and return false.
|
* the parser. Otherwise, do not change the parser state and return false.
|
||||||
*
|
*
|
||||||
* @param string $kind
|
* @param string $kind
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private function skip($kind)
|
private function skip($kind)
|
||||||
@ -227,8 +235,11 @@ class Parser
|
|||||||
/**
|
/**
|
||||||
* If the next token is of the given kind, return that token after advancing
|
* If the next token is of the given kind, return that token after advancing
|
||||||
* the parser. Otherwise, do not change the parser state and return false.
|
* the parser. Otherwise, do not change the parser state and return false.
|
||||||
|
*
|
||||||
* @param string $kind
|
* @param string $kind
|
||||||
|
*
|
||||||
* @return Token
|
* @return Token
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function expect($kind)
|
private function expect($kind)
|
||||||
@ -254,7 +265,9 @@ class Parser
|
|||||||
* false.
|
* false.
|
||||||
*
|
*
|
||||||
* @param string $value
|
* @param string $value
|
||||||
|
*
|
||||||
* @return Token
|
* @return Token
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function expectKeyword($value)
|
private function expectKeyword($value)
|
||||||
@ -292,7 +305,9 @@ class Parser
|
|||||||
* @param string $openKind
|
* @param string $openKind
|
||||||
* @param callable $parseFn
|
* @param callable $parseFn
|
||||||
* @param string $closeKind
|
* @param string $closeKind
|
||||||
|
*
|
||||||
* @return NodeList
|
* @return NodeList
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function any($openKind, $parseFn, $closeKind)
|
private function any($openKind, $parseFn, $closeKind)
|
||||||
@ -316,7 +331,9 @@ class Parser
|
|||||||
* @param string $openKind
|
* @param string $openKind
|
||||||
* @param callable $parseFn
|
* @param callable $parseFn
|
||||||
* @param string $closeKind
|
* @param string $closeKind
|
||||||
|
*
|
||||||
* @return NodeList
|
* @return NodeList
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function many($openKind, $parseFn, $closeKind)
|
private function many($openKind, $parseFn, $closeKind)
|
||||||
@ -335,6 +352,7 @@ class Parser
|
|||||||
* Converts a name lex token into a name parse node.
|
* Converts a name lex token into a name parse node.
|
||||||
*
|
*
|
||||||
* @return NameNode
|
* @return NameNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseName()
|
private function parseName()
|
||||||
@ -351,6 +369,7 @@ class Parser
|
|||||||
* Implements the parsing rules in the Document section.
|
* Implements the parsing rules in the Document section.
|
||||||
*
|
*
|
||||||
* @return DocumentNode
|
* @return DocumentNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseDocument()
|
private function parseDocument()
|
||||||
@ -371,6 +390,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ExecutableDefinitionNode|TypeSystemDefinitionNode
|
* @return ExecutableDefinitionNode|TypeSystemDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseDefinition()
|
private function parseDefinition()
|
||||||
@ -408,6 +428,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ExecutableDefinitionNode
|
* @return ExecutableDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseExecutableDefinition()
|
private function parseExecutableDefinition()
|
||||||
@ -433,6 +454,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return OperationDefinitionNode
|
* @return OperationDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseOperationDefinition()
|
private function parseOperationDefinition()
|
||||||
@ -468,6 +490,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseOperationType()
|
private function parseOperationType()
|
||||||
@ -503,6 +526,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return VariableDefinitionNode
|
* @return VariableDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseVariableDefinition()
|
private function parseVariableDefinition()
|
||||||
@ -524,6 +548,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return VariableNode
|
* @return VariableNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseVariable()
|
private function parseVariable()
|
||||||
@ -575,6 +600,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldNode
|
* @return FieldNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseField()
|
private function parseField()
|
||||||
@ -602,7 +628,9 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $isConst
|
* @param bool $isConst
|
||||||
|
*
|
||||||
* @return ArgumentNode[]|NodeList
|
* @return ArgumentNode[]|NodeList
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseArguments($isConst)
|
private function parseArguments($isConst)
|
||||||
@ -622,6 +650,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ArgumentNode
|
* @return ArgumentNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseArgument()
|
private function parseArgument()
|
||||||
@ -641,6 +670,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ArgumentNode
|
* @return ArgumentNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseConstArgument()
|
private function parseConstArgument()
|
||||||
@ -662,6 +692,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FragmentSpreadNode|InlineFragmentNode
|
* @return FragmentSpreadNode|InlineFragmentNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseFragment()
|
private function parseFragment()
|
||||||
@ -693,6 +724,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FragmentDefinitionNode
|
* @return FragmentDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseFragmentDefinition()
|
private function parseFragmentDefinition()
|
||||||
@ -724,6 +756,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return NameNode
|
* @return NameNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseFragmentName()
|
private function parseFragmentName()
|
||||||
@ -756,7 +789,9 @@ class Parser
|
|||||||
* EnumValue : Name but not `true`, `false` or `null`
|
* EnumValue : Name but not `true`, `false` or `null`
|
||||||
*
|
*
|
||||||
* @param bool $isConst
|
* @param bool $isConst
|
||||||
|
*
|
||||||
* @return BooleanValueNode|EnumValueNode|FloatValueNode|IntValueNode|StringValueNode|VariableNode|ListValueNode|ObjectValueNode|NullValueNode
|
* @return BooleanValueNode|EnumValueNode|FloatValueNode|IntValueNode|StringValueNode|VariableNode|ListValueNode|ObjectValueNode|NullValueNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseValueLiteral($isConst)
|
private function parseValueLiteral($isConst)
|
||||||
@ -834,6 +869,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BooleanValueNode|EnumValueNode|FloatValueNode|IntValueNode|StringValueNode|VariableNode
|
* @return BooleanValueNode|EnumValueNode|FloatValueNode|IntValueNode|StringValueNode|VariableNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseConstValue()
|
private function parseConstValue()
|
||||||
@ -851,6 +887,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $isConst
|
* @param bool $isConst
|
||||||
|
*
|
||||||
* @return ListValueNode
|
* @return ListValueNode
|
||||||
*/
|
*/
|
||||||
private function parseArray($isConst)
|
private function parseArray($isConst)
|
||||||
@ -872,6 +909,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $isConst
|
* @param bool $isConst
|
||||||
|
*
|
||||||
* @return ObjectValueNode
|
* @return ObjectValueNode
|
||||||
*/
|
*/
|
||||||
private function parseObject($isConst)
|
private function parseObject($isConst)
|
||||||
@ -891,6 +929,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $isConst
|
* @param bool $isConst
|
||||||
|
*
|
||||||
* @return ObjectFieldNode
|
* @return ObjectFieldNode
|
||||||
*/
|
*/
|
||||||
private function parseObjectField($isConst)
|
private function parseObjectField($isConst)
|
||||||
@ -911,7 +950,9 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $isConst
|
* @param bool $isConst
|
||||||
|
*
|
||||||
* @return DirectiveNode[]|NodeList
|
* @return DirectiveNode[]|NodeList
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseDirectives($isConst)
|
private function parseDirectives($isConst)
|
||||||
@ -926,7 +967,9 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $isConst
|
* @param bool $isConst
|
||||||
|
*
|
||||||
* @return DirectiveNode
|
* @return DirectiveNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseDirective($isConst)
|
private function parseDirective($isConst)
|
||||||
@ -947,6 +990,7 @@ class Parser
|
|||||||
* Handles the Type: TypeName, ListType, and NonNullType parsing rules.
|
* Handles the Type: TypeName, ListType, and NonNullType parsing rules.
|
||||||
*
|
*
|
||||||
* @return ListTypeNode|NameNode|NonNullTypeNode
|
* @return ListTypeNode|NameNode|NonNullTypeNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseTypeReference()
|
private function parseTypeReference()
|
||||||
@ -1001,6 +1045,7 @@ class Parser
|
|||||||
* - InputObjectTypeDefinition
|
* - InputObjectTypeDefinition
|
||||||
*
|
*
|
||||||
* @return TypeSystemDefinitionNode
|
* @return TypeSystemDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseTypeSystemDefinition()
|
private function parseTypeSystemDefinition()
|
||||||
@ -1056,6 +1101,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return SchemaDefinitionNode
|
* @return SchemaDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseSchemaDefinition()
|
private function parseSchemaDefinition()
|
||||||
@ -1081,6 +1127,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return OperationTypeDefinitionNode
|
* @return OperationTypeDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseOperationTypeDefinition()
|
private function parseOperationTypeDefinition()
|
||||||
@ -1099,6 +1146,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ScalarTypeDefinitionNode
|
* @return ScalarTypeDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseScalarTypeDefinition()
|
private function parseScalarTypeDefinition()
|
||||||
@ -1119,6 +1167,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ObjectTypeDefinitionNode
|
* @return ObjectTypeDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseObjectTypeDefinition()
|
private function parseObjectTypeDefinition()
|
||||||
@ -1168,6 +1217,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldDefinitionNode[]|NodeList
|
* @return FieldDefinitionNode[]|NodeList
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseFieldsDefinition()
|
private function parseFieldsDefinition()
|
||||||
@ -1196,6 +1246,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldDefinitionNode
|
* @return FieldDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseFieldDefinition()
|
private function parseFieldDefinition()
|
||||||
@ -1220,6 +1271,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return InputValueDefinitionNode[]|NodeList
|
* @return InputValueDefinitionNode[]|NodeList
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseArgumentDefs()
|
private function parseArgumentDefs()
|
||||||
@ -1239,6 +1291,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return InputValueDefinitionNode
|
* @return InputValueDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseInputValueDef()
|
private function parseInputValueDef()
|
||||||
@ -1266,6 +1319,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return InterfaceTypeDefinitionNode
|
* @return InterfaceTypeDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseInterfaceTypeDefinition()
|
private function parseInterfaceTypeDefinition()
|
||||||
@ -1291,6 +1345,7 @@ class Parser
|
|||||||
* - Description? union Name Directives[Const]? UnionMemberTypes?
|
* - Description? union Name Directives[Const]? UnionMemberTypes?
|
||||||
*
|
*
|
||||||
* @return UnionTypeDefinitionNode
|
* @return UnionTypeDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseUnionTypeDefinition()
|
private function parseUnionTypeDefinition()
|
||||||
@ -1334,6 +1389,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return EnumTypeDefinitionNode
|
* @return EnumTypeDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseEnumTypeDefinition()
|
private function parseEnumTypeDefinition()
|
||||||
@ -1356,6 +1412,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return EnumValueDefinitionNode[]|NodeList
|
* @return EnumValueDefinitionNode[]|NodeList
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseEnumValuesDefinition()
|
private function parseEnumValuesDefinition()
|
||||||
@ -1373,6 +1430,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return EnumValueDefinitionNode
|
* @return EnumValueDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseEnumValueDefinition()
|
private function parseEnumValueDefinition()
|
||||||
@ -1392,6 +1450,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return InputObjectTypeDefinitionNode
|
* @return InputObjectTypeDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseInputObjectTypeDefinition()
|
private function parseInputObjectTypeDefinition()
|
||||||
@ -1414,6 +1473,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return InputValueDefinitionNode[]|NodeList
|
* @return InputValueDefinitionNode[]|NodeList
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseInputFieldsDefinition()
|
private function parseInputFieldsDefinition()
|
||||||
@ -1439,6 +1499,7 @@ class Parser
|
|||||||
* - InputObjectTypeDefinition
|
* - InputObjectTypeDefinition
|
||||||
*
|
*
|
||||||
* @return TypeExtensionNode
|
* @return TypeExtensionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseTypeExtension()
|
private function parseTypeExtension()
|
||||||
@ -1469,6 +1530,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return SchemaTypeExtensionNode
|
* @return SchemaTypeExtensionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseSchemaTypeExtension()
|
private function parseSchemaTypeExtension()
|
||||||
@ -1496,6 +1558,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ScalarTypeExtensionNode
|
* @return ScalarTypeExtensionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseScalarTypeExtension()
|
private function parseScalarTypeExtension()
|
||||||
@ -1518,6 +1581,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ObjectTypeExtensionNode
|
* @return ObjectTypeExtensionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseObjectTypeExtension()
|
private function parseObjectTypeExtension()
|
||||||
@ -1548,6 +1612,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return InterfaceTypeExtensionNode
|
* @return InterfaceTypeExtensionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseInterfaceTypeExtension()
|
private function parseInterfaceTypeExtension()
|
||||||
@ -1578,6 +1643,7 @@ class Parser
|
|||||||
* - extend union Name Directives[Const]
|
* - extend union Name Directives[Const]
|
||||||
*
|
*
|
||||||
* @return UnionTypeExtensionNode
|
* @return UnionTypeExtensionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseUnionTypeExtension()
|
private function parseUnionTypeExtension()
|
||||||
@ -1604,6 +1670,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return EnumTypeExtensionNode
|
* @return EnumTypeExtensionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseEnumTypeExtension()
|
private function parseEnumTypeExtension()
|
||||||
@ -1630,6 +1697,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return InputObjectTypeExtensionNode
|
* @return InputObjectTypeExtensionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseInputObjectTypeExtension()
|
private function parseInputObjectTypeExtension()
|
||||||
@ -1659,6 +1727,7 @@ class Parser
|
|||||||
* - directive @ Name ArgumentsDefinition? on DirectiveLocations
|
* - directive @ Name ArgumentsDefinition? on DirectiveLocations
|
||||||
*
|
*
|
||||||
* @return DirectiveDefinitionNode
|
* @return DirectiveDefinitionNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseDirectiveDefinition()
|
private function parseDirectiveDefinition()
|
||||||
@ -1683,6 +1752,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return NameNode[]
|
* @return NameNode[]
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseDirectiveLocations()
|
private function parseDirectiveLocations()
|
||||||
@ -1699,6 +1769,7 @@ class Parser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return NameNode
|
* @return NameNode
|
||||||
|
*
|
||||||
* @throws SyntaxError
|
* @throws SyntaxError
|
||||||
*/
|
*/
|
||||||
private function parseDirectiveLocation()
|
private function parseDirectiveLocation()
|
||||||
|
@ -73,9 +73,11 @@ class Printer
|
|||||||
/**
|
/**
|
||||||
* Prints AST to string. Capable of printing GraphQL queries and Type definition language.
|
* Prints AST to string. Capable of printing GraphQL queries and Type definition language.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param Node $ast
|
* @param Node $ast
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function doPrint($ast)
|
public static function doPrint($ast)
|
||||||
{
|
{
|
||||||
@ -95,11 +97,11 @@ class Printer
|
|||||||
$ast,
|
$ast,
|
||||||
[
|
[
|
||||||
'leave' => [
|
'leave' => [
|
||||||
NodeKind::NAME => function (Node $node) {
|
NodeKind::NAME => static function (Node $node) {
|
||||||
return '' . $node->value;
|
return '' . $node->value;
|
||||||
},
|
},
|
||||||
|
|
||||||
NodeKind::VARIABLE => function ($node) {
|
NodeKind::VARIABLE => static function ($node) {
|
||||||
return '$' . $node->name;
|
return '$' . $node->name;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -143,7 +145,7 @@ class Printer
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
NodeKind::ARGUMENT => function (ArgumentNode $node) {
|
NodeKind::ARGUMENT => static function (ArgumentNode $node) {
|
||||||
return $node->name . ': ' . $node->value;
|
return $node->name . ': ' . $node->value;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -172,11 +174,11 @@ class Printer
|
|||||||
. $node->selectionSet;
|
. $node->selectionSet;
|
||||||
},
|
},
|
||||||
|
|
||||||
NodeKind::INT => function (IntValueNode $node) {
|
NodeKind::INT => static function (IntValueNode $node) {
|
||||||
return $node->value;
|
return $node->value;
|
||||||
},
|
},
|
||||||
|
|
||||||
NodeKind::FLOAT => function (FloatValueNode $node) {
|
NodeKind::FLOAT => static function (FloatValueNode $node) {
|
||||||
return $node->value;
|
return $node->value;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -188,15 +190,15 @@ class Printer
|
|||||||
return json_encode($node->value);
|
return json_encode($node->value);
|
||||||
},
|
},
|
||||||
|
|
||||||
NodeKind::BOOLEAN => function (BooleanValueNode $node) {
|
NodeKind::BOOLEAN => static function (BooleanValueNode $node) {
|
||||||
return $node->value ? 'true' : 'false';
|
return $node->value ? 'true' : 'false';
|
||||||
},
|
},
|
||||||
|
|
||||||
NodeKind::NULL => function (NullValueNode $node) {
|
NodeKind::NULL => static function (NullValueNode $node) {
|
||||||
return 'null';
|
return 'null';
|
||||||
},
|
},
|
||||||
|
|
||||||
NodeKind::ENUM => function (EnumValueNode $node) {
|
NodeKind::ENUM => static function (EnumValueNode $node) {
|
||||||
return $node->value;
|
return $node->value;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -208,7 +210,7 @@ class Printer
|
|||||||
return '{' . $this->join($node->fields, ', ') . '}';
|
return '{' . $this->join($node->fields, ', ') . '}';
|
||||||
},
|
},
|
||||||
|
|
||||||
NodeKind::OBJECT_FIELD => function (ObjectFieldNode $node) {
|
NodeKind::OBJECT_FIELD => static function (ObjectFieldNode $node) {
|
||||||
return $node->name . ': ' . $node->value;
|
return $node->name . ': ' . $node->value;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -216,15 +218,15 @@ class Printer
|
|||||||
return '@' . $node->name . $this->wrap('(', $this->join($node->arguments, ', '), ')');
|
return '@' . $node->name . $this->wrap('(', $this->join($node->arguments, ', '), ')');
|
||||||
},
|
},
|
||||||
|
|
||||||
NodeKind::NAMED_TYPE => function (NamedTypeNode $node) {
|
NodeKind::NAMED_TYPE => static function (NamedTypeNode $node) {
|
||||||
return $node->name;
|
return $node->name;
|
||||||
},
|
},
|
||||||
|
|
||||||
NodeKind::LIST_TYPE => function (ListTypeNode $node) {
|
NodeKind::LIST_TYPE => static function (ListTypeNode $node) {
|
||||||
return '[' . $node->type . ']';
|
return '[' . $node->type . ']';
|
||||||
},
|
},
|
||||||
|
|
||||||
NodeKind::NON_NULL_TYPE => function (NonNullTypeNode $node) {
|
NodeKind::NON_NULL_TYPE => static function (NonNullTypeNode $node) {
|
||||||
return $node->type . '!';
|
return $node->type . '!';
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -239,7 +241,7 @@ class Printer
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
NodeKind::OPERATION_TYPE_DEFINITION => function (OperationTypeDefinitionNode $def) {
|
NodeKind::OPERATION_TYPE_DEFINITION => static function (OperationTypeDefinitionNode $def) {
|
||||||
return $def->operation . ': ' . $def->type;
|
return $def->operation . ': ' . $def->type;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -432,7 +434,7 @@ class Printer
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addDescription(\Closure $cb)
|
public function addDescription(callable $cb)
|
||||||
{
|
{
|
||||||
return function ($node) use ($cb) {
|
return function ($node) use ($cb) {
|
||||||
return $this->join([$node->description, $cb($node)], "\n");
|
return $this->join([$node->description, $cb($node)], "\n");
|
||||||
@ -454,7 +456,7 @@ class Printer
|
|||||||
*/
|
*/
|
||||||
public function block($array)
|
public function block($array)
|
||||||
{
|
{
|
||||||
return ($array && $this->length($array))
|
return $array && $this->length($array)
|
||||||
? "{\n" . $this->indent($this->join($array, "\n")) . "\n}"
|
? "{\n" . $this->indent($this->join($array, "\n")) . "\n}"
|
||||||
: '';
|
: '';
|
||||||
}
|
}
|
||||||
@ -481,7 +483,7 @@ class Printer
|
|||||||
$separator,
|
$separator,
|
||||||
Utils::filter(
|
Utils::filter(
|
||||||
$maybeArray,
|
$maybeArray,
|
||||||
function ($x) {
|
static function ($x) {
|
||||||
return (bool) $x;
|
return (bool) $x;
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -498,7 +500,7 @@ class Printer
|
|||||||
{
|
{
|
||||||
$escaped = str_replace('"""', '\\"""', $value);
|
$escaped = str_replace('"""', '\\"""', $value);
|
||||||
|
|
||||||
return (($value[0] === ' ' || $value[0] === "\t") && strpos($value, "\n") === false)
|
return ($value[0] === ' ' || $value[0] === "\t") && strpos($value, "\n") === false
|
||||||
? ('"""' . preg_replace('/"$/', "\"\n", $escaped) . '"""')
|
? ('"""' . preg_replace('/"$/', "\"\n", $escaped) . '"""')
|
||||||
: ('"""' . "\n" . ($isDescription ? $escaped : $this->indent($escaped)) . "\n" . '"""');
|
: ('"""' . "\n" . ($isDescription ? $escaped : $this->indent($escaped)) . "\n" . '"""');
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,6 @@ class Source
|
|||||||
public $locationOffset;
|
public $locationOffset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
*
|
|
||||||
* A representation of source input to GraphQL.
|
* A representation of source input to GraphQL.
|
||||||
* `name` and `locationOffset` are optional. They are useful for clients who
|
* `name` and `locationOffset` are optional. They are useful for clients who
|
||||||
* store GraphQL documents in source files; for example, if the GraphQL input
|
* store GraphQL documents in source files; for example, if the GraphQL input
|
||||||
@ -63,6 +61,7 @@ class Source
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $position
|
* @param int $position
|
||||||
|
*
|
||||||
* @return SourceLocation
|
* @return SourceLocation
|
||||||
*/
|
*/
|
||||||
public function getLocation($position)
|
public function getLocation($position)
|
||||||
|
@ -4,7 +4,9 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Language;
|
namespace GraphQL\Language;
|
||||||
|
|
||||||
class SourceLocation implements \JsonSerializable
|
use JsonSerializable;
|
||||||
|
|
||||||
|
class SourceLocation implements JsonSerializable
|
||||||
{
|
{
|
||||||
/** @var int */
|
/** @var int */
|
||||||
public $line;
|
public $line;
|
||||||
|
@ -85,7 +85,6 @@ class Token
|
|||||||
public $next;
|
public $next;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param string $kind
|
* @param string $kind
|
||||||
* @param int $start
|
* @param int $start
|
||||||
* @param int $end
|
* @param int $end
|
||||||
|
@ -5,10 +5,12 @@ declare(strict_types=1);
|
|||||||
namespace GraphQL\Language;
|
namespace GraphQL\Language;
|
||||||
|
|
||||||
use ArrayObject;
|
use ArrayObject;
|
||||||
|
use Exception;
|
||||||
use GraphQL\Language\AST\Node;
|
use GraphQL\Language\AST\Node;
|
||||||
use GraphQL\Language\AST\NodeKind;
|
use GraphQL\Language\AST\NodeKind;
|
||||||
use GraphQL\Language\AST\NodeList;
|
use GraphQL\Language\AST\NodeList;
|
||||||
use GraphQL\Utils\TypeInfo;
|
use GraphQL\Utils\TypeInfo;
|
||||||
|
use SplFixedArray;
|
||||||
use stdClass;
|
use stdClass;
|
||||||
use function array_pop;
|
use function array_pop;
|
||||||
use function array_splice;
|
use function array_splice;
|
||||||
@ -172,12 +174,15 @@ class Visitor
|
|||||||
/**
|
/**
|
||||||
* Visit the AST (see class description for details)
|
* Visit the AST (see class description for details)
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param Node|ArrayObject|stdClass $root
|
* @param Node|ArrayObject|stdClass $root
|
||||||
* @param callable[] $visitor
|
* @param callable[] $visitor
|
||||||
* @param mixed[]|null $keyMap
|
* @param mixed[]|null $keyMap
|
||||||
|
*
|
||||||
* @return Node|mixed
|
* @return Node|mixed
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function visit($root, $visitor, $keyMap = null)
|
public static function visit($root, $visitor, $keyMap = null)
|
||||||
{
|
{
|
||||||
@ -247,7 +252,7 @@ class Visitor
|
|||||||
$stack = $stack['prev'];
|
$stack = $stack['prev'];
|
||||||
} else {
|
} else {
|
||||||
$key = $parent ? ($inArray ? $index : $keys[$index]) : $UNDEFINED;
|
$key = $parent ? ($inArray ? $index : $keys[$index]) : $UNDEFINED;
|
||||||
$node = $parent ? (($parent instanceof NodeList || is_array($parent)) ? $parent[$key] : $parent->{$key}) : $newRoot;
|
$node = $parent ? ($parent instanceof NodeList || is_array($parent) ? $parent[$key] : $parent->{$key}) : $newRoot;
|
||||||
if ($node === null || $node === $UNDEFINED) {
|
if ($node === null || $node === $UNDEFINED) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -259,7 +264,7 @@ class Visitor
|
|||||||
$result = null;
|
$result = null;
|
||||||
if (! $node instanceof NodeList && ! is_array($node)) {
|
if (! $node instanceof NodeList && ! is_array($node)) {
|
||||||
if (! ($node instanceof Node)) {
|
if (! ($node instanceof Node)) {
|
||||||
throw new \Exception('Invalid AST Node: ' . json_encode($node));
|
throw new Exception('Invalid AST Node: ' . json_encode($node));
|
||||||
}
|
}
|
||||||
|
|
||||||
$visitFn = self::getVisitFn($visitor, $node->kind, $isLeaving);
|
$visitFn = self::getVisitFn($visitor, $node->kind, $isLeaving);
|
||||||
@ -333,8 +338,9 @@ class Visitor
|
|||||||
/**
|
/**
|
||||||
* Returns marker for visitor break
|
* Returns marker for visitor break
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return VisitorOperation
|
* @return VisitorOperation
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function stop()
|
public static function stop()
|
||||||
{
|
{
|
||||||
@ -347,8 +353,9 @@ class Visitor
|
|||||||
/**
|
/**
|
||||||
* Returns marker for skipping current node
|
* Returns marker for skipping current node
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return VisitorOperation
|
* @return VisitorOperation
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function skipNode()
|
public static function skipNode()
|
||||||
{
|
{
|
||||||
@ -361,8 +368,9 @@ class Visitor
|
|||||||
/**
|
/**
|
||||||
* Returns marker for removing a node
|
* Returns marker for removing a node
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return VisitorOperation
|
* @return VisitorOperation
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function removeNode()
|
public static function removeNode()
|
||||||
{
|
{
|
||||||
@ -374,15 +382,16 @@ class Visitor
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param callable[][] $visitors
|
* @param callable[][] $visitors
|
||||||
|
*
|
||||||
* @return callable[][]
|
* @return callable[][]
|
||||||
*/
|
*/
|
||||||
public static function visitInParallel($visitors)
|
public static function visitInParallel($visitors)
|
||||||
{
|
{
|
||||||
$visitorsCount = count($visitors);
|
$visitorsCount = count($visitors);
|
||||||
$skipping = new \SplFixedArray($visitorsCount);
|
$skipping = new SplFixedArray($visitorsCount);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'enter' => function (Node $node) use ($visitors, $skipping, $visitorsCount) {
|
'enter' => static function (Node $node) use ($visitors, $skipping, $visitorsCount) {
|
||||||
for ($i = 0; $i < $visitorsCount; $i++) {
|
for ($i = 0; $i < $visitorsCount; $i++) {
|
||||||
if (! empty($skipping[$i])) {
|
if (! empty($skipping[$i])) {
|
||||||
continue;
|
continue;
|
||||||
@ -413,7 +422,7 @@ class Visitor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'leave' => function (Node $node) use ($visitors, $skipping, $visitorsCount) {
|
'leave' => static function (Node $node) use ($visitors, $skipping, $visitorsCount) {
|
||||||
for ($i = 0; $i < $visitorsCount; $i++) {
|
for ($i = 0; $i < $visitorsCount; $i++) {
|
||||||
if (empty($skipping[$i])) {
|
if (empty($skipping[$i])) {
|
||||||
$fn = self::getVisitFn(
|
$fn = self::getVisitFn(
|
||||||
@ -449,7 +458,7 @@ class Visitor
|
|||||||
public static function visitWithTypeInfo(TypeInfo $typeInfo, $visitor)
|
public static function visitWithTypeInfo(TypeInfo $typeInfo, $visitor)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'enter' => function (Node $node) use ($typeInfo, $visitor) {
|
'enter' => static function (Node $node) use ($typeInfo, $visitor) {
|
||||||
$typeInfo->enter($node);
|
$typeInfo->enter($node);
|
||||||
$fn = self::getVisitFn($visitor, $node->kind, false);
|
$fn = self::getVisitFn($visitor, $node->kind, false);
|
||||||
|
|
||||||
@ -467,7 +476,7 @@ class Visitor
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
'leave' => function (Node $node) use ($typeInfo, $visitor) {
|
'leave' => static function (Node $node) use ($typeInfo, $visitor) {
|
||||||
$fn = self::getVisitFn($visitor, $node->kind, true);
|
$fn = self::getVisitFn($visitor, $node->kind, true);
|
||||||
$result = $fn ? call_user_func_array($fn, func_get_args()) : null;
|
$result = $fn ? call_user_func_array($fn, func_get_args()) : null;
|
||||||
$typeInfo->leave($node);
|
$typeInfo->leave($node);
|
||||||
@ -481,6 +490,7 @@ class Visitor
|
|||||||
* @param callable[]|null $visitor
|
* @param callable[]|null $visitor
|
||||||
* @param string $kind
|
* @param string $kind
|
||||||
* @param bool $isLeaving
|
* @param bool $isLeaving
|
||||||
|
*
|
||||||
* @return callable|null
|
* @return callable|null
|
||||||
*/
|
*/
|
||||||
public static function getVisitFn($visitor, $kind, $isLeaving)
|
public static function getVisitFn($visitor, $kind, $isLeaving)
|
||||||
|
@ -17,6 +17,7 @@ use GraphQL\Language\AST\DocumentNode;
|
|||||||
use GraphQL\Language\Parser;
|
use GraphQL\Language\Parser;
|
||||||
use GraphQL\Utils\AST;
|
use GraphQL\Utils\AST;
|
||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
|
use JsonSerializable;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Psr\Http\Message\StreamInterface;
|
use Psr\Http\Message\StreamInterface;
|
||||||
@ -52,9 +53,11 @@ class Helper
|
|||||||
*
|
*
|
||||||
* For PSR-7 request parsing use `parsePsrRequest()` instead.
|
* For PSR-7 request parsing use `parsePsrRequest()` instead.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return OperationParams|OperationParams[]
|
* @return OperationParams|OperationParams[]
|
||||||
|
*
|
||||||
* @throws RequestError
|
* @throws RequestError
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function parseHttpRequest(?callable $readRawBodyFn = null)
|
public function parseHttpRequest(?callable $readRawBodyFn = null)
|
||||||
{
|
{
|
||||||
@ -104,12 +107,15 @@ class Helper
|
|||||||
*
|
*
|
||||||
* Returned value is a suitable input for `executeOperation` or `executeBatch` (if array)
|
* Returned value is a suitable input for `executeOperation` or `executeBatch` (if array)
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param string $method
|
* @param string $method
|
||||||
* @param mixed[] $bodyParams
|
* @param mixed[] $bodyParams
|
||||||
* @param mixed[] $queryParams
|
* @param mixed[] $queryParams
|
||||||
|
*
|
||||||
* @return OperationParams|OperationParams[]
|
* @return OperationParams|OperationParams[]
|
||||||
|
*
|
||||||
* @throws RequestError
|
* @throws RequestError
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function parseRequestParams($method, array $bodyParams, array $queryParams)
|
public function parseRequestParams($method, array $bodyParams, array $queryParams)
|
||||||
{
|
{
|
||||||
@ -136,8 +142,9 @@ class Helper
|
|||||||
* Checks validity of OperationParams extracted from HTTP request and returns an array of errors
|
* Checks validity of OperationParams extracted from HTTP request and returns an array of errors
|
||||||
* if params are invalid (or empty array when params are valid)
|
* if params are invalid (or empty array when params are valid)
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return Error[]
|
* @return Error[]
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function validateOperationParams(OperationParams $params)
|
public function validateOperationParams(OperationParams $params)
|
||||||
{
|
{
|
||||||
@ -185,9 +192,9 @@ class Helper
|
|||||||
* Executes GraphQL operation with given server configuration and returns execution result
|
* Executes GraphQL operation with given server configuration and returns execution result
|
||||||
* (or promise when promise adapter is different from SyncPromiseAdapter)
|
* (or promise when promise adapter is different from SyncPromiseAdapter)
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
*
|
|
||||||
* @return ExecutionResult|Promise
|
* @return ExecutionResult|Promise
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function executeOperation(ServerConfig $config, OperationParams $op)
|
public function executeOperation(ServerConfig $config, OperationParams $op)
|
||||||
{
|
{
|
||||||
@ -205,9 +212,11 @@ class Helper
|
|||||||
* Executes batched GraphQL operations with shared promise queue
|
* Executes batched GraphQL operations with shared promise queue
|
||||||
* (thus, effectively batching deferreds|promises of all queries at once)
|
* (thus, effectively batching deferreds|promises of all queries at once)
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param OperationParams[] $operations
|
* @param OperationParams[] $operations
|
||||||
|
*
|
||||||
* @return ExecutionResult|ExecutionResult[]|Promise
|
* @return ExecutionResult|ExecutionResult[]|Promise
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function executeBatch(ServerConfig $config, array $operations)
|
public function executeBatch(ServerConfig $config, array $operations)
|
||||||
{
|
{
|
||||||
@ -230,6 +239,7 @@ class Helper
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $isBatch
|
* @param bool $isBatch
|
||||||
|
*
|
||||||
* @return Promise
|
* @return Promise
|
||||||
*/
|
*/
|
||||||
private function promiseToExecuteOperation(
|
private function promiseToExecuteOperation(
|
||||||
@ -252,7 +262,7 @@ class Helper
|
|||||||
if (! empty($errors)) {
|
if (! empty($errors)) {
|
||||||
$errors = Utils::map(
|
$errors = Utils::map(
|
||||||
$errors,
|
$errors,
|
||||||
function (RequestError $err) {
|
static function (RequestError $err) {
|
||||||
return Error::createLocatedError($err, null, null);
|
return Error::createLocatedError($err, null, null);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -294,7 +304,7 @@ class Helper
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$applyErrorHandling = function (ExecutionResult $result) use ($config) {
|
$applyErrorHandling = static function (ExecutionResult $result) use ($config) {
|
||||||
if ($config->getErrorsHandler()) {
|
if ($config->getErrorsHandler()) {
|
||||||
$result->setErrorsHandler($config->getErrorsHandler());
|
$result->setErrorsHandler($config->getErrorsHandler());
|
||||||
}
|
}
|
||||||
@ -315,6 +325,7 @@ class Helper
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
*
|
||||||
* @throws RequestError
|
* @throws RequestError
|
||||||
*/
|
*/
|
||||||
private function loadPersistedQuery(ServerConfig $config, OperationParams $operationParams)
|
private function loadPersistedQuery(ServerConfig $config, OperationParams $operationParams)
|
||||||
@ -341,6 +352,7 @@ class Helper
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $operationType
|
* @param string $operationType
|
||||||
|
*
|
||||||
* @return mixed[]|null
|
* @return mixed[]|null
|
||||||
*/
|
*/
|
||||||
private function resolveValidationRules(
|
private function resolveValidationRules(
|
||||||
@ -368,13 +380,14 @@ class Helper
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $operationType
|
* @param string $operationType
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
private function resolveRootValue(ServerConfig $config, OperationParams $params, DocumentNode $doc, $operationType)
|
private function resolveRootValue(ServerConfig $config, OperationParams $params, DocumentNode $doc, $operationType)
|
||||||
{
|
{
|
||||||
$root = $config->getRootValue();
|
$root = $config->getRootValue();
|
||||||
|
|
||||||
if ($root instanceof \Closure) {
|
if (is_callable($root)) {
|
||||||
$root = $root($params, $doc, $operationType);
|
$root = $root($params, $doc, $operationType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,6 +396,7 @@ class Helper
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $operationType
|
* @param string $operationType
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
private function resolveContextValue(
|
private function resolveContextValue(
|
||||||
@ -393,7 +407,7 @@ class Helper
|
|||||||
) {
|
) {
|
||||||
$context = $config->getContext();
|
$context = $config->getContext();
|
||||||
|
|
||||||
if ($context instanceof \Closure) {
|
if (is_callable($context)) {
|
||||||
$context = $context($params, $doc, $operationType);
|
$context = $context($params, $doc, $operationType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,9 +417,10 @@ class Helper
|
|||||||
/**
|
/**
|
||||||
* Send response using standard PHP `header()` and `echo`.
|
* Send response using standard PHP `header()` and `echo`.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param Promise|ExecutionResult|ExecutionResult[] $result
|
* @param Promise|ExecutionResult|ExecutionResult[] $result
|
||||||
* @param bool $exitWhenDone
|
* @param bool $exitWhenDone
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function sendResponse($result, $exitWhenDone = false)
|
public function sendResponse($result, $exitWhenDone = false)
|
||||||
{
|
{
|
||||||
@ -425,7 +440,7 @@ class Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed[]|\JsonSerializable $jsonSerializable
|
* @param mixed[]|JsonSerializable $jsonSerializable
|
||||||
* @param int $httpStatus
|
* @param int $httpStatus
|
||||||
* @param bool $exitWhenDone
|
* @param bool $exitWhenDone
|
||||||
*/
|
*/
|
||||||
@ -450,6 +465,7 @@ class Helper
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ExecutionResult|mixed[] $result
|
* @param ExecutionResult|mixed[] $result
|
||||||
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
private function resolveHttpStatus($result)
|
private function resolveHttpStatus($result)
|
||||||
@ -457,7 +473,7 @@ class Helper
|
|||||||
if (is_array($result) && isset($result[0])) {
|
if (is_array($result) && isset($result[0])) {
|
||||||
Utils::each(
|
Utils::each(
|
||||||
$result,
|
$result,
|
||||||
function ($executionResult, $index) {
|
static function ($executionResult, $index) {
|
||||||
if (! $executionResult instanceof ExecutionResult) {
|
if (! $executionResult instanceof ExecutionResult) {
|
||||||
throw new InvariantViolation(sprintf(
|
throw new InvariantViolation(sprintf(
|
||||||
'Expecting every entry of batched query result to be instance of %s but entry at position %d is %s',
|
'Expecting every entry of batched query result to be instance of %s but entry at position %d is %s',
|
||||||
@ -490,9 +506,11 @@ class Helper
|
|||||||
/**
|
/**
|
||||||
* Converts PSR-7 request to OperationParams[]
|
* Converts PSR-7 request to OperationParams[]
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return OperationParams[]|OperationParams
|
* @return OperationParams[]|OperationParams
|
||||||
|
*
|
||||||
* @throws RequestError
|
* @throws RequestError
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function parsePsrRequest(ServerRequestInterface $request)
|
public function parsePsrRequest(ServerRequestInterface $request)
|
||||||
{
|
{
|
||||||
@ -541,9 +559,11 @@ class Helper
|
|||||||
/**
|
/**
|
||||||
* Converts query execution result to PSR-7 response
|
* Converts query execution result to PSR-7 response
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param Promise|ExecutionResult|ExecutionResult[] $result
|
* @param Promise|ExecutionResult|ExecutionResult[] $result
|
||||||
|
*
|
||||||
* @return Promise|ResponseInterface
|
* @return Promise|ResponseInterface
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function toPsrResponse($result, ResponseInterface $response, StreamInterface $writableBodyStream)
|
public function toPsrResponse($result, ResponseInterface $response, StreamInterface $writableBodyStream)
|
||||||
{
|
{
|
||||||
|
@ -55,10 +55,12 @@ class OperationParams
|
|||||||
/**
|
/**
|
||||||
* Creates an instance from given array
|
* Creates an instance from given array
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param mixed[] $params
|
* @param mixed[] $params
|
||||||
* @param bool $readonly
|
* @param bool $readonly
|
||||||
|
*
|
||||||
* @return OperationParams
|
* @return OperationParams
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function create(array $params, $readonly = false)
|
public static function create(array $params, $readonly = false)
|
||||||
{
|
{
|
||||||
@ -97,9 +99,11 @@ class OperationParams
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param string $key
|
* @param string $key
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getOriginalInput($key)
|
public function getOriginalInput($key)
|
||||||
{
|
{
|
||||||
@ -110,8 +114,9 @@ class OperationParams
|
|||||||
* Indicates that operation is executed in read-only context
|
* Indicates that operation is executed in read-only context
|
||||||
* (e.g. via HTTP GET request)
|
* (e.g. via HTTP GET request)
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return bool
|
* @return bool
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function isReadOnly()
|
public function isReadOnly()
|
||||||
{
|
{
|
||||||
|
@ -4,9 +4,10 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Server;
|
namespace GraphQL\Server;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\ClientAware;
|
use GraphQL\Error\ClientAware;
|
||||||
|
|
||||||
class RequestError extends \Exception implements ClientAware
|
class RequestError extends Exception implements ClientAware
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Returns true when exception message is safe to be displayed to client
|
* Returns true when exception message is safe to be displayed to client
|
||||||
|
@ -34,9 +34,11 @@ class ServerConfig
|
|||||||
* Converts an array of options to instance of ServerConfig
|
* Converts an array of options to instance of ServerConfig
|
||||||
* (or just returns empty config when array is not passed).
|
* (or just returns empty config when array is not passed).
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param mixed[] $config
|
* @param mixed[] $config
|
||||||
|
*
|
||||||
* @return ServerConfig
|
* @return ServerConfig
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function create(array $config = [])
|
public static function create(array $config = [])
|
||||||
{
|
{
|
||||||
@ -55,10 +57,10 @@ class ServerConfig
|
|||||||
/** @var Schema */
|
/** @var Schema */
|
||||||
private $schema;
|
private $schema;
|
||||||
|
|
||||||
/** @var mixed|\Closure */
|
/** @var mixed|callable */
|
||||||
private $context;
|
private $context;
|
||||||
|
|
||||||
/** @var mixed|\Closure */
|
/** @var mixed|callable */
|
||||||
private $rootValue;
|
private $rootValue;
|
||||||
|
|
||||||
/** @var callable|null */
|
/** @var callable|null */
|
||||||
@ -86,8 +88,9 @@ class ServerConfig
|
|||||||
private $persistentQueryLoader;
|
private $persistentQueryLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @return self
|
* @return self
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setSchema(Schema $schema)
|
public function setSchema(Schema $schema)
|
||||||
{
|
{
|
||||||
@ -97,9 +100,11 @@ class ServerConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
* @param mixed|callable $context
|
||||||
* @param mixed|\Closure $context
|
*
|
||||||
* @return self
|
* @return self
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setContext($context)
|
public function setContext($context)
|
||||||
{
|
{
|
||||||
@ -109,9 +114,11 @@ class ServerConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
* @param mixed|callable $rootValue
|
||||||
* @param mixed|\Closure $rootValue
|
*
|
||||||
* @return self
|
* @return self
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setRootValue($rootValue)
|
public function setRootValue($rootValue)
|
||||||
{
|
{
|
||||||
@ -123,8 +130,9 @@ class ServerConfig
|
|||||||
/**
|
/**
|
||||||
* Expects function(Throwable $e) : array
|
* Expects function(Throwable $e) : array
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return self
|
* @return self
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setErrorFormatter(callable $errorFormatter)
|
public function setErrorFormatter(callable $errorFormatter)
|
||||||
{
|
{
|
||||||
@ -136,8 +144,9 @@ class ServerConfig
|
|||||||
/**
|
/**
|
||||||
* Expects function(array $errors, callable $formatter) : array
|
* Expects function(array $errors, callable $formatter) : array
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return self
|
* @return self
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setErrorsHandler(callable $handler)
|
public function setErrorsHandler(callable $handler)
|
||||||
{
|
{
|
||||||
@ -149,9 +158,11 @@ class ServerConfig
|
|||||||
/**
|
/**
|
||||||
* Set validation rules for this server.
|
* Set validation rules for this server.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param ValidationRule[]|callable $validationRules
|
* @param ValidationRule[]|callable $validationRules
|
||||||
|
*
|
||||||
* @return self
|
* @return self
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setValidationRules($validationRules)
|
public function setValidationRules($validationRules)
|
||||||
{
|
{
|
||||||
@ -168,8 +179,9 @@ class ServerConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @return self
|
* @return self
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setFieldResolver(callable $fieldResolver)
|
public function setFieldResolver(callable $fieldResolver)
|
||||||
{
|
{
|
||||||
@ -183,8 +195,9 @@ class ServerConfig
|
|||||||
*
|
*
|
||||||
* This function must return query string or valid DocumentNode.
|
* This function must return query string or valid DocumentNode.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return self
|
* @return self
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setPersistentQueryLoader(callable $persistentQueryLoader)
|
public function setPersistentQueryLoader(callable $persistentQueryLoader)
|
||||||
{
|
{
|
||||||
@ -196,9 +209,11 @@ class ServerConfig
|
|||||||
/**
|
/**
|
||||||
* Set response debug flags. See GraphQL\Error\Debug class for a list of all available flags
|
* Set response debug flags. See GraphQL\Error\Debug class for a list of all available flags
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param bool|int $set
|
* @param bool|int $set
|
||||||
|
*
|
||||||
* @return self
|
* @return self
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setDebug($set = true)
|
public function setDebug($set = true)
|
||||||
{
|
{
|
||||||
@ -210,9 +225,11 @@ class ServerConfig
|
|||||||
/**
|
/**
|
||||||
* Allow batching queries (disabled by default)
|
* Allow batching queries (disabled by default)
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param bool $enableBatching
|
* @param bool $enableBatching
|
||||||
|
*
|
||||||
* @return self
|
* @return self
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setQueryBatching($enableBatching)
|
public function setQueryBatching($enableBatching)
|
||||||
{
|
{
|
||||||
@ -222,8 +239,9 @@ class ServerConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @return self
|
* @return self
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setPromiseAdapter(PromiseAdapter $promiseAdapter)
|
public function setPromiseAdapter(PromiseAdapter $promiseAdapter)
|
||||||
{
|
{
|
||||||
|
@ -12,6 +12,7 @@ use GraphQL\Utils\Utils;
|
|||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Psr\Http\Message\StreamInterface;
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
use Throwable;
|
||||||
use function is_array;
|
use function is_array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,7 +35,6 @@ use function is_array;
|
|||||||
* $server->handleRequest();
|
* $server->handleRequest();
|
||||||
*
|
*
|
||||||
* See [dedicated section in docs](executing-queries.md#using-server) for details.
|
* See [dedicated section in docs](executing-queries.md#using-server) for details.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
class StandardServer
|
class StandardServer
|
||||||
{
|
{
|
||||||
@ -49,10 +49,11 @@ class StandardServer
|
|||||||
* Useful when an exception is thrown somewhere outside of server execution context
|
* Useful when an exception is thrown somewhere outside of server execution context
|
||||||
* (e.g. during schema instantiation).
|
* (e.g. during schema instantiation).
|
||||||
*
|
*
|
||||||
* @api
|
* @param Throwable $error
|
||||||
* @param \Throwable $error
|
|
||||||
* @param bool $debug
|
* @param bool $debug
|
||||||
* @param bool $exitWhenDone
|
* @param bool $exitWhenDone
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function send500Error($error, $debug = false, $exitWhenDone = false)
|
public static function send500Error($error, $debug = false, $exitWhenDone = false)
|
||||||
{
|
{
|
||||||
@ -66,8 +67,9 @@ class StandardServer
|
|||||||
/**
|
/**
|
||||||
* Creates new instance of a standard GraphQL HTTP server
|
* Creates new instance of a standard GraphQL HTTP server
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param ServerConfig|mixed[] $config
|
* @param ServerConfig|mixed[] $config
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function __construct($config)
|
public function __construct($config)
|
||||||
{
|
{
|
||||||
@ -91,9 +93,10 @@ class StandardServer
|
|||||||
* See `executeRequest()` if you prefer to emit response yourself
|
* See `executeRequest()` if you prefer to emit response yourself
|
||||||
* (e.g. using Response object of some framework)
|
* (e.g. using Response object of some framework)
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param OperationParams|OperationParams[] $parsedBody
|
* @param OperationParams|OperationParams[] $parsedBody
|
||||||
* @param bool $exitWhenDone
|
* @param bool $exitWhenDone
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function handleRequest($parsedBody = null, $exitWhenDone = false)
|
public function handleRequest($parsedBody = null, $exitWhenDone = false)
|
||||||
{
|
{
|
||||||
@ -111,10 +114,13 @@ class StandardServer
|
|||||||
*
|
*
|
||||||
* PSR-7 compatible method executePsrRequest() does exactly this.
|
* PSR-7 compatible method executePsrRequest() does exactly this.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param OperationParams|OperationParams[] $parsedBody
|
* @param OperationParams|OperationParams[] $parsedBody
|
||||||
|
*
|
||||||
* @return ExecutionResult|ExecutionResult[]|Promise
|
* @return ExecutionResult|ExecutionResult[]|Promise
|
||||||
|
*
|
||||||
* @throws InvariantViolation
|
* @throws InvariantViolation
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function executeRequest($parsedBody = null)
|
public function executeRequest($parsedBody = null)
|
||||||
{
|
{
|
||||||
@ -135,8 +141,9 @@ class StandardServer
|
|||||||
* See `executePsrRequest()` if you prefer to create response yourself
|
* See `executePsrRequest()` if you prefer to create response yourself
|
||||||
* (e.g. using specific JsonResponse instance of some framework).
|
* (e.g. using specific JsonResponse instance of some framework).
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return ResponseInterface|Promise
|
* @return ResponseInterface|Promise
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function processPsrRequest(
|
public function processPsrRequest(
|
||||||
ServerRequestInterface $request,
|
ServerRequestInterface $request,
|
||||||
@ -151,8 +158,9 @@ class StandardServer
|
|||||||
* Executes GraphQL operation and returns execution result
|
* Executes GraphQL operation and returns execution result
|
||||||
* (or promise when promise adapter is different from SyncPromiseAdapter)
|
* (or promise when promise adapter is different from SyncPromiseAdapter)
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return ExecutionResult|ExecutionResult[]|Promise
|
* @return ExecutionResult|ExecutionResult[]|Promise
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function executePsrRequest(ServerRequestInterface $request)
|
public function executePsrRequest(ServerRequestInterface $request)
|
||||||
{
|
{
|
||||||
@ -164,8 +172,9 @@ class StandardServer
|
|||||||
* Returns an instance of Server helper, which contains most of the actual logic for
|
* Returns an instance of Server helper, which contains most of the actual logic for
|
||||||
* parsing / validating / executing request (which could be re-used by other server implementations)
|
* parsing / validating / executing request (which could be re-used by other server implementations)
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return Helper
|
* @return Helper
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getHelper()
|
public function getHelper()
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@ interface AbstractType
|
|||||||
*
|
*
|
||||||
* @param object $objectValue
|
* @param object $objectValue
|
||||||
* @param mixed[] $context
|
* @param mixed[] $context
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function resolveType($objectValue, $context, ResolveInfo $info);
|
public function resolveType($objectValue, $context, ResolveInfo $info);
|
||||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Type\Definition;
|
namespace GraphQL\Type\Definition;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
use GraphQL\Language\AST\BooleanValueNode;
|
use GraphQL\Language\AST\BooleanValueNode;
|
||||||
use GraphQL\Language\AST\Node;
|
use GraphQL\Language\AST\Node;
|
||||||
@ -23,6 +24,7 @@ class BooleanType extends ScalarType
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function serialize($value)
|
public function serialize($value)
|
||||||
@ -32,7 +34,9 @@ class BooleanType extends ScalarType
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public function parseValue($value)
|
public function parseValue($value)
|
||||||
@ -47,8 +51,10 @@ class BooleanType extends ScalarType
|
|||||||
/**
|
/**
|
||||||
* @param Node $valueNode
|
* @param Node $valueNode
|
||||||
* @param mixed[]|null $variables
|
* @param mixed[]|null $variables
|
||||||
|
*
|
||||||
* @return bool|null
|
* @return bool|null
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function parseLiteral($valueNode, ?array $variables = null)
|
public function parseLiteral($valueNode, ?array $variables = null)
|
||||||
{
|
{
|
||||||
@ -57,6 +63,6 @@ class BooleanType extends ScalarType
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Intentionally without message, as all information already in wrapped Exception
|
// Intentionally without message, as all information already in wrapped Exception
|
||||||
throw new \Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Type\Definition;
|
namespace GraphQL\Type\Definition;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Language\AST\Node;
|
use GraphQL\Language\AST\Node;
|
||||||
use GraphQL\Utils\AST;
|
use GraphQL\Utils\AST;
|
||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
@ -18,6 +19,7 @@ class CustomScalarType extends ScalarType
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function serialize($value)
|
public function serialize($value)
|
||||||
@ -27,6 +29,7 @@ class CustomScalarType extends ScalarType
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function parseValue($value)
|
public function parseValue($value)
|
||||||
@ -41,8 +44,10 @@ class CustomScalarType extends ScalarType
|
|||||||
/**
|
/**
|
||||||
* @param Node $valueNode
|
* @param Node $valueNode
|
||||||
* @param mixed[]|null $variables
|
* @param mixed[]|null $variables
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function parseLiteral(/* GraphQL\Language\AST\ValueNode */
|
public function parseLiteral(/* GraphQL\Language\AST\ValueNode */
|
||||||
$valueNode,
|
$valueNode,
|
||||||
|
@ -41,7 +41,6 @@ class Directive
|
|||||||
public $config;
|
public $config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param mixed[] $config
|
* @param mixed[] $config
|
||||||
*/
|
*/
|
||||||
public function __construct(array $config)
|
public function __construct(array $config)
|
||||||
|
@ -4,6 +4,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Type\Definition;
|
namespace GraphQL\Type\Definition;
|
||||||
|
|
||||||
|
use ArrayObject;
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
use GraphQL\Error\InvariantViolation;
|
use GraphQL\Error\InvariantViolation;
|
||||||
use GraphQL\Language\AST\EnumTypeDefinitionNode;
|
use GraphQL\Language\AST\EnumTypeDefinitionNode;
|
||||||
@ -54,6 +56,7 @@ class EnumType extends Type implements InputType, OutputType, LeafType, NamedTyp
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string|mixed[] $name
|
* @param string|mixed[] $name
|
||||||
|
*
|
||||||
* @return EnumValueDefinition|null
|
* @return EnumValueDefinition|null
|
||||||
*/
|
*/
|
||||||
public function getValue($name)
|
public function getValue($name)
|
||||||
@ -73,7 +76,7 @@ class EnumType extends Type implements InputType, OutputType, LeafType, NamedTyp
|
|||||||
private function getNameLookup()
|
private function getNameLookup()
|
||||||
{
|
{
|
||||||
if (! $this->nameLookup) {
|
if (! $this->nameLookup) {
|
||||||
$lookup = new \ArrayObject();
|
$lookup = new ArrayObject();
|
||||||
foreach ($this->getValues() as $value) {
|
foreach ($this->getValues() as $value) {
|
||||||
$lookup[$value->name] = $value;
|
$lookup[$value->name] = $value;
|
||||||
}
|
}
|
||||||
@ -123,7 +126,9 @@ class EnumType extends Type implements InputType, OutputType, LeafType, NamedTyp
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public function serialize($value)
|
public function serialize($value)
|
||||||
@ -154,7 +159,9 @@ class EnumType extends Type implements InputType, OutputType, LeafType, NamedTyp
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public function parseValue($value)
|
public function parseValue($value)
|
||||||
@ -170,8 +177,10 @@ class EnumType extends Type implements InputType, OutputType, LeafType, NamedTyp
|
|||||||
/**
|
/**
|
||||||
* @param Node $valueNode
|
* @param Node $valueNode
|
||||||
* @param mixed[]|null $variables
|
* @param mixed[]|null $variables
|
||||||
|
*
|
||||||
* @return null
|
* @return null
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function parseLiteral($valueNode, ?array $variables = null)
|
public function parseLiteral($valueNode, ?array $variables = null)
|
||||||
{
|
{
|
||||||
@ -186,7 +195,7 @@ class EnumType extends Type implements InputType, OutputType, LeafType, NamedTyp
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Intentionally without message, as all information already in wrapped Exception
|
// Intentionally without message, as all information already in wrapped Exception
|
||||||
throw new \Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,7 +38,6 @@ class FieldArgument
|
|||||||
private $defaultValueExists = false;
|
private $defaultValueExists = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param mixed[] $def
|
* @param mixed[] $def
|
||||||
*/
|
*/
|
||||||
public function __construct(array $def)
|
public function __construct(array $def)
|
||||||
@ -68,6 +67,7 @@ class FieldArgument
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed[] $config
|
* @param mixed[] $config
|
||||||
|
*
|
||||||
* @return FieldArgument[]
|
* @return FieldArgument[]
|
||||||
*/
|
*/
|
||||||
public static function createMap(array $config)
|
public static function createMap(array $config)
|
||||||
|
@ -65,7 +65,6 @@ class FieldDefinition
|
|||||||
private $complexityFn;
|
private $complexityFn;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param mixed[] $config
|
* @param mixed[] $config
|
||||||
*/
|
*/
|
||||||
protected function __construct(array $config)
|
protected function __construct(array $config)
|
||||||
@ -140,6 +139,7 @@ class FieldDefinition
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed[] $field
|
* @param mixed[] $field
|
||||||
|
*
|
||||||
* @return FieldDefinition
|
* @return FieldDefinition
|
||||||
*/
|
*/
|
||||||
public static function create($field)
|
public static function create($field)
|
||||||
@ -149,6 +149,7 @@ class FieldDefinition
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $childrenComplexity
|
* @param int $childrenComplexity
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function defaultComplexity($childrenComplexity)
|
public static function defaultComplexity($childrenComplexity)
|
||||||
@ -158,6 +159,7 @@ class FieldDefinition
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name
|
* @param string $name
|
||||||
|
*
|
||||||
* @return FieldArgument|null
|
* @return FieldArgument|null
|
||||||
*/
|
*/
|
||||||
public function getArg($name)
|
public function getArg($name)
|
||||||
@ -189,7 +191,7 @@ class FieldDefinition
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return callable|\Closure
|
* @return callable|callable
|
||||||
*/
|
*/
|
||||||
public function getComplexityFn()
|
public function getComplexityFn()
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Type\Definition;
|
namespace GraphQL\Type\Definition;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
use GraphQL\Language\AST\FloatValueNode;
|
use GraphQL\Language\AST\FloatValueNode;
|
||||||
use GraphQL\Language\AST\IntValueNode;
|
use GraphQL\Language\AST\IntValueNode;
|
||||||
@ -27,7 +28,9 @@ values as specified by
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return float|null
|
* @return float|null
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public function serialize($value)
|
public function serialize($value)
|
||||||
@ -55,7 +58,9 @@ values as specified by
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return float|null
|
* @return float|null
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public function parseValue($value)
|
public function parseValue($value)
|
||||||
@ -66,8 +71,10 @@ values as specified by
|
|||||||
/**
|
/**
|
||||||
* @param Node $valueNode
|
* @param Node $valueNode
|
||||||
* @param mixed[]|null $variables
|
* @param mixed[]|null $variables
|
||||||
|
*
|
||||||
* @return float|null
|
* @return float|null
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function parseLiteral($valueNode, ?array $variables = null)
|
public function parseLiteral($valueNode, ?array $variables = null)
|
||||||
{
|
{
|
||||||
@ -76,6 +83,6 @@ values as specified by
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Intentionally without message, as all information already in wrapped Exception
|
// Intentionally without message, as all information already in wrapped Exception
|
||||||
throw new \Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Type\Definition;
|
namespace GraphQL\Type\Definition;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
use GraphQL\Language\AST\IntValueNode;
|
use GraphQL\Language\AST\IntValueNode;
|
||||||
use GraphQL\Language\AST\Node;
|
use GraphQL\Language\AST\Node;
|
||||||
@ -30,7 +31,9 @@ When expected as an input type, any string (such as `"4"`) or integer
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public function serialize($value)
|
public function serialize($value)
|
||||||
@ -53,7 +56,9 @@ When expected as an input type, any string (such as `"4"`) or integer
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public function parseValue($value)
|
public function parseValue($value)
|
||||||
@ -68,8 +73,10 @@ When expected as an input type, any string (such as `"4"`) or integer
|
|||||||
/**
|
/**
|
||||||
* @param Node $valueNode
|
* @param Node $valueNode
|
||||||
* @param mixed[]|null $variables
|
* @param mixed[]|null $variables
|
||||||
* @return null|string
|
*
|
||||||
* @throws \Exception
|
* @return string|null
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function parseLiteral($valueNode, ?array $variables = null)
|
public function parseLiteral($valueNode, ?array $variables = null)
|
||||||
{
|
{
|
||||||
@ -78,6 +85,6 @@ When expected as an input type, any string (such as `"4"`) or integer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Intentionally without message, as all information already in wrapped Exception
|
// Intentionally without message, as all information already in wrapped Exception
|
||||||
throw new \Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,6 @@ class InputObjectField
|
|||||||
private $defaultValueExists = false;
|
private $defaultValueExists = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param mixed[] $opts
|
* @param mixed[] $opts
|
||||||
*/
|
*/
|
||||||
public function __construct(array $opts)
|
public function __construct(array $opts)
|
||||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Type\Definition;
|
namespace GraphQL\Type\Definition;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\InvariantViolation;
|
use GraphQL\Error\InvariantViolation;
|
||||||
use GraphQL\Language\AST\InputObjectTypeDefinitionNode;
|
use GraphQL\Language\AST\InputObjectTypeDefinitionNode;
|
||||||
use GraphQL\Language\AST\InputObjectTypeExtensionNode;
|
use GraphQL\Language\AST\InputObjectTypeExtensionNode;
|
||||||
@ -29,7 +30,6 @@ class InputObjectType extends Type implements InputType, NamedType
|
|||||||
public $extensionASTNodes;
|
public $extensionASTNodes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param mixed[] $config
|
* @param mixed[] $config
|
||||||
*/
|
*/
|
||||||
public function __construct(array $config)
|
public function __construct(array $config)
|
||||||
@ -49,8 +49,10 @@ class InputObjectType extends Type implements InputType, NamedType
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name
|
* @param string $name
|
||||||
|
*
|
||||||
* @return InputObjectField
|
* @return InputObjectField
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function getField($name)
|
public function getField($name)
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Type\Definition;
|
namespace GraphQL\Type\Definition;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
use GraphQL\Language\AST\IntValueNode;
|
use GraphQL\Language\AST\IntValueNode;
|
||||||
use GraphQL\Language\AST\Node;
|
use GraphQL\Language\AST\Node;
|
||||||
@ -36,7 +37,9 @@ values. Int can represent values between -(2^31) and 2^31 - 1. ';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return int|null
|
* @return int|null
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public function serialize($value)
|
public function serialize($value)
|
||||||
@ -46,6 +49,7 @@ values. Int can represent values between -(2^31) and 2^31 - 1. ';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
private function coerceInt($value)
|
private function coerceInt($value)
|
||||||
@ -78,7 +82,9 @@ values. Int can represent values between -(2^31) and 2^31 - 1. ';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return int|null
|
* @return int|null
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public function parseValue($value)
|
public function parseValue($value)
|
||||||
@ -89,8 +95,10 @@ values. Int can represent values between -(2^31) and 2^31 - 1. ';
|
|||||||
/**
|
/**
|
||||||
* @param Node $valueNode
|
* @param Node $valueNode
|
||||||
* @param mixed[]|null $variables
|
* @param mixed[]|null $variables
|
||||||
|
*
|
||||||
* @return int|null
|
* @return int|null
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function parseLiteral($valueNode, ?array $variables = null)
|
public function parseLiteral($valueNode, ?array $variables = null)
|
||||||
{
|
{
|
||||||
@ -102,6 +110,6 @@ values. Int can represent values between -(2^31) and 2^31 - 1. ';
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Intentionally without message, as all information already in wrapped Exception
|
// Intentionally without message, as all information already in wrapped Exception
|
||||||
throw new \Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT
|
|||||||
private $fields;
|
private $fields;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param mixed[] $config
|
* @param mixed[] $config
|
||||||
*/
|
*/
|
||||||
public function __construct(array $config)
|
public function __construct(array $config)
|
||||||
@ -47,6 +46,7 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $type
|
* @param mixed $type
|
||||||
|
*
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public static function assertInterfaceType($type)
|
public static function assertInterfaceType($type)
|
||||||
@ -61,6 +61,7 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name
|
* @param string $name
|
||||||
|
*
|
||||||
* @return FieldDefinition
|
* @return FieldDefinition
|
||||||
*/
|
*/
|
||||||
public function getField($name)
|
public function getField($name)
|
||||||
@ -91,6 +92,7 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT
|
|||||||
*
|
*
|
||||||
* @param object $objectValue
|
* @param object $objectValue
|
||||||
* @param mixed[] $context
|
* @param mixed[] $context
|
||||||
|
*
|
||||||
* @return callable|null
|
* @return callable|null
|
||||||
*/
|
*/
|
||||||
public function resolveType($objectValue, $context, ResolveInfo $info)
|
public function resolveType($objectValue, $context, ResolveInfo $info)
|
||||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Type\Definition;
|
namespace GraphQL\Type\Definition;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
use GraphQL\Language\AST\Node;
|
use GraphQL\Language\AST\Node;
|
||||||
|
|
||||||
@ -19,7 +20,9 @@ interface LeafType
|
|||||||
* Serializes an internal value to include in a response.
|
* Serializes an internal value to include in a response.
|
||||||
*
|
*
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public function serialize($value);
|
public function serialize($value);
|
||||||
@ -30,7 +33,9 @@ interface LeafType
|
|||||||
* In the case of an invalid value this method must throw an Exception
|
* In the case of an invalid value this method must throw an Exception
|
||||||
*
|
*
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public function parseValue($value);
|
public function parseValue($value);
|
||||||
@ -42,8 +47,10 @@ interface LeafType
|
|||||||
*
|
*
|
||||||
* @param Node $valueNode
|
* @param Node $valueNode
|
||||||
* @param mixed[]|null $variables
|
* @param mixed[]|null $variables
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function parseLiteral($valueNode, ?array $variables = null);
|
public function parseLiteral($valueNode, ?array $variables = null);
|
||||||
}
|
}
|
||||||
|
@ -33,12 +33,13 @@ class ListOfType extends Type implements WrappingType, OutputType, InputType
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $recurse
|
* @param bool $recurse
|
||||||
|
*
|
||||||
* @return ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType
|
* @return ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType
|
||||||
*/
|
*/
|
||||||
public function getWrappedType($recurse = false)
|
public function getWrappedType($recurse = false)
|
||||||
{
|
{
|
||||||
$type = $this->ofType;
|
$type = $this->ofType;
|
||||||
|
|
||||||
return ($recurse && $type instanceof WrappingType) ? $type->getWrappedType($recurse) : $type;
|
return $recurse && $type instanceof WrappingType ? $type->getWrappedType($recurse) : $type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Type\Definition;
|
namespace GraphQL\Type\Definition;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\InvariantViolation;
|
use GraphQL\Error\InvariantViolation;
|
||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
|
|
||||||
@ -17,7 +18,8 @@ class NonNull extends Type implements WrappingType, OutputType, InputType
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param callable|Type $type
|
* @param callable|Type $type
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function __construct($type)
|
public function __construct($type)
|
||||||
{
|
{
|
||||||
@ -26,6 +28,7 @@ class NonNull extends Type implements WrappingType, OutputType, InputType
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $type
|
* @param mixed $type
|
||||||
|
*
|
||||||
* @return ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType|ListOfType
|
* @return ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType|ListOfType
|
||||||
*/
|
*/
|
||||||
public static function assertNullableType($type)
|
public static function assertNullableType($type)
|
||||||
@ -40,6 +43,7 @@ class NonNull extends Type implements WrappingType, OutputType, InputType
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $type
|
* @param mixed $type
|
||||||
|
*
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public static function assertNullType($type)
|
public static function assertNullType($type)
|
||||||
@ -62,13 +66,15 @@ class NonNull extends Type implements WrappingType, OutputType, InputType
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $recurse
|
* @param bool $recurse
|
||||||
|
*
|
||||||
* @return ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType|ListOfType
|
* @return ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType|ListOfType
|
||||||
|
*
|
||||||
* @throws InvariantViolation
|
* @throws InvariantViolation
|
||||||
*/
|
*/
|
||||||
public function getWrappedType($recurse = false)
|
public function getWrappedType($recurse = false)
|
||||||
{
|
{
|
||||||
$type = $this->ofType;
|
$type = $this->ofType;
|
||||||
|
|
||||||
return ($recurse && $type instanceof WrappingType) ? $type->getWrappedType($recurse) : $type;
|
return $recurse && $type instanceof WrappingType ? $type->getWrappedType($recurse) : $type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Type\Definition;
|
namespace GraphQL\Type\Definition;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\InvariantViolation;
|
use GraphQL\Error\InvariantViolation;
|
||||||
use GraphQL\Language\AST\ObjectTypeDefinitionNode;
|
use GraphQL\Language\AST\ObjectTypeDefinitionNode;
|
||||||
use GraphQL\Language\AST\ObjectTypeExtensionNode;
|
use GraphQL\Language\AST\ObjectTypeExtensionNode;
|
||||||
@ -52,7 +53,6 @@ use function sprintf;
|
|||||||
* ];
|
* ];
|
||||||
* }
|
* }
|
||||||
* ]);
|
* ]);
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
class ObjectType extends Type implements OutputType, CompositeType, NamedType
|
class ObjectType extends Type implements OutputType, CompositeType, NamedType
|
||||||
{
|
{
|
||||||
@ -75,7 +75,6 @@ class ObjectType extends Type implements OutputType, CompositeType, NamedType
|
|||||||
private $interfaceMap;
|
private $interfaceMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param mixed[] $config
|
* @param mixed[] $config
|
||||||
*/
|
*/
|
||||||
public function __construct(array $config)
|
public function __construct(array $config)
|
||||||
@ -96,6 +95,7 @@ class ObjectType extends Type implements OutputType, CompositeType, NamedType
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $type
|
* @param mixed $type
|
||||||
|
*
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public static function assertObjectType($type)
|
public static function assertObjectType($type)
|
||||||
@ -110,8 +110,10 @@ class ObjectType extends Type implements OutputType, CompositeType, NamedType
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name
|
* @param string $name
|
||||||
|
*
|
||||||
* @return FieldDefinition
|
* @return FieldDefinition
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function getField($name)
|
public function getField($name)
|
||||||
{
|
{
|
||||||
@ -125,6 +127,7 @@ class ObjectType extends Type implements OutputType, CompositeType, NamedType
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldDefinition[]
|
* @return FieldDefinition[]
|
||||||
|
*
|
||||||
* @throws InvariantViolation
|
* @throws InvariantViolation
|
||||||
*/
|
*/
|
||||||
public function getFields()
|
public function getFields()
|
||||||
@ -139,6 +142,7 @@ class ObjectType extends Type implements OutputType, CompositeType, NamedType
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param InterfaceType $iface
|
* @param InterfaceType $iface
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function implementsInterface($iface)
|
public function implementsInterface($iface)
|
||||||
@ -184,6 +188,7 @@ class ObjectType extends Type implements OutputType, CompositeType, NamedType
|
|||||||
/**
|
/**
|
||||||
* @param mixed[] $value
|
* @param mixed[] $value
|
||||||
* @param mixed[]|null $context
|
* @param mixed[]|null $context
|
||||||
|
*
|
||||||
* @return bool|null
|
* @return bool|null
|
||||||
*/
|
*/
|
||||||
public function isTypeOf($value, $context, ResolveInfo $info)
|
public function isTypeOf($value, $context, ResolveInfo $info)
|
||||||
|
@ -139,9 +139,11 @@ class ResolveInfo
|
|||||||
* Warning: this method it is a naive implementation which does not take into account
|
* Warning: this method it is a naive implementation which does not take into account
|
||||||
* conditional typed fragments. So use it with care for fields of interface and union types.
|
* conditional typed fragments. So use it with care for fields of interface and union types.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param int $depth How many levels to include in output
|
* @param int $depth How many levels to include in output
|
||||||
|
*
|
||||||
* @return bool[]
|
* @return bool[]
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getFieldSelection($depth = 0)
|
public function getFieldSelection($depth = 0)
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Type\Definition;
|
namespace GraphQL\Type\Definition;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
use GraphQL\Language\AST\Node;
|
use GraphQL\Language\AST\Node;
|
||||||
use GraphQL\Language\AST\StringValueNode;
|
use GraphQL\Language\AST\StringValueNode;
|
||||||
@ -29,7 +30,9 @@ represent free-form human-readable text.';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return mixed|string
|
* @return mixed|string
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public function serialize($value)
|
public function serialize($value)
|
||||||
@ -67,7 +70,9 @@ represent free-form human-readable text.';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public function parseValue($value)
|
public function parseValue($value)
|
||||||
@ -78,8 +83,10 @@ represent free-form human-readable text.';
|
|||||||
/**
|
/**
|
||||||
* @param Node $valueNode
|
* @param Node $valueNode
|
||||||
* @param mixed[]|null $variables
|
* @param mixed[]|null $variables
|
||||||
* @return null|string
|
*
|
||||||
* @throws \Exception
|
* @return string|null
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function parseLiteral($valueNode, ?array $variables = null)
|
public function parseLiteral($valueNode, ?array $variables = null)
|
||||||
{
|
{
|
||||||
@ -88,6 +95,6 @@ represent free-form human-readable text.';
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Intentionally without message, as all information already in wrapped Exception
|
// Intentionally without message, as all information already in wrapped Exception
|
||||||
throw new \Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,14 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Type\Definition;
|
namespace GraphQL\Type\Definition;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\InvariantViolation;
|
use GraphQL\Error\InvariantViolation;
|
||||||
use GraphQL\Language\AST\TypeDefinitionNode;
|
use GraphQL\Language\AST\TypeDefinitionNode;
|
||||||
use GraphQL\Type\Introspection;
|
use GraphQL\Type\Introspection;
|
||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
|
use JsonSerializable;
|
||||||
|
use ReflectionClass;
|
||||||
|
use Throwable;
|
||||||
use function array_keys;
|
use function array_keys;
|
||||||
use function array_merge;
|
use function array_merge;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
@ -17,7 +21,7 @@ use function preg_replace;
|
|||||||
* Registry of standard GraphQL types
|
* Registry of standard GraphQL types
|
||||||
* and a base class for all other types.
|
* and a base class for all other types.
|
||||||
*/
|
*/
|
||||||
abstract class Type implements \JsonSerializable
|
abstract class Type implements JsonSerializable
|
||||||
{
|
{
|
||||||
public const STRING = 'String';
|
public const STRING = 'String';
|
||||||
public const INT = 'Int';
|
public const INT = 'Int';
|
||||||
@ -44,8 +48,9 @@ abstract class Type implements \JsonSerializable
|
|||||||
public $config;
|
public $config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @return IDType
|
* @return IDType
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function id()
|
public static function id()
|
||||||
{
|
{
|
||||||
@ -54,6 +59,7 @@ abstract class Type implements \JsonSerializable
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name
|
* @param string $name
|
||||||
|
*
|
||||||
* @return (IDType|StringType|FloatType|IntType|BooleanType)[]|IDType|StringType|FloatType|IntType|BooleanType
|
* @return (IDType|StringType|FloatType|IntType|BooleanType)[]|IDType|StringType|FloatType|IntType|BooleanType
|
||||||
*/
|
*/
|
||||||
private static function getInternalType($name = null)
|
private static function getInternalType($name = null)
|
||||||
@ -72,8 +78,9 @@ abstract class Type implements \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @return StringType
|
* @return StringType
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function string()
|
public static function string()
|
||||||
{
|
{
|
||||||
@ -81,8 +88,9 @@ abstract class Type implements \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @return BooleanType
|
* @return BooleanType
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function boolean()
|
public static function boolean()
|
||||||
{
|
{
|
||||||
@ -90,8 +98,9 @@ abstract class Type implements \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @return IntType
|
* @return IntType
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function int()
|
public static function int()
|
||||||
{
|
{
|
||||||
@ -99,8 +108,9 @@ abstract class Type implements \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @return FloatType
|
* @return FloatType
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function float()
|
public static function float()
|
||||||
{
|
{
|
||||||
@ -108,9 +118,11 @@ abstract class Type implements \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param Type|ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType|ListOfType|NonNull $wrappedType
|
* @param Type|ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType|ListOfType|NonNull $wrappedType
|
||||||
|
*
|
||||||
* @return ListOfType
|
* @return ListOfType
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function listOf($wrappedType)
|
public static function listOf($wrappedType)
|
||||||
{
|
{
|
||||||
@ -118,9 +130,11 @@ abstract class Type implements \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType|ListOfType $wrappedType
|
* @param ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType|ListOfType $wrappedType
|
||||||
|
*
|
||||||
* @return NonNull
|
* @return NonNull
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function nonNull($wrappedType)
|
public static function nonNull($wrappedType)
|
||||||
{
|
{
|
||||||
@ -166,9 +180,11 @@ abstract class Type implements \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param Type $type
|
* @param Type $type
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function isInputType($type)
|
public static function isInputType($type)
|
||||||
{
|
{
|
||||||
@ -180,9 +196,11 @@ abstract class Type implements \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param Type $type
|
* @param Type $type
|
||||||
|
*
|
||||||
* @return ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType
|
* @return ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function getNamedType($type)
|
public static function getNamedType($type)
|
||||||
{
|
{
|
||||||
@ -197,9 +215,11 @@ abstract class Type implements \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param Type $type
|
* @param Type $type
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function isOutputType($type)
|
public static function isOutputType($type)
|
||||||
{
|
{
|
||||||
@ -211,9 +231,11 @@ abstract class Type implements \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param Type $type
|
* @param Type $type
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function isLeafType($type)
|
public static function isLeafType($type)
|
||||||
{
|
{
|
||||||
@ -221,9 +243,11 @@ abstract class Type implements \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param Type $type
|
* @param Type $type
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function isCompositeType($type)
|
public static function isCompositeType($type)
|
||||||
{
|
{
|
||||||
@ -231,9 +255,11 @@ abstract class Type implements \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param Type $type
|
* @param Type $type
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function isAbstractType($type)
|
public static function isAbstractType($type)
|
||||||
{
|
{
|
||||||
@ -242,6 +268,7 @@ abstract class Type implements \JsonSerializable
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $type
|
* @param mixed $type
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function assertType($type)
|
public static function assertType($type)
|
||||||
@ -255,9 +282,11 @@ abstract class Type implements \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param Type $type
|
* @param Type $type
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function isType($type)
|
public static function isType($type)
|
||||||
{
|
{
|
||||||
@ -265,9 +294,11 @@ abstract class Type implements \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param Type $type
|
* @param Type $type
|
||||||
|
*
|
||||||
* @return ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType|ListOfType
|
* @return ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType|ListOfType
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function getNullableType($type)
|
public static function getNullableType($type)
|
||||||
{
|
{
|
||||||
@ -305,15 +336,15 @@ abstract class Type implements \JsonSerializable
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return $this->toString();
|
return $this->toString();
|
||||||
} catch (\Exception $e) {
|
} catch (Exception $e) {
|
||||||
echo $e;
|
echo $e;
|
||||||
} catch (\Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
echo $e;
|
echo $e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return null|string
|
* @return string|null
|
||||||
*/
|
*/
|
||||||
protected function tryInferName()
|
protected function tryInferName()
|
||||||
{
|
{
|
||||||
@ -324,7 +355,7 @@ abstract class Type implements \JsonSerializable
|
|||||||
// If class is extended - infer name from className
|
// If class is extended - infer name from className
|
||||||
// QueryType -> Type
|
// QueryType -> Type
|
||||||
// SomeOtherType -> SomeOther
|
// SomeOtherType -> SomeOther
|
||||||
$tmp = new \ReflectionClass($this);
|
$tmp = new ReflectionClass($this);
|
||||||
$name = $tmp->getShortName();
|
$name = $tmp->getShortName();
|
||||||
|
|
||||||
if ($tmp->getNamespaceName() !== __NAMESPACE__) {
|
if ($tmp->getNamespaceName() !== __NAMESPACE__) {
|
||||||
|
@ -104,6 +104,7 @@ class UnionType extends Type implements AbstractType, OutputType, CompositeType,
|
|||||||
*
|
*
|
||||||
* @param object $objectValue
|
* @param object $objectValue
|
||||||
* @param mixed $context
|
* @param mixed $context
|
||||||
|
*
|
||||||
* @return callable|null
|
* @return callable|null
|
||||||
*/
|
*/
|
||||||
public function resolveType($objectValue, $context, ResolveInfo $info)
|
public function resolveType($objectValue, $context, ResolveInfo $info)
|
||||||
|
@ -8,6 +8,7 @@ interface WrappingType
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param bool $recurse
|
* @param bool $recurse
|
||||||
|
*
|
||||||
* @return ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType
|
* @return ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType
|
||||||
*/
|
*/
|
||||||
public function getWrappedType($recurse = false);
|
public function getWrappedType($recurse = false);
|
||||||
|
@ -25,7 +25,6 @@ class EagerResolution implements Resolution
|
|||||||
private $implementations = [];
|
private $implementations = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param Type[] $initialTypes
|
* @param Type[] $initialTypes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $initialTypes)
|
public function __construct(array $initialTypes)
|
||||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Type;
|
namespace GraphQL\Type;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Language\DirectiveLocation;
|
use GraphQL\Language\DirectiveLocation;
|
||||||
use GraphQL\Language\Printer;
|
use GraphQL\Language\Printer;
|
||||||
use GraphQL\Type\Definition\Directive;
|
use GraphQL\Type\Definition\Directive;
|
||||||
@ -44,6 +45,7 @@ class Introspection
|
|||||||
* Default: true
|
* Default: true
|
||||||
*
|
*
|
||||||
* @param bool[]|bool $options
|
* @param bool[]|bool $options
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function getIntrospectionQuery($options = [])
|
public static function getIntrospectionQuery($options = [])
|
||||||
@ -157,6 +159,7 @@ EOD;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Type $type
|
* @param Type $type
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function isIntrospectionType($type)
|
public static function isIntrospectionType($type)
|
||||||
@ -193,14 +196,14 @@ EOD;
|
|||||||
'types' => [
|
'types' => [
|
||||||
'description' => 'A list of all types supported by this server.',
|
'description' => 'A list of all types supported by this server.',
|
||||||
'type' => new NonNull(new ListOfType(new NonNull(self::_type()))),
|
'type' => new NonNull(new ListOfType(new NonNull(self::_type()))),
|
||||||
'resolve' => function (Schema $schema) {
|
'resolve' => static function (Schema $schema) {
|
||||||
return array_values($schema->getTypeMap());
|
return array_values($schema->getTypeMap());
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'queryType' => [
|
'queryType' => [
|
||||||
'description' => 'The type that query operations will be rooted at.',
|
'description' => 'The type that query operations will be rooted at.',
|
||||||
'type' => new NonNull(self::_type()),
|
'type' => new NonNull(self::_type()),
|
||||||
'resolve' => function (Schema $schema) {
|
'resolve' => static function (Schema $schema) {
|
||||||
return $schema->getQueryType();
|
return $schema->getQueryType();
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -209,21 +212,21 @@ EOD;
|
|||||||
'If this server supports mutation, the type that ' .
|
'If this server supports mutation, the type that ' .
|
||||||
'mutation operations will be rooted at.',
|
'mutation operations will be rooted at.',
|
||||||
'type' => self::_type(),
|
'type' => self::_type(),
|
||||||
'resolve' => function (Schema $schema) {
|
'resolve' => static function (Schema $schema) {
|
||||||
return $schema->getMutationType();
|
return $schema->getMutationType();
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'subscriptionType' => [
|
'subscriptionType' => [
|
||||||
'description' => 'If this server support subscription, the type that subscription operations will be rooted at.',
|
'description' => 'If this server support subscription, the type that subscription operations will be rooted at.',
|
||||||
'type' => self::_type(),
|
'type' => self::_type(),
|
||||||
'resolve' => function (Schema $schema) {
|
'resolve' => static function (Schema $schema) {
|
||||||
return $schema->getSubscriptionType();
|
return $schema->getSubscriptionType();
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'directives' => [
|
'directives' => [
|
||||||
'description' => 'A list of all directives supported by this server.',
|
'description' => 'A list of all directives supported by this server.',
|
||||||
'type' => Type::nonNull(Type::listOf(Type::nonNull(self::_directive()))),
|
'type' => Type::nonNull(Type::listOf(Type::nonNull(self::_directive()))),
|
||||||
'resolve' => function (Schema $schema) {
|
'resolve' => static function (Schema $schema) {
|
||||||
return $schema->getDirectives();
|
return $schema->getDirectives();
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -250,11 +253,11 @@ EOD;
|
|||||||
'Object and Interface types provide the fields they describe. Abstract ' .
|
'Object and Interface types provide the fields they describe. Abstract ' .
|
||||||
'types, Union and Interface, provide the Object types possible ' .
|
'types, Union and Interface, provide the Object types possible ' .
|
||||||
'at runtime. List and NonNull types compose other types.',
|
'at runtime. List and NonNull types compose other types.',
|
||||||
'fields' => function () {
|
'fields' => static function () {
|
||||||
return [
|
return [
|
||||||
'kind' => [
|
'kind' => [
|
||||||
'type' => Type::nonNull(self::_typeKind()),
|
'type' => Type::nonNull(self::_typeKind()),
|
||||||
'resolve' => function (Type $type) {
|
'resolve' => static function (Type $type) {
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case $type instanceof ListOfType:
|
case $type instanceof ListOfType:
|
||||||
return TypeKind::LIST_KIND;
|
return TypeKind::LIST_KIND;
|
||||||
@ -273,7 +276,7 @@ EOD;
|
|||||||
case $type instanceof UnionType:
|
case $type instanceof UnionType:
|
||||||
return TypeKind::UNION;
|
return TypeKind::UNION;
|
||||||
default:
|
default:
|
||||||
throw new \Exception('Unknown kind of type: ' . Utils::printSafe($type));
|
throw new Exception('Unknown kind of type: ' . Utils::printSafe($type));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -284,14 +287,14 @@ EOD;
|
|||||||
'args' => [
|
'args' => [
|
||||||
'includeDeprecated' => ['type' => Type::boolean(), 'defaultValue' => false],
|
'includeDeprecated' => ['type' => Type::boolean(), 'defaultValue' => false],
|
||||||
],
|
],
|
||||||
'resolve' => function (Type $type, $args) {
|
'resolve' => static function (Type $type, $args) {
|
||||||
if ($type instanceof ObjectType || $type instanceof InterfaceType) {
|
if ($type instanceof ObjectType || $type instanceof InterfaceType) {
|
||||||
$fields = $type->getFields();
|
$fields = $type->getFields();
|
||||||
|
|
||||||
if (empty($args['includeDeprecated'])) {
|
if (empty($args['includeDeprecated'])) {
|
||||||
$fields = array_filter(
|
$fields = array_filter(
|
||||||
$fields,
|
$fields,
|
||||||
function (FieldDefinition $field) {
|
static function (FieldDefinition $field) {
|
||||||
return ! $field->deprecationReason;
|
return ! $field->deprecationReason;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -305,7 +308,7 @@ EOD;
|
|||||||
],
|
],
|
||||||
'interfaces' => [
|
'interfaces' => [
|
||||||
'type' => Type::listOf(Type::nonNull(self::_type())),
|
'type' => Type::listOf(Type::nonNull(self::_type())),
|
||||||
'resolve' => function ($type) {
|
'resolve' => static function ($type) {
|
||||||
if ($type instanceof ObjectType) {
|
if ($type instanceof ObjectType) {
|
||||||
return $type->getInterfaces();
|
return $type->getInterfaces();
|
||||||
}
|
}
|
||||||
@ -315,7 +318,7 @@ EOD;
|
|||||||
],
|
],
|
||||||
'possibleTypes' => [
|
'possibleTypes' => [
|
||||||
'type' => Type::listOf(Type::nonNull(self::_type())),
|
'type' => Type::listOf(Type::nonNull(self::_type())),
|
||||||
'resolve' => function ($type, $args, $context, ResolveInfo $info) {
|
'resolve' => static function ($type, $args, $context, ResolveInfo $info) {
|
||||||
if ($type instanceof InterfaceType || $type instanceof UnionType) {
|
if ($type instanceof InterfaceType || $type instanceof UnionType) {
|
||||||
return $info->schema->getPossibleTypes($type);
|
return $info->schema->getPossibleTypes($type);
|
||||||
}
|
}
|
||||||
@ -328,14 +331,14 @@ EOD;
|
|||||||
'args' => [
|
'args' => [
|
||||||
'includeDeprecated' => ['type' => Type::boolean(), 'defaultValue' => false],
|
'includeDeprecated' => ['type' => Type::boolean(), 'defaultValue' => false],
|
||||||
],
|
],
|
||||||
'resolve' => function ($type, $args) {
|
'resolve' => static function ($type, $args) {
|
||||||
if ($type instanceof EnumType) {
|
if ($type instanceof EnumType) {
|
||||||
$values = array_values($type->getValues());
|
$values = array_values($type->getValues());
|
||||||
|
|
||||||
if (empty($args['includeDeprecated'])) {
|
if (empty($args['includeDeprecated'])) {
|
||||||
$values = array_filter(
|
$values = array_filter(
|
||||||
$values,
|
$values,
|
||||||
function ($value) {
|
static function ($value) {
|
||||||
return ! $value->deprecationReason;
|
return ! $value->deprecationReason;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -349,7 +352,7 @@ EOD;
|
|||||||
],
|
],
|
||||||
'inputFields' => [
|
'inputFields' => [
|
||||||
'type' => Type::listOf(Type::nonNull(self::_inputValue())),
|
'type' => Type::listOf(Type::nonNull(self::_inputValue())),
|
||||||
'resolve' => function ($type) {
|
'resolve' => static function ($type) {
|
||||||
if ($type instanceof InputObjectType) {
|
if ($type instanceof InputObjectType) {
|
||||||
return array_values($type->getFields());
|
return array_values($type->getFields());
|
||||||
}
|
}
|
||||||
@ -359,7 +362,7 @@ EOD;
|
|||||||
],
|
],
|
||||||
'ofType' => [
|
'ofType' => [
|
||||||
'type' => self::_type(),
|
'type' => self::_type(),
|
||||||
'resolve' => function ($type) {
|
'resolve' => static function ($type) {
|
||||||
if ($type instanceof WrappingType) {
|
if ($type instanceof WrappingType) {
|
||||||
return $type->getWrappedType();
|
return $type->getWrappedType();
|
||||||
}
|
}
|
||||||
@ -431,25 +434,25 @@ EOD;
|
|||||||
'description' =>
|
'description' =>
|
||||||
'Object and Interface types are described by a list of Fields, each of ' .
|
'Object and Interface types are described by a list of Fields, each of ' .
|
||||||
'which has a name, potentially a list of arguments, and a return type.',
|
'which has a name, potentially a list of arguments, and a return type.',
|
||||||
'fields' => function () {
|
'fields' => static function () {
|
||||||
return [
|
return [
|
||||||
'name' => ['type' => Type::nonNull(Type::string())],
|
'name' => ['type' => Type::nonNull(Type::string())],
|
||||||
'description' => ['type' => Type::string()],
|
'description' => ['type' => Type::string()],
|
||||||
'args' => [
|
'args' => [
|
||||||
'type' => Type::nonNull(Type::listOf(Type::nonNull(self::_inputValue()))),
|
'type' => Type::nonNull(Type::listOf(Type::nonNull(self::_inputValue()))),
|
||||||
'resolve' => function (FieldDefinition $field) {
|
'resolve' => static function (FieldDefinition $field) {
|
||||||
return empty($field->args) ? [] : $field->args;
|
return empty($field->args) ? [] : $field->args;
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'type' => [
|
'type' => [
|
||||||
'type' => Type::nonNull(self::_type()),
|
'type' => Type::nonNull(self::_type()),
|
||||||
'resolve' => function (FieldDefinition $field) {
|
'resolve' => static function (FieldDefinition $field) {
|
||||||
return $field->getType();
|
return $field->getType();
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'isDeprecated' => [
|
'isDeprecated' => [
|
||||||
'type' => Type::nonNull(Type::boolean()),
|
'type' => Type::nonNull(Type::boolean()),
|
||||||
'resolve' => function (FieldDefinition $field) {
|
'resolve' => static function (FieldDefinition $field) {
|
||||||
return (bool) $field->deprecationReason;
|
return (bool) $field->deprecationReason;
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -474,13 +477,13 @@ EOD;
|
|||||||
'Arguments provided to Fields or Directives and the input fields of an ' .
|
'Arguments provided to Fields or Directives and the input fields of an ' .
|
||||||
'InputObject are represented as Input Values which describe their type ' .
|
'InputObject are represented as Input Values which describe their type ' .
|
||||||
'and optionally a default value.',
|
'and optionally a default value.',
|
||||||
'fields' => function () {
|
'fields' => static function () {
|
||||||
return [
|
return [
|
||||||
'name' => ['type' => Type::nonNull(Type::string())],
|
'name' => ['type' => Type::nonNull(Type::string())],
|
||||||
'description' => ['type' => Type::string()],
|
'description' => ['type' => Type::string()],
|
||||||
'type' => [
|
'type' => [
|
||||||
'type' => Type::nonNull(self::_type()),
|
'type' => Type::nonNull(self::_type()),
|
||||||
'resolve' => function ($value) {
|
'resolve' => static function ($value) {
|
||||||
return method_exists($value, 'getType') ? $value->getType() : $value->type;
|
return method_exists($value, 'getType') ? $value->getType() : $value->type;
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -488,7 +491,7 @@ EOD;
|
|||||||
'type' => Type::string(),
|
'type' => Type::string(),
|
||||||
'description' =>
|
'description' =>
|
||||||
'A GraphQL-formatted string representing the default value for this input value.',
|
'A GraphQL-formatted string representing the default value for this input value.',
|
||||||
'resolve' => function ($inputValue) {
|
'resolve' => static function ($inputValue) {
|
||||||
/** @var FieldArgument|InputObjectField $inputValue */
|
/** @var FieldArgument|InputObjectField $inputValue */
|
||||||
return ! $inputValue->defaultValueExists()
|
return ! $inputValue->defaultValueExists()
|
||||||
? null
|
? null
|
||||||
@ -521,7 +524,7 @@ EOD;
|
|||||||
'description' => ['type' => Type::string()],
|
'description' => ['type' => Type::string()],
|
||||||
'isDeprecated' => [
|
'isDeprecated' => [
|
||||||
'type' => Type::nonNull(Type::boolean()),
|
'type' => Type::nonNull(Type::boolean()),
|
||||||
'resolve' => function ($enumValue) {
|
'resolve' => static function ($enumValue) {
|
||||||
return (bool) $enumValue->deprecationReason;
|
return (bool) $enumValue->deprecationReason;
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -557,7 +560,7 @@ EOD;
|
|||||||
],
|
],
|
||||||
'args' => [
|
'args' => [
|
||||||
'type' => Type::nonNull(Type::listOf(Type::nonNull(self::_inputValue()))),
|
'type' => Type::nonNull(Type::listOf(Type::nonNull(self::_inputValue()))),
|
||||||
'resolve' => function (Directive $directive) {
|
'resolve' => static function (Directive $directive) {
|
||||||
return $directive->args ?: [];
|
return $directive->args ?: [];
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -567,7 +570,7 @@ EOD;
|
|||||||
'onOperation' => [
|
'onOperation' => [
|
||||||
'deprecationReason' => 'Use `locations`.',
|
'deprecationReason' => 'Use `locations`.',
|
||||||
'type' => Type::nonNull(Type::boolean()),
|
'type' => Type::nonNull(Type::boolean()),
|
||||||
'resolve' => function ($d) {
|
'resolve' => static function ($d) {
|
||||||
return in_array(DirectiveLocation::QUERY, $d->locations) ||
|
return in_array(DirectiveLocation::QUERY, $d->locations) ||
|
||||||
in_array(DirectiveLocation::MUTATION, $d->locations) ||
|
in_array(DirectiveLocation::MUTATION, $d->locations) ||
|
||||||
in_array(DirectiveLocation::SUBSCRIPTION, $d->locations);
|
in_array(DirectiveLocation::SUBSCRIPTION, $d->locations);
|
||||||
@ -576,7 +579,7 @@ EOD;
|
|||||||
'onFragment' => [
|
'onFragment' => [
|
||||||
'deprecationReason' => 'Use `locations`.',
|
'deprecationReason' => 'Use `locations`.',
|
||||||
'type' => Type::nonNull(Type::boolean()),
|
'type' => Type::nonNull(Type::boolean()),
|
||||||
'resolve' => function ($d) {
|
'resolve' => static function ($d) {
|
||||||
return in_array(DirectiveLocation::FRAGMENT_SPREAD, $d->locations) ||
|
return in_array(DirectiveLocation::FRAGMENT_SPREAD, $d->locations) ||
|
||||||
in_array(DirectiveLocation::INLINE_FRAGMENT, $d->locations) ||
|
in_array(DirectiveLocation::INLINE_FRAGMENT, $d->locations) ||
|
||||||
in_array(DirectiveLocation::FRAGMENT_DEFINITION, $d->locations);
|
in_array(DirectiveLocation::FRAGMENT_DEFINITION, $d->locations);
|
||||||
@ -585,7 +588,7 @@ EOD;
|
|||||||
'onField' => [
|
'onField' => [
|
||||||
'deprecationReason' => 'Use `locations`.',
|
'deprecationReason' => 'Use `locations`.',
|
||||||
'type' => Type::nonNull(Type::boolean()),
|
'type' => Type::nonNull(Type::boolean()),
|
||||||
'resolve' => function ($d) {
|
'resolve' => static function ($d) {
|
||||||
return in_array(DirectiveLocation::FIELD, $d->locations);
|
return in_array(DirectiveLocation::FIELD, $d->locations);
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -694,7 +697,7 @@ EOD;
|
|||||||
'type' => Type::nonNull(self::_schema()),
|
'type' => Type::nonNull(self::_schema()),
|
||||||
'description' => 'Access the current type schema of this server.',
|
'description' => 'Access the current type schema of this server.',
|
||||||
'args' => [],
|
'args' => [],
|
||||||
'resolve' => function (
|
'resolve' => static function (
|
||||||
$source,
|
$source,
|
||||||
$args,
|
$args,
|
||||||
$context,
|
$context,
|
||||||
@ -718,7 +721,7 @@ EOD;
|
|||||||
'args' => [
|
'args' => [
|
||||||
['name' => 'name', 'type' => Type::nonNull(Type::string())],
|
['name' => 'name', 'type' => Type::nonNull(Type::string())],
|
||||||
],
|
],
|
||||||
'resolve' => function ($source, $args, $context, ResolveInfo $info) {
|
'resolve' => static function ($source, $args, $context, ResolveInfo $info) {
|
||||||
return $info->schema->getType($args['name']);
|
return $info->schema->getType($args['name']);
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
@ -735,7 +738,7 @@ EOD;
|
|||||||
'type' => Type::nonNull(Type::string()),
|
'type' => Type::nonNull(Type::string()),
|
||||||
'description' => 'The name of the current Object type at runtime.',
|
'description' => 'The name of the current Object type at runtime.',
|
||||||
'args' => [],
|
'args' => [],
|
||||||
'resolve' => function (
|
'resolve' => static function (
|
||||||
$source,
|
$source,
|
||||||
$args,
|
$args,
|
||||||
$context,
|
$context,
|
||||||
|
@ -42,7 +42,6 @@ class LazyResolution implements Resolution
|
|||||||
private $loadedPossibleTypes;
|
private $loadedPossibleTypes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param mixed[] $descriptor
|
* @param mixed[] $descriptor
|
||||||
*/
|
*/
|
||||||
public function __construct(array $descriptor, callable $typeLoader)
|
public function __construct(array $descriptor, callable $typeLoader)
|
||||||
|
@ -20,6 +20,7 @@ interface Resolution
|
|||||||
* Returns instance of type with given $name for GraphQL Schema
|
* Returns instance of type with given $name for GraphQL Schema
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
|
*
|
||||||
* @return Type
|
* @return Type
|
||||||
*/
|
*/
|
||||||
public function resolveType($name);
|
public function resolveType($name);
|
||||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Type;
|
namespace GraphQL\Type;
|
||||||
|
|
||||||
|
use Generator;
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
use GraphQL\Error\InvariantViolation;
|
use GraphQL\Error\InvariantViolation;
|
||||||
use GraphQL\GraphQL;
|
use GraphQL\GraphQL;
|
||||||
@ -17,6 +18,7 @@ use GraphQL\Type\Definition\Type;
|
|||||||
use GraphQL\Type\Definition\UnionType;
|
use GraphQL\Type\Definition\UnionType;
|
||||||
use GraphQL\Utils\TypeInfo;
|
use GraphQL\Utils\TypeInfo;
|
||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
|
use Traversable;
|
||||||
use function array_values;
|
use function array_values;
|
||||||
use function implode;
|
use function implode;
|
||||||
use function is_array;
|
use function is_array;
|
||||||
@ -72,8 +74,9 @@ class Schema
|
|||||||
public $extensionASTNodes;
|
public $extensionASTNodes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param mixed[]|SchemaConfig $config
|
* @param mixed[]|SchemaConfig $config
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function __construct($config)
|
public function __construct($config)
|
||||||
{
|
{
|
||||||
@ -151,7 +154,7 @@ class Schema
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \Generator
|
* @return Generator
|
||||||
*/
|
*/
|
||||||
private function resolveAdditionalTypes()
|
private function resolveAdditionalTypes()
|
||||||
{
|
{
|
||||||
@ -161,7 +164,7 @@ class Schema
|
|||||||
$types = $types();
|
$types = $types();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! is_array($types) && ! $types instanceof \Traversable) {
|
if (! is_array($types) && ! $types instanceof Traversable) {
|
||||||
throw new InvariantViolation(sprintf(
|
throw new InvariantViolation(sprintf(
|
||||||
'Schema types callable must return array or instance of Traversable but got: %s',
|
'Schema types callable must return array or instance of Traversable but got: %s',
|
||||||
Utils::getVariableType($types)
|
Utils::getVariableType($types)
|
||||||
@ -186,8 +189,9 @@ class Schema
|
|||||||
*
|
*
|
||||||
* This operation requires full schema scan. Do not use in production environment.
|
* This operation requires full schema scan. Do not use in production environment.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return Type[]
|
* @return Type[]
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getTypeMap()
|
public function getTypeMap()
|
||||||
{
|
{
|
||||||
@ -228,8 +232,9 @@ class Schema
|
|||||||
/**
|
/**
|
||||||
* Returns a list of directives supported by this schema
|
* Returns a list of directives supported by this schema
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return Directive[]
|
* @return Directive[]
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getDirectives()
|
public function getDirectives()
|
||||||
{
|
{
|
||||||
@ -239,8 +244,9 @@ class Schema
|
|||||||
/**
|
/**
|
||||||
* Returns schema query type
|
* Returns schema query type
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return ObjectType
|
* @return ObjectType
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getQueryType()
|
public function getQueryType()
|
||||||
{
|
{
|
||||||
@ -250,8 +256,9 @@ class Schema
|
|||||||
/**
|
/**
|
||||||
* Returns schema mutation type
|
* Returns schema mutation type
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return ObjectType|null
|
* @return ObjectType|null
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getMutationType()
|
public function getMutationType()
|
||||||
{
|
{
|
||||||
@ -261,8 +268,9 @@ class Schema
|
|||||||
/**
|
/**
|
||||||
* Returns schema subscription
|
* Returns schema subscription
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return ObjectType|null
|
* @return ObjectType|null
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getSubscriptionType()
|
public function getSubscriptionType()
|
||||||
{
|
{
|
||||||
@ -270,8 +278,9 @@ class Schema
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @return SchemaConfig
|
* @return SchemaConfig
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getConfig()
|
public function getConfig()
|
||||||
{
|
{
|
||||||
@ -281,9 +290,11 @@ class Schema
|
|||||||
/**
|
/**
|
||||||
* Returns type by it's name
|
* Returns type by it's name
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param string $name
|
* @param string $name
|
||||||
|
*
|
||||||
* @return Type|null
|
* @return Type|null
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getType($name)
|
public function getType($name)
|
||||||
{
|
{
|
||||||
@ -300,6 +311,7 @@ class Schema
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $typeName
|
* @param string $typeName
|
||||||
|
*
|
||||||
* @return Type
|
* @return Type
|
||||||
*/
|
*/
|
||||||
private function loadType($typeName)
|
private function loadType($typeName)
|
||||||
@ -332,6 +344,7 @@ class Schema
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $typeName
|
* @param string $typeName
|
||||||
|
*
|
||||||
* @return Type
|
* @return Type
|
||||||
*/
|
*/
|
||||||
private function defaultTypeLoader($typeName)
|
private function defaultTypeLoader($typeName)
|
||||||
@ -348,8 +361,9 @@ class Schema
|
|||||||
*
|
*
|
||||||
* This operation requires full schema scan. Do not use in production environment.
|
* This operation requires full schema scan. Do not use in production environment.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return ObjectType[]
|
* @return ObjectType[]
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getPossibleTypes(AbstractType $abstractType)
|
public function getPossibleTypes(AbstractType $abstractType)
|
||||||
{
|
{
|
||||||
@ -389,8 +403,9 @@ class Schema
|
|||||||
* Returns true if object type is concrete type of given abstract type
|
* Returns true if object type is concrete type of given abstract type
|
||||||
* (implementation for interfaces and members of union type for unions)
|
* (implementation for interfaces and members of union type for unions)
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return bool
|
* @return bool
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function isPossibleType(AbstractType $abstractType, ObjectType $possibleType)
|
public function isPossibleType(AbstractType $abstractType, ObjectType $possibleType)
|
||||||
{
|
{
|
||||||
@ -405,9 +420,11 @@ class Schema
|
|||||||
/**
|
/**
|
||||||
* Returns instance of directive by name
|
* Returns instance of directive by name
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param string $name
|
* @param string $name
|
||||||
|
*
|
||||||
* @return Directive
|
* @return Directive
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getDirective($name)
|
public function getDirective($name)
|
||||||
{
|
{
|
||||||
@ -433,8 +450,9 @@ class Schema
|
|||||||
*
|
*
|
||||||
* This operation requires full schema scan. Do not use in production environment.
|
* This operation requires full schema scan. Do not use in production environment.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @throws InvariantViolation
|
* @throws InvariantViolation
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function assertValid()
|
public function assertValid()
|
||||||
{
|
{
|
||||||
@ -472,8 +490,9 @@ class Schema
|
|||||||
*
|
*
|
||||||
* This operation requires full schema scan. Do not use in production environment.
|
* This operation requires full schema scan. Do not use in production environment.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return InvariantViolation[]|Error[]
|
* @return InvariantViolation[]|Error[]
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function validate()
|
public function validate()
|
||||||
{
|
{
|
||||||
|
@ -24,7 +24,6 @@ use function is_callable;
|
|||||||
* ->setTypeLoader($myTypeLoader);
|
* ->setTypeLoader($myTypeLoader);
|
||||||
*
|
*
|
||||||
* $schema = new Schema($config);
|
* $schema = new Schema($config);
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
class SchemaConfig
|
class SchemaConfig
|
||||||
{
|
{
|
||||||
@ -59,9 +58,11 @@ class SchemaConfig
|
|||||||
* Converts an array of options to instance of SchemaConfig
|
* Converts an array of options to instance of SchemaConfig
|
||||||
* (or just returns empty config when array is not passed).
|
* (or just returns empty config when array is not passed).
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param mixed[] $options
|
* @param mixed[] $options
|
||||||
|
*
|
||||||
* @return SchemaConfig
|
* @return SchemaConfig
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function create(array $options = [])
|
public static function create(array $options = [])
|
||||||
{
|
{
|
||||||
@ -132,8 +133,9 @@ class SchemaConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @return ObjectType
|
* @return ObjectType
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getQuery()
|
public function getQuery()
|
||||||
{
|
{
|
||||||
@ -141,9 +143,11 @@ class SchemaConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param ObjectType $query
|
* @param ObjectType $query
|
||||||
|
*
|
||||||
* @return SchemaConfig
|
* @return SchemaConfig
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setQuery($query)
|
public function setQuery($query)
|
||||||
{
|
{
|
||||||
@ -153,8 +157,9 @@ class SchemaConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @return ObjectType
|
* @return ObjectType
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getMutation()
|
public function getMutation()
|
||||||
{
|
{
|
||||||
@ -162,9 +167,11 @@ class SchemaConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param ObjectType $mutation
|
* @param ObjectType $mutation
|
||||||
|
*
|
||||||
* @return SchemaConfig
|
* @return SchemaConfig
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setMutation($mutation)
|
public function setMutation($mutation)
|
||||||
{
|
{
|
||||||
@ -174,8 +181,9 @@ class SchemaConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @return ObjectType
|
* @return ObjectType
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getSubscription()
|
public function getSubscription()
|
||||||
{
|
{
|
||||||
@ -183,9 +191,11 @@ class SchemaConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param ObjectType $subscription
|
* @param ObjectType $subscription
|
||||||
|
*
|
||||||
* @return SchemaConfig
|
* @return SchemaConfig
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setSubscription($subscription)
|
public function setSubscription($subscription)
|
||||||
{
|
{
|
||||||
@ -195,8 +205,9 @@ class SchemaConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @return Type[]
|
* @return Type[]
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getTypes()
|
public function getTypes()
|
||||||
{
|
{
|
||||||
@ -204,9 +215,11 @@ class SchemaConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param Type[]|callable $types
|
* @param Type[]|callable $types
|
||||||
|
*
|
||||||
* @return SchemaConfig
|
* @return SchemaConfig
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setTypes($types)
|
public function setTypes($types)
|
||||||
{
|
{
|
||||||
@ -216,8 +229,9 @@ class SchemaConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @return Directive[]
|
* @return Directive[]
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getDirectives()
|
public function getDirectives()
|
||||||
{
|
{
|
||||||
@ -225,9 +239,11 @@ class SchemaConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param Directive[] $directives
|
* @param Directive[] $directives
|
||||||
|
*
|
||||||
* @return SchemaConfig
|
* @return SchemaConfig
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setDirectives(array $directives)
|
public function setDirectives(array $directives)
|
||||||
{
|
{
|
||||||
@ -237,8 +253,9 @@ class SchemaConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @return callable
|
* @return callable
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getTypeLoader()
|
public function getTypeLoader()
|
||||||
{
|
{
|
||||||
@ -246,8 +263,9 @@ class SchemaConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @return SchemaConfig
|
* @return SchemaConfig
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setTypeLoader(callable $typeLoader)
|
public function setTypeLoader(callable $typeLoader)
|
||||||
{
|
{
|
||||||
@ -266,6 +284,7 @@ class SchemaConfig
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $assumeValid
|
* @param bool $assumeValid
|
||||||
|
*
|
||||||
* @return SchemaConfig
|
* @return SchemaConfig
|
||||||
*/
|
*/
|
||||||
public function setAssumeValid($assumeValid)
|
public function setAssumeValid($assumeValid)
|
||||||
|
@ -207,6 +207,7 @@ class SchemaValidationContext
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $argName
|
* @param string $argName
|
||||||
|
*
|
||||||
* @return InputValueDefinitionNode[]
|
* @return InputValueDefinitionNode[]
|
||||||
*/
|
*/
|
||||||
private function getAllDirectiveArgNodes(Directive $directive, $argName)
|
private function getAllDirectiveArgNodes(Directive $directive, $argName)
|
||||||
@ -228,6 +229,7 @@ class SchemaValidationContext
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $argName
|
* @param string $argName
|
||||||
|
*
|
||||||
* @return TypeNode|null
|
* @return TypeNode|null
|
||||||
*/
|
*/
|
||||||
private function getDirectiveArgTypeNode(Directive $directive, $argName)
|
private function getDirectiveArgTypeNode(Directive $directive, $argName)
|
||||||
@ -358,6 +360,7 @@ class SchemaValidationContext
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ObjectType|InterfaceType $type
|
* @param ObjectType|InterfaceType $type
|
||||||
|
*
|
||||||
* @return ObjectTypeDefinitionNode[]|ObjectTypeExtensionNode[]|InterfaceTypeDefinitionNode[]|InterfaceTypeExtensionNode[]
|
* @return ObjectTypeDefinitionNode[]|ObjectTypeExtensionNode[]|InterfaceTypeDefinitionNode[]|InterfaceTypeExtensionNode[]
|
||||||
*/
|
*/
|
||||||
private function getAllObjectOrInterfaceNodes($type)
|
private function getAllObjectOrInterfaceNodes($type)
|
||||||
@ -372,6 +375,7 @@ class SchemaValidationContext
|
|||||||
/**
|
/**
|
||||||
* @param ObjectType|InterfaceType $type
|
* @param ObjectType|InterfaceType $type
|
||||||
* @param string $fieldName
|
* @param string $fieldName
|
||||||
|
*
|
||||||
* @return FieldDefinitionNode[]
|
* @return FieldDefinitionNode[]
|
||||||
*/
|
*/
|
||||||
private function getAllFieldNodes($type, $fieldName)
|
private function getAllFieldNodes($type, $fieldName)
|
||||||
@ -398,6 +402,7 @@ class SchemaValidationContext
|
|||||||
/**
|
/**
|
||||||
* @param ObjectType|InterfaceType $type
|
* @param ObjectType|InterfaceType $type
|
||||||
* @param string $fieldName
|
* @param string $fieldName
|
||||||
|
*
|
||||||
* @return TypeNode|null
|
* @return TypeNode|null
|
||||||
*/
|
*/
|
||||||
private function getFieldTypeNode($type, $fieldName)
|
private function getFieldTypeNode($type, $fieldName)
|
||||||
@ -410,6 +415,7 @@ class SchemaValidationContext
|
|||||||
/**
|
/**
|
||||||
* @param ObjectType|InterfaceType $type
|
* @param ObjectType|InterfaceType $type
|
||||||
* @param string $fieldName
|
* @param string $fieldName
|
||||||
|
*
|
||||||
* @return FieldDefinitionNode|null
|
* @return FieldDefinitionNode|null
|
||||||
*/
|
*/
|
||||||
private function getFieldNode($type, $fieldName)
|
private function getFieldNode($type, $fieldName)
|
||||||
@ -423,6 +429,7 @@ class SchemaValidationContext
|
|||||||
* @param ObjectType|InterfaceType $type
|
* @param ObjectType|InterfaceType $type
|
||||||
* @param string $fieldName
|
* @param string $fieldName
|
||||||
* @param string $argName
|
* @param string $argName
|
||||||
|
*
|
||||||
* @return InputValueDefinitionNode[]
|
* @return InputValueDefinitionNode[]
|
||||||
*/
|
*/
|
||||||
private function getAllFieldArgNodes($type, $fieldName, $argName)
|
private function getAllFieldArgNodes($type, $fieldName, $argName)
|
||||||
@ -446,6 +453,7 @@ class SchemaValidationContext
|
|||||||
* @param ObjectType|InterfaceType $type
|
* @param ObjectType|InterfaceType $type
|
||||||
* @param string $fieldName
|
* @param string $fieldName
|
||||||
* @param string $argName
|
* @param string $argName
|
||||||
|
*
|
||||||
* @return TypeNode|null
|
* @return TypeNode|null
|
||||||
*/
|
*/
|
||||||
private function getFieldArgTypeNode($type, $fieldName, $argName)
|
private function getFieldArgTypeNode($type, $fieldName, $argName)
|
||||||
@ -459,6 +467,7 @@ class SchemaValidationContext
|
|||||||
* @param ObjectType|InterfaceType $type
|
* @param ObjectType|InterfaceType $type
|
||||||
* @param string $fieldName
|
* @param string $fieldName
|
||||||
* @param string $argName
|
* @param string $argName
|
||||||
|
*
|
||||||
* @return InputValueDefinitionNode|null
|
* @return InputValueDefinitionNode|null
|
||||||
*/
|
*/
|
||||||
private function getFieldArgNode($type, $fieldName, $argName)
|
private function getFieldArgNode($type, $fieldName, $argName)
|
||||||
@ -497,6 +506,7 @@ class SchemaValidationContext
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param InterfaceType $iface
|
* @param InterfaceType $iface
|
||||||
|
*
|
||||||
* @return NamedTypeNode|null
|
* @return NamedTypeNode|null
|
||||||
*/
|
*/
|
||||||
private function getImplementsInterfaceNode(ObjectType $type, $iface)
|
private function getImplementsInterfaceNode(ObjectType $type, $iface)
|
||||||
@ -508,6 +518,7 @@ class SchemaValidationContext
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param InterfaceType $iface
|
* @param InterfaceType $iface
|
||||||
|
*
|
||||||
* @return NamedTypeNode[]
|
* @return NamedTypeNode[]
|
||||||
*/
|
*/
|
||||||
private function getAllImplementsInterfaceNodes(ObjectType $type, $iface)
|
private function getAllImplementsInterfaceNodes(ObjectType $type, $iface)
|
||||||
@ -715,6 +726,7 @@ class SchemaValidationContext
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $typeName
|
* @param string $typeName
|
||||||
|
*
|
||||||
* @return NamedTypeNode[]
|
* @return NamedTypeNode[]
|
||||||
*/
|
*/
|
||||||
private function getUnionMemberTypeNodes(UnionType $union, $typeName)
|
private function getUnionMemberTypeNodes(UnionType $union, $typeName)
|
||||||
@ -722,7 +734,7 @@ class SchemaValidationContext
|
|||||||
if ($union->astNode && $union->astNode->types) {
|
if ($union->astNode && $union->astNode->types) {
|
||||||
return array_filter(
|
return array_filter(
|
||||||
$union->astNode->types,
|
$union->astNode->types,
|
||||||
function (NamedTypeNode $value) use ($typeName) {
|
static function (NamedTypeNode $value) use ($typeName) {
|
||||||
return $value->name->value === $typeName;
|
return $value->name->value === $typeName;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -770,6 +782,7 @@ class SchemaValidationContext
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $valueName
|
* @param string $valueName
|
||||||
|
*
|
||||||
* @return EnumValueDefinitionNode[]
|
* @return EnumValueDefinitionNode[]
|
||||||
*/
|
*/
|
||||||
private function getEnumValueNodes(EnumType $enum, $valueName)
|
private function getEnumValueNodes(EnumType $enum, $valueName)
|
||||||
@ -777,7 +790,7 @@ class SchemaValidationContext
|
|||||||
if ($enum->astNode && $enum->astNode->values) {
|
if ($enum->astNode && $enum->astNode->values) {
|
||||||
return array_filter(
|
return array_filter(
|
||||||
iterator_to_array($enum->astNode->values),
|
iterator_to_array($enum->astNode->values),
|
||||||
function (EnumValueDefinitionNode $value) use ($valueName) {
|
static function (EnumValueDefinitionNode $value) use ($valueName) {
|
||||||
return $value->name->value === $valueName;
|
return $value->name->value === $valueName;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -4,6 +4,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Utils;
|
namespace GraphQL\Utils;
|
||||||
|
|
||||||
|
use ArrayAccess;
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
use GraphQL\Error\InvariantViolation;
|
use GraphQL\Error\InvariantViolation;
|
||||||
use GraphQL\Language\AST\BooleanValueNode;
|
use GraphQL\Language\AST\BooleanValueNode;
|
||||||
@ -36,6 +38,9 @@ use GraphQL\Type\Definition\NonNull;
|
|||||||
use GraphQL\Type\Definition\ScalarType;
|
use GraphQL\Type\Definition\ScalarType;
|
||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
use GraphQL\Type\Schema;
|
use GraphQL\Type\Schema;
|
||||||
|
use stdClass;
|
||||||
|
use Throwable;
|
||||||
|
use Traversable;
|
||||||
use function array_combine;
|
use function array_combine;
|
||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
use function array_map;
|
use function array_map;
|
||||||
@ -77,8 +82,9 @@ class AST
|
|||||||
*
|
*
|
||||||
* This is a reverse operation for AST::toArray($node)
|
* This is a reverse operation for AST::toArray($node)
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param mixed[] $node
|
* @param mixed[] $node
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function fromArray(array $node) : Node
|
public static function fromArray(array $node) : Node
|
||||||
{
|
{
|
||||||
@ -114,8 +120,9 @@ class AST
|
|||||||
/**
|
/**
|
||||||
* Convert AST node to serializable array
|
* Convert AST node to serializable array
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function toArray(Node $node)
|
public static function toArray(Node $node)
|
||||||
{
|
{
|
||||||
@ -140,9 +147,11 @@ class AST
|
|||||||
* | Mixed | Enum Value |
|
* | Mixed | Enum Value |
|
||||||
* | null | NullValue |
|
* | null | NullValue |
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param Type|mixed|null $value
|
* @param Type|mixed|null $value
|
||||||
|
*
|
||||||
* @return ObjectValueNode|ListValueNode|BooleanValueNode|IntValueNode|FloatValueNode|EnumValueNode|StringValueNode|NullValueNode
|
* @return ObjectValueNode|ListValueNode|BooleanValueNode|IntValueNode|FloatValueNode|EnumValueNode|StringValueNode|NullValueNode
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function astFromValue($value, InputType $type)
|
public static function astFromValue($value, InputType $type)
|
||||||
{
|
{
|
||||||
@ -163,7 +172,7 @@ class AST
|
|||||||
// the value is not an array, convert the value using the list's item type.
|
// the value is not an array, convert the value using the list's item type.
|
||||||
if ($type instanceof ListOfType) {
|
if ($type instanceof ListOfType) {
|
||||||
$itemType = $type->getWrappedType();
|
$itemType = $type->getWrappedType();
|
||||||
if (is_array($value) || ($value instanceof \Traversable)) {
|
if (is_array($value) || ($value instanceof Traversable)) {
|
||||||
$valuesNodes = [];
|
$valuesNodes = [];
|
||||||
foreach ($value as $item) {
|
foreach ($value as $item) {
|
||||||
$itemNode = self::astFromValue($item, $itemType);
|
$itemNode = self::astFromValue($item, $itemType);
|
||||||
@ -184,7 +193,7 @@ class AST
|
|||||||
// in the PHP object according to the fields in the input type.
|
// in the PHP object according to the fields in the input type.
|
||||||
if ($type instanceof InputObjectType) {
|
if ($type instanceof InputObjectType) {
|
||||||
$isArray = is_array($value);
|
$isArray = is_array($value);
|
||||||
$isArrayLike = $isArray || $value instanceof \ArrayAccess;
|
$isArrayLike = $isArray || $value instanceof ArrayAccess;
|
||||||
if ($value === null || (! $isArrayLike && ! is_object($value))) {
|
if ($value === null || (! $isArrayLike && ! is_object($value))) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -204,7 +213,7 @@ class AST
|
|||||||
} elseif ($isArray) {
|
} elseif ($isArray) {
|
||||||
$fieldExists = array_key_exists($fieldName, $value);
|
$fieldExists = array_key_exists($fieldName, $value);
|
||||||
} elseif ($isArrayLike) {
|
} elseif ($isArrayLike) {
|
||||||
/** @var \ArrayAccess $value */
|
/** @var ArrayAccess $value */
|
||||||
$fieldExists = $value->offsetExists($fieldName);
|
$fieldExists = $value->offsetExists($fieldName);
|
||||||
} else {
|
} else {
|
||||||
$fieldExists = property_exists($value, $fieldName);
|
$fieldExists = property_exists($value, $fieldName);
|
||||||
@ -234,12 +243,12 @@ class AST
|
|||||||
// to an externally represented value before converting into an AST.
|
// to an externally represented value before converting into an AST.
|
||||||
try {
|
try {
|
||||||
$serialized = $type->serialize($value);
|
$serialized = $type->serialize($value);
|
||||||
} catch (\Exception $error) {
|
} catch (Exception $error) {
|
||||||
if ($error instanceof Error && $type instanceof EnumType) {
|
if ($error instanceof Error && $type instanceof EnumType) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
throw $error;
|
throw $error;
|
||||||
} catch (\Throwable $error) {
|
} catch (Throwable $error) {
|
||||||
if ($error instanceof Error && $type instanceof EnumType) {
|
if ($error instanceof Error && $type instanceof EnumType) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -304,13 +313,16 @@ class AST
|
|||||||
* | Enum Value | Mixed |
|
* | Enum Value | Mixed |
|
||||||
* | Null Value | null |
|
* | Null Value | null |
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param ValueNode|null $valueNode
|
* @param ValueNode|null $valueNode
|
||||||
* @param mixed[]|null $variables
|
* @param mixed[]|null $variables
|
||||||
* @return mixed[]|null|\stdClass
|
*
|
||||||
* @throws \Exception
|
* @return mixed[]|stdClass|null
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function valueFromAST($valueNode, InputType $type, $variables = null)
|
public static function valueFromAST($valueNode, InputType $type, ?array $variables = null)
|
||||||
{
|
{
|
||||||
$undefined = Utils::undefined();
|
$undefined = Utils::undefined();
|
||||||
|
|
||||||
@ -393,7 +405,7 @@ class AST
|
|||||||
$fields = $type->getFields();
|
$fields = $type->getFields();
|
||||||
$fieldNodes = Utils::keyMap(
|
$fieldNodes = Utils::keyMap(
|
||||||
$valueNode->fields,
|
$valueNode->fields,
|
||||||
function ($field) {
|
static function ($field) {
|
||||||
return $field->name->value;
|
return $field->name->value;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -442,9 +454,9 @@ class AST
|
|||||||
// no value is returned.
|
// no value is returned.
|
||||||
try {
|
try {
|
||||||
return $type->parseLiteral($valueNode, $variables);
|
return $type->parseLiteral($valueNode, $variables);
|
||||||
} catch (\Exception $error) {
|
} catch (Exception $error) {
|
||||||
return $undefined;
|
return $undefined;
|
||||||
} catch (\Throwable $error) {
|
} catch (Throwable $error) {
|
||||||
return $undefined;
|
return $undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -455,8 +467,10 @@ class AST
|
|||||||
/**
|
/**
|
||||||
* Returns true if the provided valueNode is a variable which is not defined
|
* Returns true if the provided valueNode is a variable which is not defined
|
||||||
* in the set of variables.
|
* in the set of variables.
|
||||||
|
*
|
||||||
* @param ValueNode $valueNode
|
* @param ValueNode $valueNode
|
||||||
* @param mixed[] $variables
|
* @param mixed[] $variables
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private static function isMissingVariable($valueNode, $variables)
|
private static function isMissingVariable($valueNode, $variables)
|
||||||
@ -481,11 +495,14 @@ class AST
|
|||||||
* | Enum | Mixed |
|
* | Enum | Mixed |
|
||||||
* | Null | null |
|
* | Null | null |
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param Node $valueNode
|
* @param Node $valueNode
|
||||||
* @param mixed[]|null $variables
|
* @param mixed[]|null $variables
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function valueFromASTUntyped($valueNode, ?array $variables = null)
|
public static function valueFromASTUntyped($valueNode, ?array $variables = null)
|
||||||
{
|
{
|
||||||
@ -502,7 +519,7 @@ class AST
|
|||||||
return $valueNode->value;
|
return $valueNode->value;
|
||||||
case $valueNode instanceof ListValueNode:
|
case $valueNode instanceof ListValueNode:
|
||||||
return array_map(
|
return array_map(
|
||||||
function ($node) use ($variables) {
|
static function ($node) use ($variables) {
|
||||||
return self::valueFromASTUntyped($node, $variables);
|
return self::valueFromASTUntyped($node, $variables);
|
||||||
},
|
},
|
||||||
iterator_to_array($valueNode->values)
|
iterator_to_array($valueNode->values)
|
||||||
@ -510,13 +527,13 @@ class AST
|
|||||||
case $valueNode instanceof ObjectValueNode:
|
case $valueNode instanceof ObjectValueNode:
|
||||||
return array_combine(
|
return array_combine(
|
||||||
array_map(
|
array_map(
|
||||||
function ($field) {
|
static function ($field) {
|
||||||
return $field->name->value;
|
return $field->name->value;
|
||||||
},
|
},
|
||||||
iterator_to_array($valueNode->fields)
|
iterator_to_array($valueNode->fields)
|
||||||
),
|
),
|
||||||
array_map(
|
array_map(
|
||||||
function ($field) use ($variables) {
|
static function ($field) use ($variables) {
|
||||||
return self::valueFromASTUntyped($field->value, $variables);
|
return self::valueFromASTUntyped($field->value, $variables);
|
||||||
},
|
},
|
||||||
iterator_to_array($valueNode->fields)
|
iterator_to_array($valueNode->fields)
|
||||||
@ -525,7 +542,7 @@ class AST
|
|||||||
case $valueNode instanceof VariableNode:
|
case $valueNode instanceof VariableNode:
|
||||||
$variableName = $valueNode->name->value;
|
$variableName = $valueNode->name->value;
|
||||||
|
|
||||||
return ($variables && isset($variables[$variableName]))
|
return $variables && isset($variables[$variableName])
|
||||||
? $variables[$variableName]
|
? $variables[$variableName]
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
@ -536,10 +553,13 @@ class AST
|
|||||||
/**
|
/**
|
||||||
* Returns type definition for given AST Type node
|
* Returns type definition for given AST Type node
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param NamedTypeNode|ListTypeNode|NonNullTypeNode $inputTypeNode
|
* @param NamedTypeNode|ListTypeNode|NonNullTypeNode $inputTypeNode
|
||||||
|
*
|
||||||
* @return Type|null
|
* @return Type|null
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function typeFromAST(Schema $schema, $inputTypeNode)
|
public static function typeFromAST(Schema $schema, $inputTypeNode)
|
||||||
{
|
{
|
||||||
@ -563,9 +583,11 @@ class AST
|
|||||||
/**
|
/**
|
||||||
* Returns operation type ("query", "mutation" or "subscription") given a document and operation name
|
* Returns operation type ("query", "mutation" or "subscription") given a document and operation name
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param string $operationName
|
* @param string $operationName
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function getOperation(DocumentNode $document, $operationName = null)
|
public static function getOperation(DocumentNode $document, $operationName = null)
|
||||||
{
|
{
|
||||||
|
@ -34,6 +34,7 @@ use GraphQL\Type\Definition\NonNull;
|
|||||||
use GraphQL\Type\Definition\ObjectType;
|
use GraphQL\Type\Definition\ObjectType;
|
||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
use GraphQL\Type\Definition\UnionType;
|
use GraphQL\Type\Definition\UnionType;
|
||||||
|
use Throwable;
|
||||||
use function array_reverse;
|
use function array_reverse;
|
||||||
use function implode;
|
use function implode;
|
||||||
use function is_array;
|
use function is_array;
|
||||||
@ -82,7 +83,7 @@ class ASTDefinitionBuilder
|
|||||||
'description' => $this->getDescription($directiveNode),
|
'description' => $this->getDescription($directiveNode),
|
||||||
'locations' => Utils::map(
|
'locations' => Utils::map(
|
||||||
$directiveNode->locations,
|
$directiveNode->locations,
|
||||||
function ($node) {
|
static function ($node) {
|
||||||
return $node->value;
|
return $node->value;
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
@ -135,7 +136,7 @@ class ASTDefinitionBuilder
|
|||||||
{
|
{
|
||||||
return Utils::keyValMap(
|
return Utils::keyValMap(
|
||||||
$values,
|
$values,
|
||||||
function ($value) {
|
static function ($value) {
|
||||||
return $value->name->value;
|
return $value->name->value;
|
||||||
},
|
},
|
||||||
function ($value) {
|
function ($value) {
|
||||||
@ -160,6 +161,7 @@ class ASTDefinitionBuilder
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Type|InputType
|
* @return Type|InputType
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
private function internalBuildWrappedType(TypeNode $typeNode)
|
private function internalBuildWrappedType(TypeNode $typeNode)
|
||||||
@ -171,7 +173,9 @@ class ASTDefinitionBuilder
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string|NamedTypeNode $ref
|
* @param string|NamedTypeNode $ref
|
||||||
|
*
|
||||||
* @return Type
|
* @return Type
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public function buildType($ref)
|
public function buildType($ref)
|
||||||
@ -186,7 +190,9 @@ class ASTDefinitionBuilder
|
|||||||
/**
|
/**
|
||||||
* @param string $typeName
|
* @param string $typeName
|
||||||
* @param NamedTypeNode|null $typeNode
|
* @param NamedTypeNode|null $typeNode
|
||||||
|
*
|
||||||
* @return Type
|
* @return Type
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
private function internalBuildType($typeName, $typeNode = null)
|
private function internalBuildType($typeName, $typeNode = null)
|
||||||
@ -198,7 +204,7 @@ class ASTDefinitionBuilder
|
|||||||
$fn = $this->typeConfigDecorator;
|
$fn = $this->typeConfigDecorator;
|
||||||
try {
|
try {
|
||||||
$config = $fn($type->config, $this->typeDefintionsMap[$typeName], $this->typeDefintionsMap);
|
$config = $fn($type->config, $this->typeDefintionsMap[$typeName], $this->typeDefintionsMap);
|
||||||
} catch (\Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
sprintf('Type config decorator passed to %s threw an error ', static::class) .
|
sprintf('Type config decorator passed to %s threw an error ', static::class) .
|
||||||
sprintf('when building %s type: %s', $typeName, $e->getMessage()),
|
sprintf('when building %s type: %s', $typeName, $e->getMessage()),
|
||||||
@ -232,7 +238,9 @@ class ASTDefinitionBuilder
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode|EnumTypeDefinitionNode|ScalarTypeDefinitionNode|InputObjectTypeDefinitionNode|UnionTypeDefinitionNode $def
|
* @param ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode|EnumTypeDefinitionNode|ScalarTypeDefinitionNode|InputObjectTypeDefinitionNode|UnionTypeDefinitionNode $def
|
||||||
|
*
|
||||||
* @return CustomScalarType|EnumType|InputObjectType|InterfaceType|ObjectType|UnionType
|
* @return CustomScalarType|EnumType|InputObjectType|InterfaceType|ObjectType|UnionType
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
private function makeSchemaDef($def)
|
private function makeSchemaDef($def)
|
||||||
@ -280,7 +288,7 @@ class ASTDefinitionBuilder
|
|||||||
return $def->fields
|
return $def->fields
|
||||||
? Utils::keyValMap(
|
? Utils::keyValMap(
|
||||||
$def->fields,
|
$def->fields,
|
||||||
function ($field) {
|
static function ($field) {
|
||||||
return $field->name->value;
|
return $field->name->value;
|
||||||
},
|
},
|
||||||
function ($field) {
|
function ($field) {
|
||||||
@ -309,6 +317,7 @@ class ASTDefinitionBuilder
|
|||||||
* deprecation reason.
|
* deprecation reason.
|
||||||
*
|
*
|
||||||
* @param EnumValueDefinitionNode | FieldDefinitionNode $node
|
* @param EnumValueDefinitionNode | FieldDefinitionNode $node
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function getDeprecationReason($node)
|
private function getDeprecationReason($node)
|
||||||
@ -357,7 +366,7 @@ class ASTDefinitionBuilder
|
|||||||
'values' => $def->values
|
'values' => $def->values
|
||||||
? Utils::keyValMap(
|
? Utils::keyValMap(
|
||||||
$def->values,
|
$def->values,
|
||||||
function ($enumValue) {
|
static function ($enumValue) {
|
||||||
return $enumValue->name->value;
|
return $enumValue->name->value;
|
||||||
},
|
},
|
||||||
function ($enumValue) {
|
function ($enumValue) {
|
||||||
@ -399,7 +408,7 @@ class ASTDefinitionBuilder
|
|||||||
'name' => $def->name->value,
|
'name' => $def->name->value,
|
||||||
'description' => $this->getDescription($def),
|
'description' => $this->getDescription($def),
|
||||||
'astNode' => $def,
|
'astNode' => $def,
|
||||||
'serialize' => function ($value) {
|
'serialize' => static function ($value) {
|
||||||
return $value;
|
return $value;
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
@ -422,7 +431,9 @@ class ASTDefinitionBuilder
|
|||||||
/**
|
/**
|
||||||
* @param ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode|EnumTypeExtensionNode|ScalarTypeDefinitionNode|InputObjectTypeDefinitionNode $def
|
* @param ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode|EnumTypeExtensionNode|ScalarTypeDefinitionNode|InputObjectTypeDefinitionNode $def
|
||||||
* @param mixed[] $config
|
* @param mixed[] $config
|
||||||
|
*
|
||||||
* @return CustomScalarType|EnumType|InputObjectType|InterfaceType|ObjectType|UnionType
|
* @return CustomScalarType|EnumType|InputObjectType|InterfaceType|ObjectType|UnionType
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
private function makeSchemaDefFromConfig($def, array $config)
|
private function makeSchemaDefFromConfig($def, array $config)
|
||||||
@ -450,6 +461,7 @@ class ASTDefinitionBuilder
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param TypeNode|ListTypeNode|NonNullTypeNode $typeNode
|
* @param TypeNode|ListTypeNode|NonNullTypeNode $typeNode
|
||||||
|
*
|
||||||
* @return TypeNode
|
* @return TypeNode
|
||||||
*/
|
*/
|
||||||
private function getNamedTypeNode(TypeNode $typeNode)
|
private function getNamedTypeNode(TypeNode $typeNode)
|
||||||
@ -464,6 +476,7 @@ class ASTDefinitionBuilder
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param TypeNode|ListTypeNode|NonNullTypeNode $inputTypeNode
|
* @param TypeNode|ListTypeNode|NonNullTypeNode $inputTypeNode
|
||||||
|
*
|
||||||
* @return Type
|
* @return Type
|
||||||
*/
|
*/
|
||||||
private function buildWrappedType(Type $innerType, TypeNode $inputTypeNode)
|
private function buildWrappedType(Type $innerType, TypeNode $inputTypeNode)
|
||||||
|
@ -21,6 +21,7 @@ use GraphQL\Type\Definition\ScalarType;
|
|||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
use GraphQL\Type\Definition\UnionType;
|
use GraphQL\Type\Definition\UnionType;
|
||||||
use GraphQL\Type\Schema;
|
use GraphQL\Type\Schema;
|
||||||
|
use TypeError;
|
||||||
use function array_flip;
|
use function array_flip;
|
||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
use function array_keys;
|
use function array_keys;
|
||||||
@ -141,7 +142,7 @@ class BreakingChangesFinder
|
|||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*
|
*
|
||||||
* @throws \TypeError
|
* @throws TypeError
|
||||||
*/
|
*/
|
||||||
private static function typeKindName(Type $type)
|
private static function typeKindName(Type $type)
|
||||||
{
|
{
|
||||||
@ -169,7 +170,7 @@ class BreakingChangesFinder
|
|||||||
return 'an Input type';
|
return 'an Input type';
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new \TypeError('unknown type ' . $type->name);
|
throw new TypeError('unknown type ' . $type->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -340,7 +341,6 @@ class BreakingChangesFinder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private static function isChangeSafeForInputObjectFieldOrFieldArg(
|
private static function isChangeSafeForInputObjectFieldOrFieldArg(
|
||||||
@ -370,8 +370,8 @@ class BreakingChangesFinder
|
|||||||
$newType->getWrappedType()
|
$newType->getWrappedType()
|
||||||
)) ||
|
)) ||
|
||||||
// moving from non-null to nullable of the same underlying type is safe
|
// moving from non-null to nullable of the same underlying type is safe
|
||||||
(! ($newType instanceof NonNull) &&
|
! ($newType instanceof NonNull) &&
|
||||||
self::isChangeSafeForInputObjectFieldOrFieldArg($oldType->getWrappedType(), $newType));
|
self::isChangeSafeForInputObjectFieldOrFieldArg($oldType->getWrappedType(), $newType);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -492,7 +492,7 @@ class BreakingChangesFinder
|
|||||||
$newArgs = $newTypeFields[$fieldName]->args;
|
$newArgs = $newTypeFields[$fieldName]->args;
|
||||||
$newArgDef = Utils::find(
|
$newArgDef = Utils::find(
|
||||||
$newArgs,
|
$newArgs,
|
||||||
function ($arg) use ($oldArgDef) {
|
static function ($arg) use ($oldArgDef) {
|
||||||
return $arg->name === $oldArgDef->name;
|
return $arg->name === $oldArgDef->name;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -531,7 +531,7 @@ class BreakingChangesFinder
|
|||||||
$oldArgs = $oldTypeFields[$fieldName]->args;
|
$oldArgs = $oldTypeFields[$fieldName]->args;
|
||||||
$oldArgDef = Utils::find(
|
$oldArgDef = Utils::find(
|
||||||
$oldArgs,
|
$oldArgs,
|
||||||
function ($arg) use ($newArgDef) {
|
static function ($arg) use ($newArgDef) {
|
||||||
return $arg->name === $newArgDef->name;
|
return $arg->name === $newArgDef->name;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -586,7 +586,7 @@ class BreakingChangesFinder
|
|||||||
foreach ($oldInterfaces as $oldInterface) {
|
foreach ($oldInterfaces as $oldInterface) {
|
||||||
if (Utils::find(
|
if (Utils::find(
|
||||||
$newInterfaces,
|
$newInterfaces,
|
||||||
function (InterfaceType $interface) use ($oldInterface) {
|
static function (InterfaceType $interface) use ($oldInterface) {
|
||||||
return $interface->name === $oldInterface->name;
|
return $interface->name === $oldInterface->name;
|
||||||
}
|
}
|
||||||
)) {
|
)) {
|
||||||
@ -629,7 +629,7 @@ class BreakingChangesFinder
|
|||||||
{
|
{
|
||||||
return Utils::keyMap(
|
return Utils::keyMap(
|
||||||
$schema->getDirectives(),
|
$schema->getDirectives(),
|
||||||
function ($dir) {
|
static function ($dir) {
|
||||||
return $dir->name;
|
return $dir->name;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -678,7 +678,7 @@ class BreakingChangesFinder
|
|||||||
{
|
{
|
||||||
return Utils::keyMap(
|
return Utils::keyMap(
|
||||||
$directive->args ?: [],
|
$directive->args ?: [],
|
||||||
function ($arg) {
|
static function ($arg) {
|
||||||
return $arg->name;
|
return $arg->name;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -831,7 +831,6 @@ class BreakingChangesFinder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @return string[][]
|
* @return string[][]
|
||||||
*/
|
*/
|
||||||
public static function findInterfacesAddedToObjectTypes(
|
public static function findInterfacesAddedToObjectTypes(
|
||||||
@ -853,7 +852,7 @@ class BreakingChangesFinder
|
|||||||
foreach ($newInterfaces as $newInterface) {
|
foreach ($newInterfaces as $newInterface) {
|
||||||
if (Utils::find(
|
if (Utils::find(
|
||||||
$oldInterfaces,
|
$oldInterfaces,
|
||||||
function (InterfaceType $interface) use ($newInterface) {
|
static function (InterfaceType $interface) use ($newInterface) {
|
||||||
return $interface->name === $newInterface->name;
|
return $interface->name === $newInterface->name;
|
||||||
}
|
}
|
||||||
)) {
|
)) {
|
||||||
|
@ -49,10 +49,12 @@ class BuildSchema
|
|||||||
* A helper function to build a GraphQLSchema directly from a source
|
* A helper function to build a GraphQLSchema directly from a source
|
||||||
* document.
|
* document.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param DocumentNode|Source|string $source
|
* @param DocumentNode|Source|string $source
|
||||||
* @param bool[] $options
|
* @param bool[] $options
|
||||||
|
*
|
||||||
* @return Schema
|
* @return Schema
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function build($source, ?callable $typeConfigDecorator = null, array $options = [])
|
public static function build($source, ?callable $typeConfigDecorator = null, array $options = [])
|
||||||
{
|
{
|
||||||
@ -76,11 +78,13 @@ class BuildSchema
|
|||||||
* - commentDescriptions:
|
* - commentDescriptions:
|
||||||
* Provide true to use preceding comments as the description.
|
* Provide true to use preceding comments as the description.
|
||||||
*
|
*
|
||||||
|
* @param bool[] $options
|
||||||
|
*
|
||||||
|
* @return Schema
|
||||||
|
*
|
||||||
|
* @throws Error
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @param bool[] $options
|
|
||||||
* @return Schema
|
|
||||||
* @throws Error
|
|
||||||
*/
|
*/
|
||||||
public static function buildAST(DocumentNode $ast, ?callable $typeConfigDecorator = null, array $options = [])
|
public static function buildAST(DocumentNode $ast, ?callable $typeConfigDecorator = null, array $options = [])
|
||||||
{
|
{
|
||||||
@ -134,14 +138,14 @@ class BuildSchema
|
|||||||
$defintionBuilder = new ASTDefinitionBuilder(
|
$defintionBuilder = new ASTDefinitionBuilder(
|
||||||
$this->nodeMap,
|
$this->nodeMap,
|
||||||
$this->options,
|
$this->options,
|
||||||
function ($typeName) {
|
static function ($typeName) {
|
||||||
throw new Error('Type "' . $typeName . '" not found in document.');
|
throw new Error('Type "' . $typeName . '" not found in document.');
|
||||||
},
|
},
|
||||||
$this->typeConfigDecorator
|
$this->typeConfigDecorator
|
||||||
);
|
);
|
||||||
|
|
||||||
$directives = array_map(
|
$directives = array_map(
|
||||||
function ($def) use ($defintionBuilder) {
|
static function ($def) use ($defintionBuilder) {
|
||||||
return $defintionBuilder->buildDirective($def);
|
return $defintionBuilder->buildDirective($def);
|
||||||
},
|
},
|
||||||
$directiveDefs
|
$directiveDefs
|
||||||
@ -150,7 +154,7 @@ class BuildSchema
|
|||||||
// If specified directives were not explicitly declared, add them.
|
// If specified directives were not explicitly declared, add them.
|
||||||
$skip = array_reduce(
|
$skip = array_reduce(
|
||||||
$directives,
|
$directives,
|
||||||
function ($hasSkip, $directive) {
|
static function ($hasSkip, $directive) {
|
||||||
return $hasSkip || $directive->name === 'skip';
|
return $hasSkip || $directive->name === 'skip';
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -160,7 +164,7 @@ class BuildSchema
|
|||||||
|
|
||||||
$include = array_reduce(
|
$include = array_reduce(
|
||||||
$directives,
|
$directives,
|
||||||
function ($hasInclude, $directive) {
|
static function ($hasInclude, $directive) {
|
||||||
return $hasInclude || $directive->name === 'include';
|
return $hasInclude || $directive->name === 'include';
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -170,7 +174,7 @@ class BuildSchema
|
|||||||
|
|
||||||
$deprecated = array_reduce(
|
$deprecated = array_reduce(
|
||||||
$directives,
|
$directives,
|
||||||
function ($hasDeprecated, $directive) {
|
static function ($hasDeprecated, $directive) {
|
||||||
return $hasDeprecated || $directive->name === 'deprecated';
|
return $hasDeprecated || $directive->name === 'deprecated';
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -182,7 +186,7 @@ class BuildSchema
|
|||||||
// typed values below, that would throw immediately while type system
|
// typed values below, that would throw immediately while type system
|
||||||
// validation with validateSchema() will produce more actionable results.
|
// validation with validateSchema() will produce more actionable results.
|
||||||
|
|
||||||
$schema = new Schema([
|
return new Schema([
|
||||||
'query' => isset($operationTypes['query'])
|
'query' => isset($operationTypes['query'])
|
||||||
? $defintionBuilder->buildType($operationTypes['query'])
|
? $defintionBuilder->buildType($operationTypes['query'])
|
||||||
: null,
|
: null,
|
||||||
@ -192,7 +196,7 @@ class BuildSchema
|
|||||||
'subscription' => isset($operationTypes['subscription'])
|
'subscription' => isset($operationTypes['subscription'])
|
||||||
? $defintionBuilder->buildType($operationTypes['subscription'])
|
? $defintionBuilder->buildType($operationTypes['subscription'])
|
||||||
: null,
|
: null,
|
||||||
'typeLoader' => function ($name) use ($defintionBuilder) {
|
'typeLoader' => static function ($name) use ($defintionBuilder) {
|
||||||
return $defintionBuilder->buildType($name);
|
return $defintionBuilder->buildType($name);
|
||||||
},
|
},
|
||||||
'directives' => $directives,
|
'directives' => $directives,
|
||||||
@ -206,13 +210,13 @@ class BuildSchema
|
|||||||
return $types;
|
return $types;
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $schema;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param SchemaDefinitionNode $schemaDef
|
* @param SchemaDefinitionNode $schemaDef
|
||||||
|
*
|
||||||
* @return string[]
|
* @return string[]
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
private function getOperationTypes($schemaDef)
|
private function getOperationTypes($schemaDef)
|
||||||
|
@ -4,7 +4,10 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Utils;
|
namespace GraphQL\Utils;
|
||||||
|
|
||||||
|
use ArrayAccess;
|
||||||
use GraphQL\Type\Definition\EnumValueDefinition;
|
use GraphQL\Type\Definition\EnumValueDefinition;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use SplObjectStorage;
|
||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
use function array_search;
|
use function array_search;
|
||||||
use function array_splice;
|
use function array_splice;
|
||||||
@ -22,7 +25,7 @@ use function is_string;
|
|||||||
*
|
*
|
||||||
* Class MixedStore
|
* Class MixedStore
|
||||||
*/
|
*/
|
||||||
class MixedStore implements \ArrayAccess
|
class MixedStore implements ArrayAccess
|
||||||
{
|
{
|
||||||
/** @var EnumValueDefinition[] */
|
/** @var EnumValueDefinition[] */
|
||||||
private $standardStore;
|
private $standardStore;
|
||||||
@ -30,7 +33,7 @@ class MixedStore implements \ArrayAccess
|
|||||||
/** @var mixed[] */
|
/** @var mixed[] */
|
||||||
private $floatStore;
|
private $floatStore;
|
||||||
|
|
||||||
/** @var \SplObjectStorage */
|
/** @var SplObjectStorage */
|
||||||
private $objectStore;
|
private $objectStore;
|
||||||
|
|
||||||
/** @var callable[] */
|
/** @var callable[] */
|
||||||
@ -67,7 +70,7 @@ class MixedStore implements \ArrayAccess
|
|||||||
{
|
{
|
||||||
$this->standardStore = [];
|
$this->standardStore = [];
|
||||||
$this->floatStore = [];
|
$this->floatStore = [];
|
||||||
$this->objectStore = new \SplObjectStorage();
|
$this->objectStore = new SplObjectStorage();
|
||||||
$this->arrayKeys = [];
|
$this->arrayKeys = [];
|
||||||
$this->arrayValues = [];
|
$this->arrayValues = [];
|
||||||
$this->nullValueIsSet = false;
|
$this->nullValueIsSet = false;
|
||||||
@ -77,10 +80,13 @@ class MixedStore implements \ArrayAccess
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether a offset exists
|
* Whether a offset exists
|
||||||
|
*
|
||||||
* @link http://php.net/manual/en/arrayaccess.offsetexists.php
|
* @link http://php.net/manual/en/arrayaccess.offsetexists.php
|
||||||
|
*
|
||||||
* @param mixed $offset <p>
|
* @param mixed $offset <p>
|
||||||
* An offset to check for.
|
* An offset to check for.
|
||||||
* </p>
|
* </p>
|
||||||
|
*
|
||||||
* @return bool true on success or false on failure.
|
* @return bool true on success or false on failure.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
@ -122,10 +128,13 @@ class MixedStore implements \ArrayAccess
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Offset to retrieve
|
* Offset to retrieve
|
||||||
|
*
|
||||||
* @link http://php.net/manual/en/arrayaccess.offsetget.php
|
* @link http://php.net/manual/en/arrayaccess.offsetget.php
|
||||||
|
*
|
||||||
* @param mixed $offset <p>
|
* @param mixed $offset <p>
|
||||||
* The offset to retrieve.
|
* The offset to retrieve.
|
||||||
* </p>
|
* </p>
|
||||||
|
*
|
||||||
* @return mixed Can return all value types.
|
* @return mixed Can return all value types.
|
||||||
*/
|
*/
|
||||||
public function offsetGet($offset)
|
public function offsetGet($offset)
|
||||||
@ -165,13 +174,16 @@ class MixedStore implements \ArrayAccess
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Offset to set
|
* Offset to set
|
||||||
|
*
|
||||||
* @link http://php.net/manual/en/arrayaccess.offsetset.php
|
* @link http://php.net/manual/en/arrayaccess.offsetset.php
|
||||||
|
*
|
||||||
* @param mixed $offset <p>
|
* @param mixed $offset <p>
|
||||||
* The offset to assign the value to.
|
* The offset to assign the value to.
|
||||||
* </p>
|
* </p>
|
||||||
* @param mixed $value <p>
|
* @param mixed $value <p>
|
||||||
* The value to set.
|
* The value to set.
|
||||||
* </p>
|
* </p>
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function offsetSet($offset, $value)
|
public function offsetSet($offset, $value)
|
||||||
@ -195,16 +207,19 @@ class MixedStore implements \ArrayAccess
|
|||||||
$this->nullValue = $value;
|
$this->nullValue = $value;
|
||||||
$this->nullValueIsSet = true;
|
$this->nullValueIsSet = true;
|
||||||
} else {
|
} else {
|
||||||
throw new \InvalidArgumentException('Unexpected offset type: ' . Utils::printSafe($offset));
|
throw new InvalidArgumentException('Unexpected offset type: ' . Utils::printSafe($offset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Offset to unset
|
* Offset to unset
|
||||||
|
*
|
||||||
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
|
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
|
||||||
|
*
|
||||||
* @param mixed $offset <p>
|
* @param mixed $offset <p>
|
||||||
* The offset to unset.
|
* The offset to unset.
|
||||||
* </p>
|
* </p>
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function offsetUnset($offset)
|
public function offsetUnset($offset)
|
||||||
|
@ -22,12 +22,13 @@ class PairSet
|
|||||||
* @param string $a
|
* @param string $a
|
||||||
* @param string $b
|
* @param string $b
|
||||||
* @param bool $areMutuallyExclusive
|
* @param bool $areMutuallyExclusive
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function has($a, $b, $areMutuallyExclusive)
|
public function has($a, $b, $areMutuallyExclusive)
|
||||||
{
|
{
|
||||||
$first = $this->data[$a] ?? null;
|
$first = $this->data[$a] ?? null;
|
||||||
$result = ($first && isset($first[$b])) ? $first[$b] : null;
|
$result = $first && isset($first[$b]) ? $first[$b] : null;
|
||||||
if ($result === null) {
|
if ($result === null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -42,17 +42,19 @@ class SchemaPrinter
|
|||||||
*
|
*
|
||||||
* - commentDescriptions:
|
* - commentDescriptions:
|
||||||
* Provide true to use preceding comments as the description.
|
* Provide true to use preceding comments as the description.
|
||||||
* @api
|
*
|
||||||
* @param bool[] $options
|
* @param bool[] $options
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function doPrint(Schema $schema, array $options = []) : string
|
public static function doPrint(Schema $schema, array $options = []) : string
|
||||||
{
|
{
|
||||||
return self::printFilteredSchema(
|
return self::printFilteredSchema(
|
||||||
$schema,
|
$schema,
|
||||||
function ($type) {
|
static function ($type) {
|
||||||
return ! Directive::isSpecifiedDirective($type);
|
return ! Directive::isSpecifiedDirective($type);
|
||||||
},
|
},
|
||||||
function ($type) {
|
static function ($type) {
|
||||||
return ! Type::isBuiltInType($type);
|
return ! Type::isBuiltInType($type);
|
||||||
},
|
},
|
||||||
$options
|
$options
|
||||||
@ -66,7 +68,7 @@ class SchemaPrinter
|
|||||||
{
|
{
|
||||||
$directives = array_filter(
|
$directives = array_filter(
|
||||||
$schema->getDirectives(),
|
$schema->getDirectives(),
|
||||||
function ($directive) use ($directiveFilter) {
|
static function ($directive) use ($directiveFilter) {
|
||||||
return $directiveFilter($directive);
|
return $directiveFilter($directive);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -83,13 +85,13 @@ class SchemaPrinter
|
|||||||
array_merge(
|
array_merge(
|
||||||
[self::printSchemaDefinition($schema)],
|
[self::printSchemaDefinition($schema)],
|
||||||
array_map(
|
array_map(
|
||||||
function ($directive) use ($options) {
|
static function ($directive) use ($options) {
|
||||||
return self::printDirective($directive, $options);
|
return self::printDirective($directive, $options);
|
||||||
},
|
},
|
||||||
$directives
|
$directives
|
||||||
),
|
),
|
||||||
array_map(
|
array_map(
|
||||||
function ($type) use ($options) {
|
static function ($type) use ($options) {
|
||||||
return self::printType($type, $options);
|
return self::printType($type, $options);
|
||||||
},
|
},
|
||||||
$types
|
$types
|
||||||
@ -175,7 +177,7 @@ class SchemaPrinter
|
|||||||
return self::printDescriptionWithComments($lines, $indentation, $firstInBlock);
|
return self::printDescriptionWithComments($lines, $indentation, $firstInBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
$description = ($indentation && ! $firstInBlock)
|
$description = $indentation && ! $firstInBlock
|
||||||
? "\n" . $indentation . '"""'
|
? "\n" . $indentation . '"""'
|
||||||
: $indentation . '"""';
|
: $indentation . '"""';
|
||||||
|
|
||||||
@ -274,7 +276,7 @@ class SchemaPrinter
|
|||||||
// If every arg does not have a description, print them on one line.
|
// If every arg does not have a description, print them on one line.
|
||||||
if (Utils::every(
|
if (Utils::every(
|
||||||
$args,
|
$args,
|
||||||
function ($arg) {
|
static function ($arg) {
|
||||||
return empty($arg->description);
|
return empty($arg->description);
|
||||||
}
|
}
|
||||||
)) {
|
)) {
|
||||||
@ -286,7 +288,7 @@ class SchemaPrinter
|
|||||||
implode(
|
implode(
|
||||||
"\n",
|
"\n",
|
||||||
array_map(
|
array_map(
|
||||||
function ($arg, $i) use ($indentation, $options) {
|
static function ($arg, $i) use ($indentation, $options) {
|
||||||
return self::printDescription($options, $arg, ' ' . $indentation, ! $i) . ' ' . $indentation .
|
return self::printDescription($options, $arg, ' ' . $indentation, ! $i) . ' ' . $indentation .
|
||||||
self::printInputValue($arg);
|
self::printInputValue($arg);
|
||||||
},
|
},
|
||||||
@ -358,7 +360,7 @@ class SchemaPrinter
|
|||||||
' implements ' . implode(
|
' implements ' . implode(
|
||||||
' & ',
|
' & ',
|
||||||
array_map(
|
array_map(
|
||||||
function ($i) {
|
static function ($i) {
|
||||||
return $i->name;
|
return $i->name;
|
||||||
},
|
},
|
||||||
$interfaces
|
$interfaces
|
||||||
@ -379,7 +381,7 @@ class SchemaPrinter
|
|||||||
return implode(
|
return implode(
|
||||||
"\n",
|
"\n",
|
||||||
array_map(
|
array_map(
|
||||||
function ($f, $i) use ($options) {
|
static function ($f, $i) use ($options) {
|
||||||
return self::printDescription($options, $f, ' ', ! $i) . ' ' .
|
return self::printDescription($options, $f, ' ', ! $i) . ' ' .
|
||||||
$f->name . self::printArgs($options, $f->args, ' ') . ': ' .
|
$f->name . self::printArgs($options, $f->args, ' ') . ': ' .
|
||||||
(string) $f->getType() . self::printDeprecated($f);
|
(string) $f->getType() . self::printDeprecated($f);
|
||||||
@ -439,7 +441,7 @@ class SchemaPrinter
|
|||||||
return implode(
|
return implode(
|
||||||
"\n",
|
"\n",
|
||||||
array_map(
|
array_map(
|
||||||
function ($value, $i) use ($options) {
|
static function ($value, $i) use ($options) {
|
||||||
return self::printDescription($options, $value, ' ', ! $i) . ' ' .
|
return self::printDescription($options, $value, ' ', ! $i) . ' ' .
|
||||||
$value->name . self::printDeprecated($value);
|
$value->name . self::printDeprecated($value);
|
||||||
},
|
},
|
||||||
@ -463,7 +465,7 @@ class SchemaPrinter
|
|||||||
implode(
|
implode(
|
||||||
"\n",
|
"\n",
|
||||||
array_map(
|
array_map(
|
||||||
function ($f, $i) use ($options) {
|
static function ($f, $i) use ($options) {
|
||||||
return self::printDescription($options, $f, ' ', ! $i) . ' ' . self::printInputValue($f);
|
return self::printDescription($options, $f, ' ', ! $i) . ' ' . self::printInputValue($f);
|
||||||
},
|
},
|
||||||
$fields,
|
$fields,
|
||||||
@ -474,8 +476,9 @@ class SchemaPrinter
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param bool[] $options
|
* @param bool[] $options
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function printIntrospectionSchema(Schema $schema, array $options = []) : string
|
public static function printIntrospectionSchema(Schema $schema, array $options = []) : string
|
||||||
{
|
{
|
||||||
|
@ -46,6 +46,7 @@ class TypeComparators
|
|||||||
*
|
*
|
||||||
* @param AbstractType $maybeSubType
|
* @param AbstractType $maybeSubType
|
||||||
* @param AbstractType $superType
|
* @param AbstractType $superType
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function isTypeSubTypeOf(Schema $schema, $maybeSubType, $superType)
|
public static function isTypeSubTypeOf(Schema $schema, $maybeSubType, $superType)
|
||||||
|
@ -64,7 +64,6 @@ class TypeInfo
|
|||||||
private $enumValue;
|
private $enumValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param Type|null $initialType
|
* @param Type|null $initialType
|
||||||
*/
|
*/
|
||||||
public function __construct(Schema $schema, $initialType = null)
|
public function __construct(Schema $schema, $initialType = null)
|
||||||
@ -128,6 +127,7 @@ class TypeInfo
|
|||||||
*
|
*
|
||||||
* @param Type|null $type
|
* @param Type|null $type
|
||||||
* @param Type[]|null $typeMap
|
* @param Type[]|null $typeMap
|
||||||
|
*
|
||||||
* @return Type[]|null
|
* @return Type[]|null
|
||||||
*/
|
*/
|
||||||
public static function extractTypes($type, ?array $typeMap = null)
|
public static function extractTypes($type, ?array $typeMap = null)
|
||||||
@ -175,7 +175,7 @@ class TypeInfo
|
|||||||
foreach ((array) $type->getFields() as $fieldName => $field) {
|
foreach ((array) $type->getFields() as $fieldName => $field) {
|
||||||
if (! empty($field->args)) {
|
if (! empty($field->args)) {
|
||||||
$fieldArgTypes = array_map(
|
$fieldArgTypes = array_map(
|
||||||
function (FieldArgument $arg) {
|
static function (FieldArgument $arg) {
|
||||||
return $arg->getType();
|
return $arg->getType();
|
||||||
},
|
},
|
||||||
$field->args
|
$field->args
|
||||||
@ -200,6 +200,7 @@ class TypeInfo
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Type[] $typeMap
|
* @param Type[] $typeMap
|
||||||
|
*
|
||||||
* @return Type[]
|
* @return Type[]
|
||||||
*/
|
*/
|
||||||
public static function extractTypesFromDirectives(Directive $directive, array $typeMap = [])
|
public static function extractTypesFromDirectives(Directive $directive, array $typeMap = [])
|
||||||
@ -304,7 +305,7 @@ class TypeInfo
|
|||||||
if ($fieldOrDirective) {
|
if ($fieldOrDirective) {
|
||||||
$argDef = Utils::find(
|
$argDef = Utils::find(
|
||||||
$fieldOrDirective->args,
|
$fieldOrDirective->args,
|
||||||
function ($arg) use ($node) {
|
static function ($arg) use ($node) {
|
||||||
return $arg->name === $node->name->value;
|
return $arg->name === $node->name->value;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -406,7 +407,9 @@ class TypeInfo
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param NamedTypeNode|ListTypeNode|NonNullTypeNode $inputTypeNode
|
* @param NamedTypeNode|ListTypeNode|NonNullTypeNode $inputTypeNode
|
||||||
|
*
|
||||||
* @return Type|null
|
* @return Type|null
|
||||||
|
*
|
||||||
* @throws InvariantViolation
|
* @throws InvariantViolation
|
||||||
*/
|
*/
|
||||||
public static function typeFromAST(Schema $schema, $inputTypeNode)
|
public static function typeFromAST(Schema $schema, $inputTypeNode)
|
||||||
|
@ -4,6 +4,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Utils;
|
namespace GraphQL\Utils;
|
||||||
|
|
||||||
|
use ErrorException;
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
use GraphQL\Error\InvariantViolation;
|
use GraphQL\Error\InvariantViolation;
|
||||||
use GraphQL\Error\Warning;
|
use GraphQL\Error\Warning;
|
||||||
@ -11,6 +13,8 @@ use GraphQL\Language\AST\Node;
|
|||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
use GraphQL\Type\Definition\WrappingType;
|
use GraphQL\Type\Definition\WrappingType;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
|
use LogicException;
|
||||||
|
use stdClass;
|
||||||
use Traversable;
|
use Traversable;
|
||||||
use function array_keys;
|
use function array_keys;
|
||||||
use function array_map;
|
use function array_map;
|
||||||
@ -55,13 +59,14 @@ class Utils
|
|||||||
{
|
{
|
||||||
static $undefined;
|
static $undefined;
|
||||||
|
|
||||||
return $undefined ?: $undefined = new \stdClass();
|
return $undefined ?: $undefined = new stdClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the value is invalid
|
* Check if the value is invalid
|
||||||
*
|
*
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function isInvalid($value)
|
public static function isInvalid($value)
|
||||||
@ -100,12 +105,13 @@ class Utils
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed|Traversable $traversable
|
* @param mixed|Traversable $traversable
|
||||||
|
*
|
||||||
* @return mixed|null
|
* @return mixed|null
|
||||||
*/
|
*/
|
||||||
public static function find($traversable, callable $predicate)
|
public static function find($traversable, callable $predicate)
|
||||||
{
|
{
|
||||||
self::invariant(
|
self::invariant(
|
||||||
is_array($traversable) || $traversable instanceof \Traversable,
|
is_array($traversable) || $traversable instanceof Traversable,
|
||||||
__METHOD__ . ' expects array or Traversable'
|
__METHOD__ . ' expects array or Traversable'
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -120,13 +126,15 @@ class Utils
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed|Traversable $traversable
|
* @param mixed|Traversable $traversable
|
||||||
|
*
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function filter($traversable, callable $predicate)
|
public static function filter($traversable, callable $predicate)
|
||||||
{
|
{
|
||||||
self::invariant(
|
self::invariant(
|
||||||
is_array($traversable) || $traversable instanceof \Traversable,
|
is_array($traversable) || $traversable instanceof Traversable,
|
||||||
__METHOD__ . ' expects array or Traversable'
|
__METHOD__ . ' expects array or Traversable'
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -147,14 +155,16 @@ class Utils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed|\Traversable $traversable
|
* @param mixed|Traversable $traversable
|
||||||
|
*
|
||||||
* @return int[][]
|
* @return int[][]
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function map($traversable, callable $fn)
|
public static function map($traversable, callable $fn)
|
||||||
{
|
{
|
||||||
self::invariant(
|
self::invariant(
|
||||||
is_array($traversable) || $traversable instanceof \Traversable,
|
is_array($traversable) || $traversable instanceof Traversable,
|
||||||
__METHOD__ . ' expects array or Traversable'
|
__METHOD__ . ' expects array or Traversable'
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -168,19 +178,21 @@ class Utils
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed|Traversable $traversable
|
* @param mixed|Traversable $traversable
|
||||||
|
*
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function mapKeyValue($traversable, callable $fn)
|
public static function mapKeyValue($traversable, callable $fn)
|
||||||
{
|
{
|
||||||
self::invariant(
|
self::invariant(
|
||||||
is_array($traversable) || $traversable instanceof \Traversable,
|
is_array($traversable) || $traversable instanceof Traversable,
|
||||||
__METHOD__ . ' expects array or Traversable'
|
__METHOD__ . ' expects array or Traversable'
|
||||||
);
|
);
|
||||||
|
|
||||||
$map = [];
|
$map = [];
|
||||||
foreach ($traversable as $key => $value) {
|
foreach ($traversable as $key => $value) {
|
||||||
list($newKey, $newValue) = $fn($value, $key);
|
[$newKey, $newValue] = $fn($value, $key);
|
||||||
$map[$newKey] = $newValue;
|
$map[$newKey] = $newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,13 +201,15 @@ class Utils
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed|Traversable $traversable
|
* @param mixed|Traversable $traversable
|
||||||
|
*
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
* @throws \Exception
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function keyMap($traversable, callable $keyFn)
|
public static function keyMap($traversable, callable $keyFn)
|
||||||
{
|
{
|
||||||
self::invariant(
|
self::invariant(
|
||||||
is_array($traversable) || $traversable instanceof \Traversable,
|
is_array($traversable) || $traversable instanceof Traversable,
|
||||||
__METHOD__ . ' expects array or Traversable'
|
__METHOD__ . ' expects array or Traversable'
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -215,7 +229,7 @@ class Utils
|
|||||||
public static function each($traversable, callable $fn)
|
public static function each($traversable, callable $fn)
|
||||||
{
|
{
|
||||||
self::invariant(
|
self::invariant(
|
||||||
is_array($traversable) || $traversable instanceof \Traversable,
|
is_array($traversable) || $traversable instanceof Traversable,
|
||||||
__METHOD__ . ' expects array or Traversable'
|
__METHOD__ . ' expects array or Traversable'
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -237,12 +251,13 @@ class Utils
|
|||||||
* $keyFn is also allowed to return array of keys. Then value will be added to all arrays with given keys
|
* $keyFn is also allowed to return array of keys. Then value will be added to all arrays with given keys
|
||||||
*
|
*
|
||||||
* @param mixed[]|Traversable $traversable
|
* @param mixed[]|Traversable $traversable
|
||||||
|
*
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
*/
|
*/
|
||||||
public static function groupBy($traversable, callable $keyFn)
|
public static function groupBy($traversable, callable $keyFn)
|
||||||
{
|
{
|
||||||
self::invariant(
|
self::invariant(
|
||||||
is_array($traversable) || $traversable instanceof \Traversable,
|
is_array($traversable) || $traversable instanceof Traversable,
|
||||||
__METHOD__ . ' expects array or Traversable'
|
__METHOD__ . ' expects array or Traversable'
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -259,6 +274,7 @@ class Utils
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed[]|Traversable $traversable
|
* @param mixed[]|Traversable $traversable
|
||||||
|
*
|
||||||
* @return mixed[][]
|
* @return mixed[][]
|
||||||
*/
|
*/
|
||||||
public static function keyValMap($traversable, callable $keyFn, callable $valFn)
|
public static function keyValMap($traversable, callable $keyFn, callable $valFn)
|
||||||
@ -273,6 +289,7 @@ class Utils
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed[] $traversable
|
* @param mixed[] $traversable
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function every($traversable, callable $predicate)
|
public static function every($traversable, callable $predicate)
|
||||||
@ -305,6 +322,7 @@ class Utils
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Type|mixed $var
|
* @param Type|mixed $var
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function getVariableType($var)
|
public static function getVariableType($var)
|
||||||
@ -323,11 +341,12 @@ class Utils
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $var
|
* @param mixed $var
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function printSafeJson($var)
|
public static function printSafeJson($var)
|
||||||
{
|
{
|
||||||
if ($var instanceof \stdClass) {
|
if ($var instanceof stdClass) {
|
||||||
$var = (array) $var;
|
$var = (array) $var;
|
||||||
}
|
}
|
||||||
if (is_array($var)) {
|
if (is_array($var)) {
|
||||||
@ -357,6 +376,7 @@ class Utils
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Type|mixed $var
|
* @param Type|mixed $var
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function printSafe($var)
|
public static function printSafe($var)
|
||||||
@ -401,6 +421,7 @@ class Utils
|
|||||||
*
|
*
|
||||||
* @param string $ord
|
* @param string $ord
|
||||||
* @param string $encoding
|
* @param string $encoding
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function chr($ord, $encoding = 'UTF-8')
|
public static function chr($ord, $encoding = 'UTF-8')
|
||||||
@ -420,6 +441,7 @@ class Utils
|
|||||||
*
|
*
|
||||||
* @param string $char
|
* @param string $char
|
||||||
* @param string $encoding
|
* @param string $encoding
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function ord($char, $encoding = 'UTF-8')
|
public static function ord($char, $encoding = 'UTF-8')
|
||||||
@ -442,6 +464,7 @@ class Utils
|
|||||||
*
|
*
|
||||||
* @param string $string
|
* @param string $string
|
||||||
* @param int $position
|
* @param int $position
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function charCodeAt($string, $position)
|
public static function charCodeAt($string, $position)
|
||||||
@ -453,6 +476,7 @@ class Utils
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int|null $code
|
* @param int|null $code
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function printCharCode($code)
|
public static function printCharCode($code)
|
||||||
@ -472,6 +496,7 @@ class Utils
|
|||||||
* Upholds the spec rules about naming.
|
* Upholds the spec rules about naming.
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
|
*
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public static function assertValidName($name)
|
public static function assertValidName($name)
|
||||||
@ -487,6 +512,7 @@ class Utils
|
|||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param Node|null $node
|
* @param Node|null $node
|
||||||
|
*
|
||||||
* @return Error|null
|
* @return Error|null
|
||||||
*/
|
*/
|
||||||
public static function isValidNameError($name, $node = null)
|
public static function isValidNameError($name, $node = null)
|
||||||
@ -512,18 +538,19 @@ class Utils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps original closure with PHP error handling (using set_error_handler).
|
* Wraps original callable with PHP error handling (using set_error_handler).
|
||||||
* Resulting closure will collect all PHP errors that occur during the call in $errors array.
|
* Resulting callable will collect all PHP errors that occur during the call in $errors array.
|
||||||
*
|
*
|
||||||
* @param \ErrorException[] $errors
|
* @param ErrorException[] $errors
|
||||||
* @return \Closure
|
*
|
||||||
|
* @return callable
|
||||||
*/
|
*/
|
||||||
public static function withErrorHandling(callable $fn, array &$errors)
|
public static function withErrorHandling(callable $fn, array &$errors)
|
||||||
{
|
{
|
||||||
return function () use ($fn, &$errors) {
|
return static function () use ($fn, &$errors) {
|
||||||
// Catch custom errors (to report them in query results)
|
// Catch custom errors (to report them in query results)
|
||||||
set_error_handler(function ($severity, $message, $file, $line) use (&$errors) {
|
set_error_handler(static function ($severity, $message, $file, $line) use (&$errors) {
|
||||||
$errors[] = new \ErrorException($message, 0, $severity, $file, $line);
|
$errors[] = new ErrorException($message, 0, $severity, $file, $line);
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -536,12 +563,13 @@ class Utils
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string[] $items
|
* @param string[] $items
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function quotedOrList(array $items)
|
public static function quotedOrList(array $items)
|
||||||
{
|
{
|
||||||
$items = array_map(
|
$items = array_map(
|
||||||
function ($item) {
|
static function ($item) {
|
||||||
return sprintf('"%s"', $item);
|
return sprintf('"%s"', $item);
|
||||||
},
|
},
|
||||||
$items
|
$items
|
||||||
@ -552,12 +580,13 @@ class Utils
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string[] $items
|
* @param string[] $items
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function orList(array $items)
|
public static function orList(array $items)
|
||||||
{
|
{
|
||||||
if (count($items) === 0) {
|
if (count($items) === 0) {
|
||||||
throw new \LogicException('items must not need to be empty.');
|
throw new LogicException('items must not need to be empty.');
|
||||||
}
|
}
|
||||||
$selected = array_slice($items, 0, 5);
|
$selected = array_slice($items, 0, 5);
|
||||||
$selectedLength = count($selected);
|
$selectedLength = count($selected);
|
||||||
@ -569,7 +598,7 @@ class Utils
|
|||||||
|
|
||||||
return array_reduce(
|
return array_reduce(
|
||||||
range(1, $selectedLength - 1),
|
range(1, $selectedLength - 1),
|
||||||
function ($list, $index) use ($selected, $selectedLength) {
|
static function ($list, $index) use ($selected, $selectedLength) {
|
||||||
return $list .
|
return $list .
|
||||||
($selectedLength > 2 ? ', ' : ' ') .
|
($selectedLength > 2 ? ', ' : ' ') .
|
||||||
($index === $selectedLength - 1 ? 'or ' : '') .
|
($index === $selectedLength - 1 ? 'or ' : '') .
|
||||||
@ -586,8 +615,10 @@ class Utils
|
|||||||
* Includes a custom alteration from Damerau-Levenshtein to treat case changes
|
* Includes a custom alteration from Damerau-Levenshtein to treat case changes
|
||||||
* as a single edit which helps identify mis-cased values with an edit distance
|
* as a single edit which helps identify mis-cased values with an edit distance
|
||||||
* of 1
|
* of 1
|
||||||
|
*
|
||||||
* @param string $input
|
* @param string $input
|
||||||
* @param string[] $options
|
* @param string[] $options
|
||||||
|
*
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
public static function suggestionList($input, array $options)
|
public static function suggestionList($input, array $options)
|
||||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Utils;
|
namespace GraphQL\Utils;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
use GraphQL\Language\AST\Node;
|
use GraphQL\Language\AST\Node;
|
||||||
use GraphQL\Type\Definition\EnumType;
|
use GraphQL\Type\Definition\EnumType;
|
||||||
@ -12,6 +13,8 @@ use GraphQL\Type\Definition\InputType;
|
|||||||
use GraphQL\Type\Definition\ListOfType;
|
use GraphQL\Type\Definition\ListOfType;
|
||||||
use GraphQL\Type\Definition\NonNull;
|
use GraphQL\Type\Definition\NonNull;
|
||||||
use GraphQL\Type\Definition\ScalarType;
|
use GraphQL\Type\Definition\ScalarType;
|
||||||
|
use Throwable;
|
||||||
|
use Traversable;
|
||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
use function array_keys;
|
use function array_keys;
|
||||||
use function array_map;
|
use function array_map;
|
||||||
@ -61,7 +64,7 @@ class Value
|
|||||||
// the original error.
|
// the original error.
|
||||||
try {
|
try {
|
||||||
return self::ofValue($type->parseValue($value));
|
return self::ofValue($type->parseValue($value));
|
||||||
} catch (\Exception $error) {
|
} catch (Exception $error) {
|
||||||
return self::ofErrors([
|
return self::ofErrors([
|
||||||
self::coercionError(
|
self::coercionError(
|
||||||
sprintf('Expected type %s', $type->name),
|
sprintf('Expected type %s', $type->name),
|
||||||
@ -71,7 +74,7 @@ class Value
|
|||||||
$error
|
$error
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
} catch (\Throwable $error) {
|
} catch (Throwable $error) {
|
||||||
return self::ofErrors([
|
return self::ofErrors([
|
||||||
self::coercionError(
|
self::coercionError(
|
||||||
sprintf('Expected type %s', $type->name),
|
sprintf('Expected type %s', $type->name),
|
||||||
@ -95,7 +98,7 @@ class Value
|
|||||||
$suggestions = Utils::suggestionList(
|
$suggestions = Utils::suggestionList(
|
||||||
Utils::printSafe($value),
|
Utils::printSafe($value),
|
||||||
array_map(
|
array_map(
|
||||||
function ($enumValue) {
|
static function ($enumValue) {
|
||||||
return $enumValue->name;
|
return $enumValue->name;
|
||||||
},
|
},
|
||||||
$type->getValues()
|
$type->getValues()
|
||||||
@ -118,7 +121,7 @@ class Value
|
|||||||
|
|
||||||
if ($type instanceof ListOfType) {
|
if ($type instanceof ListOfType) {
|
||||||
$itemType = $type->getWrappedType();
|
$itemType = $type->getWrappedType();
|
||||||
if (is_array($value) || $value instanceof \Traversable) {
|
if (is_array($value) || $value instanceof Traversable) {
|
||||||
$errors = [];
|
$errors = [];
|
||||||
$coercedValue = [];
|
$coercedValue = [];
|
||||||
foreach ($value as $index => $itemValue) {
|
foreach ($value as $index => $itemValue) {
|
||||||
@ -144,7 +147,7 @@ class Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($type instanceof InputObjectType) {
|
if ($type instanceof InputObjectType) {
|
||||||
if (! is_object($value) && ! is_array($value) && ! $value instanceof \Traversable) {
|
if (! is_object($value) && ! is_array($value) && ! $value instanceof Traversable) {
|
||||||
return self::ofErrors([
|
return self::ofErrors([
|
||||||
self::coercionError(
|
self::coercionError(
|
||||||
sprintf('Expected type %s to be an object', $type->name),
|
sprintf('Expected type %s to be an object', $type->name),
|
||||||
@ -229,7 +232,8 @@ class Value
|
|||||||
* @param Node $blameNode
|
* @param Node $blameNode
|
||||||
* @param mixed[]|null $path
|
* @param mixed[]|null $path
|
||||||
* @param string $subMessage
|
* @param string $subMessage
|
||||||
* @param \Exception|\Throwable|null $originalError
|
* @param Exception|Throwable|null $originalError
|
||||||
|
*
|
||||||
* @return Error
|
* @return Error
|
||||||
*/
|
*/
|
||||||
private static function coercionError(
|
private static function coercionError(
|
||||||
@ -258,6 +262,7 @@ class Value
|
|||||||
* Build a string describing the path into the value where the error was found
|
* Build a string describing the path into the value where the error was found
|
||||||
*
|
*
|
||||||
* @param mixed[]|null $path
|
* @param mixed[]|null $path
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private static function printPath(?array $path = null)
|
private static function printPath(?array $path = null)
|
||||||
@ -277,6 +282,7 @@ class Value
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return (mixed|null)[]
|
* @return (mixed|null)[]
|
||||||
*/
|
*/
|
||||||
private static function ofValue($value)
|
private static function ofValue($value)
|
||||||
@ -287,6 +293,7 @@ class Value
|
|||||||
/**
|
/**
|
||||||
* @param mixed|null $prev
|
* @param mixed|null $prev
|
||||||
* @param mixed|null $key
|
* @param mixed|null $key
|
||||||
|
*
|
||||||
* @return (mixed|null)[]
|
* @return (mixed|null)[]
|
||||||
*/
|
*/
|
||||||
private static function atPath($prev, $key)
|
private static function atPath($prev, $key)
|
||||||
@ -297,6 +304,7 @@ class Value
|
|||||||
/**
|
/**
|
||||||
* @param Error[] $errors
|
* @param Error[] $errors
|
||||||
* @param Error|Error[] $moreErrors
|
* @param Error|Error[] $moreErrors
|
||||||
|
*
|
||||||
* @return Error[]
|
* @return Error[]
|
||||||
*/
|
*/
|
||||||
private static function add($errors, $moreErrors)
|
private static function add($errors, $moreErrors)
|
||||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Validator;
|
namespace GraphQL\Validator;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
use GraphQL\Language\AST\DocumentNode;
|
use GraphQL\Language\AST\DocumentNode;
|
||||||
use GraphQL\Language\Visitor;
|
use GraphQL\Language\Visitor;
|
||||||
@ -41,6 +42,7 @@ use GraphQL\Validator\Rules\ValuesOfCorrectType;
|
|||||||
use GraphQL\Validator\Rules\VariablesAreInputTypes;
|
use GraphQL\Validator\Rules\VariablesAreInputTypes;
|
||||||
use GraphQL\Validator\Rules\VariablesDefaultValueAllowed;
|
use GraphQL\Validator\Rules\VariablesDefaultValueAllowed;
|
||||||
use GraphQL\Validator\Rules\VariablesInAllowedPosition;
|
use GraphQL\Validator\Rules\VariablesInAllowedPosition;
|
||||||
|
use Throwable;
|
||||||
use function array_filter;
|
use function array_filter;
|
||||||
use function array_merge;
|
use function array_merge;
|
||||||
use function count;
|
use function count;
|
||||||
@ -82,9 +84,11 @@ class DocumentValidator
|
|||||||
/**
|
/**
|
||||||
* Primary method for query validation. See class description for details.
|
* Primary method for query validation. See class description for details.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param ValidationRule[]|null $rules
|
* @param ValidationRule[]|null $rules
|
||||||
|
*
|
||||||
* @return Error[]
|
* @return Error[]
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function validate(
|
public static function validate(
|
||||||
Schema $schema,
|
Schema $schema,
|
||||||
@ -109,8 +113,9 @@ class DocumentValidator
|
|||||||
/**
|
/**
|
||||||
* Returns all global validation rules.
|
* Returns all global validation rules.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @return ValidationRule[]
|
* @return ValidationRule[]
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function allRules()
|
public static function allRules()
|
||||||
{
|
{
|
||||||
@ -183,6 +188,7 @@ class DocumentValidator
|
|||||||
* while maintaining the visitor skip and break API.
|
* while maintaining the visitor skip and break API.
|
||||||
*
|
*
|
||||||
* @param ValidationRule[] $rules
|
* @param ValidationRule[] $rules
|
||||||
|
*
|
||||||
* @return Error[]
|
* @return Error[]
|
||||||
*/
|
*/
|
||||||
public static function visitUsingRules(Schema $schema, TypeInfo $typeInfo, DocumentNode $documentNode, array $rules)
|
public static function visitUsingRules(Schema $schema, TypeInfo $typeInfo, DocumentNode $documentNode, array $rules)
|
||||||
@ -203,9 +209,11 @@ class DocumentValidator
|
|||||||
*
|
*
|
||||||
* $rule = DocumentValidator::getRule(GraphQL\Validator\Rules\QueryComplexity::class);
|
* $rule = DocumentValidator::getRule(GraphQL\Validator\Rules\QueryComplexity::class);
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param string $name
|
* @param string $name
|
||||||
|
*
|
||||||
* @return ValidationRule
|
* @return ValidationRule
|
||||||
|
*
|
||||||
|
* @api
|
||||||
*/
|
*/
|
||||||
public static function getRule($name)
|
public static function getRule($name)
|
||||||
{
|
{
|
||||||
@ -235,11 +243,11 @@ class DocumentValidator
|
|||||||
return is_array($value)
|
return is_array($value)
|
||||||
? count(array_filter(
|
? count(array_filter(
|
||||||
$value,
|
$value,
|
||||||
function ($item) {
|
static function ($item) {
|
||||||
return $item instanceof \Exception || $item instanceof \Throwable;
|
return $item instanceof Exception || $item instanceof Throwable;
|
||||||
}
|
}
|
||||||
)) === count($value)
|
)) === count($value)
|
||||||
: ($value instanceof \Exception || $value instanceof \Throwable);
|
: ($value instanceof Exception || $value instanceof Throwable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function append(&$arr, $items)
|
public static function append(&$arr, $items)
|
||||||
@ -259,6 +267,7 @@ class DocumentValidator
|
|||||||
* Deprecated. Rely on validation for documents containing literal values.
|
* Deprecated. Rely on validation for documents containing literal values.
|
||||||
*
|
*
|
||||||
* @deprecated
|
* @deprecated
|
||||||
|
*
|
||||||
* @return Error[]
|
* @return Error[]
|
||||||
*/
|
*/
|
||||||
public static function isValidLiteralValue(Type $type, $valueNode)
|
public static function isValidLiteralValue(Type $type, $valueNode)
|
||||||
|
@ -31,7 +31,7 @@ class DisableIntrospection extends QuerySecurityRule
|
|||||||
return $this->invokeIfNeeded(
|
return $this->invokeIfNeeded(
|
||||||
$context,
|
$context,
|
||||||
[
|
[
|
||||||
NodeKind::FIELD => function (FieldNode $node) use ($context) {
|
NodeKind::FIELD => static function (FieldNode $node) use ($context) {
|
||||||
if ($node->name->value !== '__type' && $node->name->value !== '__schema') {
|
if ($node->name->value !== '__type' && $node->name->value !== '__schema') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ class ExecutableDefinitions extends ValidationRule
|
|||||||
public function getVisitor(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::DOCUMENT => function (DocumentNode $node) use ($context) {
|
NodeKind::DOCUMENT => static function (DocumentNode $node) use ($context) {
|
||||||
/** @var Node $definition */
|
/** @var Node $definition */
|
||||||
foreach ($node->definitions as $definition) {
|
foreach ($node->definitions as $definition) {
|
||||||
if ($definition instanceof OperationDefinitionNode ||
|
if ($definition instanceof OperationDefinitionNode ||
|
||||||
|
@ -74,6 +74,7 @@ class FieldsOnCorrectType extends ValidationRule
|
|||||||
*
|
*
|
||||||
* @param ObjectType|InterfaceType $type
|
* @param ObjectType|InterfaceType $type
|
||||||
* @param string $fieldName
|
* @param string $fieldName
|
||||||
|
*
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
private function getSuggestedTypeNames(Schema $schema, $type, $fieldName)
|
private function getSuggestedTypeNames(Schema $schema, $type, $fieldName)
|
||||||
@ -120,6 +121,7 @@ class FieldsOnCorrectType extends ValidationRule
|
|||||||
*
|
*
|
||||||
* @param ObjectType|InterfaceType $type
|
* @param ObjectType|InterfaceType $type
|
||||||
* @param string $fieldName
|
* @param string $fieldName
|
||||||
|
*
|
||||||
* @return array|string[]
|
* @return array|string[]
|
||||||
*/
|
*/
|
||||||
private function getSuggestedFieldNames(Schema $schema, $type, $fieldName)
|
private function getSuggestedFieldNames(Schema $schema, $type, $fieldName)
|
||||||
@ -139,6 +141,7 @@ class FieldsOnCorrectType extends ValidationRule
|
|||||||
* @param string $type
|
* @param string $type
|
||||||
* @param string[] $suggestedTypeNames
|
* @param string[] $suggestedTypeNames
|
||||||
* @param string[] $suggestedFieldNames
|
* @param string[] $suggestedFieldNames
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function undefinedFieldMessage(
|
public static function undefinedFieldMessage(
|
||||||
|
@ -19,7 +19,7 @@ class FragmentsOnCompositeTypes extends ValidationRule
|
|||||||
public function getVisitor(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::INLINE_FRAGMENT => function (InlineFragmentNode $node) use ($context) {
|
NodeKind::INLINE_FRAGMENT => static function (InlineFragmentNode $node) use ($context) {
|
||||||
if (! $node->typeCondition) {
|
if (! $node->typeCondition) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ class FragmentsOnCompositeTypes extends ValidationRule
|
|||||||
[$node->typeCondition]
|
[$node->typeCondition]
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
NodeKind::FRAGMENT_DEFINITION => function (FragmentDefinitionNode $node) use ($context) {
|
NodeKind::FRAGMENT_DEFINITION => static function (FragmentDefinitionNode $node) use ($context) {
|
||||||
$type = TypeInfo::typeFromAST($context->getSchema(), $node->typeCondition);
|
$type = TypeInfo::typeFromAST($context->getSchema(), $node->typeCondition);
|
||||||
|
|
||||||
if (! $type || Type::isCompositeType($type)) {
|
if (! $type || Type::isCompositeType($type)) {
|
||||||
|
@ -26,7 +26,7 @@ class KnownArgumentNames extends ValidationRule
|
|||||||
public function getVisitor(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::ARGUMENT => function (ArgumentNode $node, $key, $parent, $path, $ancestors) use ($context) {
|
NodeKind::ARGUMENT => static function (ArgumentNode $node, $key, $parent, $path, $ancestors) use ($context) {
|
||||||
/** @var NodeList|Node[] $ancestors */
|
/** @var NodeList|Node[] $ancestors */
|
||||||
$argDef = $context->getArgument();
|
$argDef = $context->getArgument();
|
||||||
if ($argDef !== null) {
|
if ($argDef !== null) {
|
||||||
@ -46,7 +46,7 @@ class KnownArgumentNames extends ValidationRule
|
|||||||
Utils::suggestionList(
|
Utils::suggestionList(
|
||||||
$node->name->value,
|
$node->name->value,
|
||||||
array_map(
|
array_map(
|
||||||
function ($arg) {
|
static function ($arg) {
|
||||||
return $arg->name;
|
return $arg->name;
|
||||||
},
|
},
|
||||||
$fieldDef->args
|
$fieldDef->args
|
||||||
@ -66,7 +66,7 @@ class KnownArgumentNames extends ValidationRule
|
|||||||
Utils::suggestionList(
|
Utils::suggestionList(
|
||||||
$node->name->value,
|
$node->name->value,
|
||||||
array_map(
|
array_map(
|
||||||
function ($arg) {
|
static function ($arg) {
|
||||||
return $arg->name;
|
return $arg->name;
|
||||||
},
|
},
|
||||||
$directive->args
|
$directive->args
|
||||||
|
@ -37,7 +37,7 @@ class KnownDirectives extends ValidationRule
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$locationsMap[$def->name->value] = array_map(function ($name) {
|
$locationsMap[$def->name->value] = array_map(static function ($name) {
|
||||||
return $name->value;
|
return $name->value;
|
||||||
}, $def->locations);
|
}, $def->locations);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ class KnownFragmentNames extends ValidationRule
|
|||||||
public function getVisitor(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::FRAGMENT_SPREAD => function (FragmentSpreadNode $node) use ($context) {
|
NodeKind::FRAGMENT_SPREAD => static function (FragmentSpreadNode $node) use ($context) {
|
||||||
$fragmentName = $node->name->value;
|
$fragmentName = $node->name->value;
|
||||||
$fragment = $context->getFragment($fragmentName);
|
$fragment = $context->getFragment($fragmentName);
|
||||||
if ($fragment) {
|
if ($fragment) {
|
||||||
|
@ -23,7 +23,7 @@ class KnownTypeNames extends ValidationRule
|
|||||||
{
|
{
|
||||||
public function getVisitor(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
$skip = function () {
|
$skip = static function () {
|
||||||
return Visitor::skipNode();
|
return Visitor::skipNode();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ class KnownTypeNames extends ValidationRule
|
|||||||
NodeKind::INTERFACE_TYPE_DEFINITION => $skip,
|
NodeKind::INTERFACE_TYPE_DEFINITION => $skip,
|
||||||
NodeKind::UNION_TYPE_DEFINITION => $skip,
|
NodeKind::UNION_TYPE_DEFINITION => $skip,
|
||||||
NodeKind::INPUT_OBJECT_TYPE_DEFINITION => $skip,
|
NodeKind::INPUT_OBJECT_TYPE_DEFINITION => $skip,
|
||||||
NodeKind::NAMED_TYPE => function (NamedTypeNode $node) use ($context) {
|
NodeKind::NAMED_TYPE => static function (NamedTypeNode $node) use ($context) {
|
||||||
$schema = $context->getSchema();
|
$schema = $context->getSchema();
|
||||||
$typeName = $node->name->value;
|
$typeName = $node->name->value;
|
||||||
$type = $schema->getType($typeName);
|
$type = $schema->getType($typeName);
|
||||||
|
@ -26,17 +26,17 @@ class LoneAnonymousOperation extends ValidationRule
|
|||||||
$operationCount = 0;
|
$operationCount = 0;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
NodeKind::DOCUMENT => function (DocumentNode $node) use (&$operationCount) {
|
NodeKind::DOCUMENT => static function (DocumentNode $node) use (&$operationCount) {
|
||||||
$tmp = Utils::filter(
|
$tmp = Utils::filter(
|
||||||
$node->definitions,
|
$node->definitions,
|
||||||
function (Node $definition) {
|
static function (Node $definition) {
|
||||||
return $definition->kind === NodeKind::OPERATION_DEFINITION;
|
return $definition->kind === NodeKind::OPERATION_DEFINITION;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
$operationCount = count($tmp);
|
$operationCount = count($tmp);
|
||||||
},
|
},
|
||||||
NodeKind::OPERATION_DEFINITION => function (OperationDefinitionNode $node) use (
|
NodeKind::OPERATION_DEFINITION => static function (OperationDefinitionNode $node) use (
|
||||||
&$operationCount,
|
&$operationCount,
|
||||||
$context
|
$context
|
||||||
) {
|
) {
|
||||||
|
@ -43,7 +43,7 @@ class NoFragmentCycles extends ValidationRule
|
|||||||
$this->spreadPathIndexByName = [];
|
$this->spreadPathIndexByName = [];
|
||||||
|
|
||||||
return [
|
return [
|
||||||
NodeKind::OPERATION_DEFINITION => function () {
|
NodeKind::OPERATION_DEFINITION => static function () {
|
||||||
return Visitor::skipNode();
|
return Visitor::skipNode();
|
||||||
},
|
},
|
||||||
NodeKind::FRAGMENT_DEFINITION => function (FragmentDefinitionNode $node) use ($context) {
|
NodeKind::FRAGMENT_DEFINITION => function (FragmentDefinitionNode $node) use ($context) {
|
||||||
@ -98,7 +98,7 @@ class NoFragmentCycles extends ValidationRule
|
|||||||
$spreadName,
|
$spreadName,
|
||||||
Utils::map(
|
Utils::map(
|
||||||
$cyclePath,
|
$cyclePath,
|
||||||
function ($s) {
|
static function ($s) {
|
||||||
return $s->name->value;
|
return $s->name->value;
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -25,10 +25,10 @@ class NoUndefinedVariables extends ValidationRule
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
NodeKind::OPERATION_DEFINITION => [
|
NodeKind::OPERATION_DEFINITION => [
|
||||||
'enter' => function () use (&$variableNameDefined) {
|
'enter' => static function () use (&$variableNameDefined) {
|
||||||
$variableNameDefined = [];
|
$variableNameDefined = [];
|
||||||
},
|
},
|
||||||
'leave' => function (OperationDefinitionNode $operation) use (&$variableNameDefined, $context) {
|
'leave' => static function (OperationDefinitionNode $operation) use (&$variableNameDefined, $context) {
|
||||||
$usages = $context->getRecursiveVariableUsages($operation);
|
$usages = $context->getRecursiveVariableUsages($operation);
|
||||||
|
|
||||||
foreach ($usages as $usage) {
|
foreach ($usages as $usage) {
|
||||||
@ -49,7 +49,7 @@ class NoUndefinedVariables extends ValidationRule
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
NodeKind::VARIABLE_DEFINITION => function (VariableDefinitionNode $def) use (&$variableNameDefined) {
|
NodeKind::VARIABLE_DEFINITION => static function (VariableDefinitionNode $def) use (&$variableNameDefined) {
|
||||||
$variableNameDefined[$def->variable->name->value] = true;
|
$variableNameDefined[$def->variable->name->value] = true;
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -24,6 +24,7 @@ use GraphQL\Type\Definition\Type;
|
|||||||
use GraphQL\Utils\PairSet;
|
use GraphQL\Utils\PairSet;
|
||||||
use GraphQL\Utils\TypeInfo;
|
use GraphQL\Utils\TypeInfo;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
use SplObjectStorage;
|
||||||
use function array_keys;
|
use function array_keys;
|
||||||
use function array_map;
|
use function array_map;
|
||||||
use function array_merge;
|
use function array_merge;
|
||||||
@ -39,6 +40,7 @@ class OverlappingFieldsCanBeMerged extends ValidationRule
|
|||||||
* A memoization for when two fragments are compared "between" each other for
|
* A memoization for when two fragments are compared "between" each other for
|
||||||
* conflicts. Two fragments may be compared many times, so memoizing this can
|
* conflicts. Two fragments may be compared many times, so memoizing this can
|
||||||
* dramatically improve the performance of this validator.
|
* dramatically improve the performance of this validator.
|
||||||
|
*
|
||||||
* @var PairSet
|
* @var PairSet
|
||||||
*/
|
*/
|
||||||
private $comparedFragmentPairs;
|
private $comparedFragmentPairs;
|
||||||
@ -48,14 +50,14 @@ class OverlappingFieldsCanBeMerged extends ValidationRule
|
|||||||
* selection set. Selection sets may be asked for this information multiple
|
* selection set. Selection sets may be asked for this information multiple
|
||||||
* times, so this improves the performance of this validator.
|
* times, so this improves the performance of this validator.
|
||||||
*
|
*
|
||||||
* @var \SplObjectStorage
|
* @var SplObjectStorage
|
||||||
*/
|
*/
|
||||||
private $cachedFieldsAndFragmentNames;
|
private $cachedFieldsAndFragmentNames;
|
||||||
|
|
||||||
public function getVisitor(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
$this->comparedFragmentPairs = new PairSet();
|
$this->comparedFragmentPairs = new PairSet();
|
||||||
$this->cachedFieldsAndFragmentNames = new \SplObjectStorage();
|
$this->cachedFieldsAndFragmentNames = new SplObjectStorage();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
NodeKind::SELECTION_SET => function (SelectionSetNode $selectionSet) use ($context) {
|
NodeKind::SELECTION_SET => function (SelectionSetNode $selectionSet) use ($context) {
|
||||||
@ -83,6 +85,7 @@ class OverlappingFieldsCanBeMerged extends ValidationRule
|
|||||||
* GraphQL Document.
|
* GraphQL Document.
|
||||||
*
|
*
|
||||||
* @param CompositeType $parentType
|
* @param CompositeType $parentType
|
||||||
|
*
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
*/
|
*/
|
||||||
private function findConflictsWithinSelectionSet(
|
private function findConflictsWithinSelectionSet(
|
||||||
@ -145,7 +148,8 @@ class OverlappingFieldsCanBeMerged extends ValidationRule
|
|||||||
* referenced via fragment spreads.
|
* referenced via fragment spreads.
|
||||||
*
|
*
|
||||||
* @param CompositeType $parentType
|
* @param CompositeType $parentType
|
||||||
* @return mixed[]|\SplObjectStorage
|
*
|
||||||
|
* @return mixed[]|SplObjectStorage
|
||||||
*/
|
*/
|
||||||
private function getFieldsAndFragmentNames(
|
private function getFieldsAndFragmentNames(
|
||||||
ValidationContext $context,
|
ValidationContext $context,
|
||||||
@ -224,7 +228,6 @@ class OverlappingFieldsCanBeMerged extends ValidationRule
|
|||||||
*
|
*
|
||||||
* J) Also, if two fragments are referenced in both selection sets, then a
|
* J) Also, if two fragments are referenced in both selection sets, then a
|
||||||
* comparison is made "between" the two fragments.
|
* comparison is made "between" the two fragments.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -333,6 +336,7 @@ class OverlappingFieldsCanBeMerged extends ValidationRule
|
|||||||
* @param string $responseName
|
* @param string $responseName
|
||||||
* @param mixed[] $field1
|
* @param mixed[] $field1
|
||||||
* @param mixed[] $field2
|
* @param mixed[] $field2
|
||||||
|
*
|
||||||
* @return mixed[]|null
|
* @return mixed[]|null
|
||||||
*/
|
*/
|
||||||
private function findConflict(
|
private function findConflict(
|
||||||
@ -503,6 +507,7 @@ class OverlappingFieldsCanBeMerged extends ValidationRule
|
|||||||
* @param bool $areMutuallyExclusive
|
* @param bool $areMutuallyExclusive
|
||||||
* @param CompositeType $parentType1
|
* @param CompositeType $parentType1
|
||||||
* @param CompositeType $parentType2
|
* @param CompositeType $parentType2
|
||||||
|
*
|
||||||
* @return mixed[][]
|
* @return mixed[][]
|
||||||
*/
|
*/
|
||||||
private function findConflictsBetweenSubSelectionSets(
|
private function findConflictsBetweenSubSelectionSets(
|
||||||
@ -704,7 +709,7 @@ class OverlappingFieldsCanBeMerged extends ValidationRule
|
|||||||
* Given a reference to a fragment, return the represented collection of fields
|
* Given a reference to a fragment, return the represented collection of fields
|
||||||
* as well as a list of nested fragment names referenced via fragment spreads.
|
* as well as a list of nested fragment names referenced via fragment spreads.
|
||||||
*
|
*
|
||||||
* @return mixed[]|\SplObjectStorage
|
* @return mixed[]|SplObjectStorage
|
||||||
*/
|
*/
|
||||||
private function getReferencedFieldsAndFragmentNames(
|
private function getReferencedFieldsAndFragmentNames(
|
||||||
ValidationContext $context,
|
ValidationContext $context,
|
||||||
@ -818,6 +823,7 @@ class OverlappingFieldsCanBeMerged extends ValidationRule
|
|||||||
*
|
*
|
||||||
* @param mixed[][] $conflicts
|
* @param mixed[][] $conflicts
|
||||||
* @param string $responseName
|
* @param string $responseName
|
||||||
|
*
|
||||||
* @return mixed[]|null
|
* @return mixed[]|null
|
||||||
*/
|
*/
|
||||||
private function subfieldConflicts(
|
private function subfieldConflicts(
|
||||||
@ -834,7 +840,7 @@ class OverlappingFieldsCanBeMerged extends ValidationRule
|
|||||||
[
|
[
|
||||||
$responseName,
|
$responseName,
|
||||||
array_map(
|
array_map(
|
||||||
function ($conflict) {
|
static function ($conflict) {
|
||||||
return $conflict[0];
|
return $conflict[0];
|
||||||
},
|
},
|
||||||
$conflicts
|
$conflicts
|
||||||
@ -842,14 +848,14 @@ class OverlappingFieldsCanBeMerged extends ValidationRule
|
|||||||
],
|
],
|
||||||
array_reduce(
|
array_reduce(
|
||||||
$conflicts,
|
$conflicts,
|
||||||
function ($allFields, $conflict) {
|
static function ($allFields, $conflict) {
|
||||||
return array_merge($allFields, $conflict[1]);
|
return array_merge($allFields, $conflict[1]);
|
||||||
},
|
},
|
||||||
[$ast1]
|
[$ast1]
|
||||||
),
|
),
|
||||||
array_reduce(
|
array_reduce(
|
||||||
$conflicts,
|
$conflicts,
|
||||||
function ($allFields, $conflict) {
|
static function ($allFields, $conflict) {
|
||||||
return array_merge($allFields, $conflict[2]);
|
return array_merge($allFields, $conflict[2]);
|
||||||
},
|
},
|
||||||
[$ast2]
|
[$ast2]
|
||||||
@ -876,7 +882,7 @@ class OverlappingFieldsCanBeMerged extends ValidationRule
|
|||||||
{
|
{
|
||||||
if (is_array($reason)) {
|
if (is_array($reason)) {
|
||||||
$tmp = array_map(
|
$tmp = array_map(
|
||||||
function ($tmp) {
|
static function ($tmp) {
|
||||||
[$responseName, $subReason] = $tmp;
|
[$responseName, $subReason] = $tmp;
|
||||||
|
|
||||||
$reasonMessage = self::reasonMessage($subReason);
|
$reasonMessage = self::reasonMessage($subReason);
|
||||||
|
@ -19,7 +19,7 @@ class ProvidedNonNullArguments extends ValidationRule
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::FIELD => [
|
NodeKind::FIELD => [
|
||||||
'leave' => function (FieldNode $fieldNode) use ($context) {
|
'leave' => static function (FieldNode $fieldNode) use ($context) {
|
||||||
$fieldDef = $context->getFieldDef();
|
$fieldDef = $context->getFieldDef();
|
||||||
|
|
||||||
if (! $fieldDef) {
|
if (! $fieldDef) {
|
||||||
@ -45,7 +45,7 @@ class ProvidedNonNullArguments extends ValidationRule
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
NodeKind::DIRECTIVE => [
|
NodeKind::DIRECTIVE => [
|
||||||
'leave' => function (DirectiveNode $directiveNode) use ($context) {
|
'leave' => static function (DirectiveNode $directiveNode) use ($context) {
|
||||||
$directiveDef = $context->getDirective();
|
$directiveDef = $context->getDirective();
|
||||||
if (! $directiveDef) {
|
if (! $directiveDef) {
|
||||||
return Visitor::skipNode();
|
return Visitor::skipNode();
|
||||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Validator\Rules;
|
namespace GraphQL\Validator\Rules;
|
||||||
|
|
||||||
|
use ArrayObject;
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
use GraphQL\Executor\Values;
|
use GraphQL\Executor\Values;
|
||||||
use GraphQL\Language\AST\FieldNode;
|
use GraphQL\Language\AST\FieldNode;
|
||||||
@ -31,10 +32,10 @@ class QueryComplexity extends QuerySecurityRule
|
|||||||
/** @var mixed[]|null */
|
/** @var mixed[]|null */
|
||||||
private $rawVariableValues = [];
|
private $rawVariableValues = [];
|
||||||
|
|
||||||
/** @var \ArrayObject */
|
/** @var ArrayObject */
|
||||||
private $variableDefs;
|
private $variableDefs;
|
||||||
|
|
||||||
/** @var \ArrayObject */
|
/** @var ArrayObject */
|
||||||
private $fieldNodeAndDefs;
|
private $fieldNodeAndDefs;
|
||||||
|
|
||||||
/** @var ValidationContext */
|
/** @var ValidationContext */
|
||||||
@ -49,8 +50,8 @@ class QueryComplexity extends QuerySecurityRule
|
|||||||
{
|
{
|
||||||
$this->context = $context;
|
$this->context = $context;
|
||||||
|
|
||||||
$this->variableDefs = new \ArrayObject();
|
$this->variableDefs = new ArrayObject();
|
||||||
$this->fieldNodeAndDefs = new \ArrayObject();
|
$this->fieldNodeAndDefs = new ArrayObject();
|
||||||
$complexity = 0;
|
$complexity = 0;
|
||||||
|
|
||||||
return $this->invokeIfNeeded(
|
return $this->invokeIfNeeded(
|
||||||
@ -196,7 +197,7 @@ class QueryComplexity extends QuerySecurityRule
|
|||||||
throw new Error(implode(
|
throw new Error(implode(
|
||||||
"\n\n",
|
"\n\n",
|
||||||
array_map(
|
array_map(
|
||||||
function ($error) {
|
static function ($error) {
|
||||||
return $error->getMessage();
|
return $error->getMessage();
|
||||||
},
|
},
|
||||||
$variableValuesResult['errors']
|
$variableValuesResult['errors']
|
||||||
@ -251,7 +252,7 @@ class QueryComplexity extends QuerySecurityRule
|
|||||||
throw new Error(implode(
|
throw new Error(implode(
|
||||||
"\n\n",
|
"\n\n",
|
||||||
array_map(
|
array_map(
|
||||||
function ($error) {
|
static function ($error) {
|
||||||
return $error->getMessage();
|
return $error->getMessage();
|
||||||
},
|
},
|
||||||
$variableValuesResult['errors']
|
$variableValuesResult['errors']
|
||||||
|
@ -4,16 +4,18 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Validator\Rules;
|
namespace GraphQL\Validator\Rules;
|
||||||
|
|
||||||
use Closure;
|
use ArrayObject;
|
||||||
use GraphQL\Language\AST\FieldNode;
|
use GraphQL\Language\AST\FieldNode;
|
||||||
use GraphQL\Language\AST\FragmentDefinitionNode;
|
use GraphQL\Language\AST\FragmentDefinitionNode;
|
||||||
use GraphQL\Language\AST\FragmentSpreadNode;
|
use GraphQL\Language\AST\FragmentSpreadNode;
|
||||||
|
use GraphQL\Language\AST\InlineFragmentNode;
|
||||||
use GraphQL\Language\AST\NodeKind;
|
use GraphQL\Language\AST\NodeKind;
|
||||||
use GraphQL\Language\AST\SelectionSetNode;
|
use GraphQL\Language\AST\SelectionSetNode;
|
||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
use GraphQL\Type\Introspection;
|
use GraphQL\Type\Introspection;
|
||||||
use GraphQL\Utils\TypeInfo;
|
use GraphQL\Utils\TypeInfo;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
use InvalidArgumentException;
|
||||||
use function class_alias;
|
use function class_alias;
|
||||||
use function method_exists;
|
use function method_exists;
|
||||||
use function sprintf;
|
use function sprintf;
|
||||||
@ -34,7 +36,7 @@ abstract class QuerySecurityRule extends ValidationRule
|
|||||||
protected function checkIfGreaterOrEqualToZero($name, $value)
|
protected function checkIfGreaterOrEqualToZero($name, $value)
|
||||||
{
|
{
|
||||||
if ($value < 0) {
|
if ($value < 0) {
|
||||||
throw new \InvalidArgumentException(sprintf('$%s argument must be greater or equal to 0.', $name));
|
throw new InvalidArgumentException(sprintf('$%s argument must be greater or equal to 0.', $name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,8 +57,9 @@ abstract class QuerySecurityRule extends ValidationRule
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Closure[] $validators
|
* @param callable[] $validators
|
||||||
* @return Closure[]
|
*
|
||||||
|
* @return callable[]
|
||||||
*/
|
*/
|
||||||
protected function invokeIfNeeded(ValidationContext $context, array $validators)
|
protected function invokeIfNeeded(ValidationContext $context, array $validators)
|
||||||
{
|
{
|
||||||
@ -98,17 +101,17 @@ abstract class QuerySecurityRule extends ValidationRule
|
|||||||
*
|
*
|
||||||
* @param Type|null $parentType
|
* @param Type|null $parentType
|
||||||
*
|
*
|
||||||
* @return \ArrayObject
|
* @return ArrayObject
|
||||||
*/
|
*/
|
||||||
protected function collectFieldASTsAndDefs(
|
protected function collectFieldASTsAndDefs(
|
||||||
ValidationContext $context,
|
ValidationContext $context,
|
||||||
$parentType,
|
$parentType,
|
||||||
SelectionSetNode $selectionSet,
|
SelectionSetNode $selectionSet,
|
||||||
?\ArrayObject $visitedFragmentNames = null,
|
?ArrayObject $visitedFragmentNames = null,
|
||||||
?\ArrayObject $astAndDefs = null
|
?ArrayObject $astAndDefs = null
|
||||||
) {
|
) {
|
||||||
$_visitedFragmentNames = $visitedFragmentNames ?: new \ArrayObject();
|
$_visitedFragmentNames = $visitedFragmentNames ?: new ArrayObject();
|
||||||
$_astAndDefs = $astAndDefs ?: new \ArrayObject();
|
$_astAndDefs = $astAndDefs ?: new ArrayObject();
|
||||||
|
|
||||||
foreach ($selectionSet->selections as $selection) {
|
foreach ($selectionSet->selections as $selection) {
|
||||||
switch ($selection->kind) {
|
switch ($selection->kind) {
|
||||||
@ -134,7 +137,7 @@ abstract class QuerySecurityRule extends ValidationRule
|
|||||||
}
|
}
|
||||||
$responseName = $this->getFieldName($selection);
|
$responseName = $this->getFieldName($selection);
|
||||||
if (! isset($_astAndDefs[$responseName])) {
|
if (! isset($_astAndDefs[$responseName])) {
|
||||||
$_astAndDefs[$responseName] = new \ArrayObject();
|
$_astAndDefs[$responseName] = new ArrayObject();
|
||||||
}
|
}
|
||||||
// create field context
|
// create field context
|
||||||
$_astAndDefs[$responseName][] = [$selection, $fieldDef];
|
$_astAndDefs[$responseName][] = [$selection, $fieldDef];
|
||||||
|
@ -16,7 +16,7 @@ class ScalarLeafs extends ValidationRule
|
|||||||
public function getVisitor(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::FIELD => function (FieldNode $node) use ($context) {
|
NodeKind::FIELD => static function (FieldNode $node) use ($context) {
|
||||||
$type = $context->getType();
|
$type = $context->getType();
|
||||||
if (! $type) {
|
if (! $type) {
|
||||||
return;
|
return;
|
||||||
|
@ -15,7 +15,7 @@ class UniqueDirectivesPerLocation extends ValidationRule
|
|||||||
public function getVisitor(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'enter' => function (Node $node) use ($context) {
|
'enter' => static function (Node $node) use ($context) {
|
||||||
if (! isset($node->directives)) {
|
if (! isset($node->directives)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ class UniqueFragmentNames extends ValidationRule
|
|||||||
$this->knownFragmentNames = [];
|
$this->knownFragmentNames = [];
|
||||||
|
|
||||||
return [
|
return [
|
||||||
NodeKind::OPERATION_DEFINITION => function () {
|
NodeKind::OPERATION_DEFINITION => static function () {
|
||||||
return Visitor::skipNode();
|
return Visitor::skipNode();
|
||||||
},
|
},
|
||||||
NodeKind::FRAGMENT_DEFINITION => function (FragmentDefinitionNode $node) use ($context) {
|
NodeKind::FRAGMENT_DEFINITION => function (FragmentDefinitionNode $node) use ($context) {
|
||||||
|
@ -38,7 +38,7 @@ class UniqueOperationNames extends ValidationRule
|
|||||||
|
|
||||||
return Visitor::skipNode();
|
return Visitor::skipNode();
|
||||||
},
|
},
|
||||||
NodeKind::FRAGMENT_DEFINITION => function () {
|
NodeKind::FRAGMENT_DEFINITION => static function () {
|
||||||
return Visitor::skipNode();
|
return Visitor::skipNode();
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -6,7 +6,6 @@ namespace GraphQL\Validator\Rules;
|
|||||||
|
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
use function class_alias;
|
use function class_alias;
|
||||||
use function get_class;
|
|
||||||
|
|
||||||
abstract class ValidationRule
|
abstract class ValidationRule
|
||||||
{
|
{
|
||||||
@ -15,7 +14,7 @@ abstract class ValidationRule
|
|||||||
|
|
||||||
public function getName()
|
public function getName()
|
||||||
{
|
{
|
||||||
return $this->name ?: get_class($this);
|
return $this->name ?: static::class;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(ValidationContext $context)
|
public function __invoke(ValidationContext $context)
|
||||||
@ -27,6 +26,7 @@ abstract class ValidationRule
|
|||||||
* Returns structure suitable for GraphQL\Language\Visitor
|
* Returns structure suitable for GraphQL\Language\Visitor
|
||||||
*
|
*
|
||||||
* @see \GraphQL\Language\Visitor
|
* @see \GraphQL\Language\Visitor
|
||||||
|
*
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
*/
|
*/
|
||||||
abstract public function getVisitor(ValidationContext $context);
|
abstract public function getVisitor(ValidationContext $context);
|
||||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GraphQL\Validator\Rules;
|
namespace GraphQL\Validator\Rules;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
use GraphQL\Language\AST\BooleanValueNode;
|
use GraphQL\Language\AST\BooleanValueNode;
|
||||||
use GraphQL\Language\AST\EnumValueNode;
|
use GraphQL\Language\AST\EnumValueNode;
|
||||||
@ -27,6 +28,7 @@ use GraphQL\Type\Definition\ScalarType;
|
|||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
use GraphQL\Validator\ValidationContext;
|
use GraphQL\Validator\ValidationContext;
|
||||||
|
use Throwable;
|
||||||
use function array_combine;
|
use function array_combine;
|
||||||
use function array_keys;
|
use function array_keys;
|
||||||
use function array_map;
|
use function array_map;
|
||||||
@ -45,7 +47,7 @@ class ValuesOfCorrectType extends ValidationRule
|
|||||||
public function getVisitor(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::NULL => function (NullValueNode $node) use ($context) {
|
NodeKind::NULL => static function (NullValueNode $node) use ($context) {
|
||||||
$type = $context->getInputType();
|
$type = $context->getInputType();
|
||||||
if (! ($type instanceof NonNull)) {
|
if (! ($type instanceof NonNull)) {
|
||||||
return;
|
return;
|
||||||
@ -82,7 +84,7 @@ class ValuesOfCorrectType extends ValidationRule
|
|||||||
$nodeFields = iterator_to_array($node->fields);
|
$nodeFields = iterator_to_array($node->fields);
|
||||||
$fieldNodeMap = array_combine(
|
$fieldNodeMap = array_combine(
|
||||||
array_map(
|
array_map(
|
||||||
function ($field) {
|
static function ($field) {
|
||||||
return $field->name->value;
|
return $field->name->value;
|
||||||
},
|
},
|
||||||
$nodeFields
|
$nodeFields
|
||||||
@ -103,7 +105,7 @@ class ValuesOfCorrectType extends ValidationRule
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
NodeKind::OBJECT_FIELD => function (ObjectFieldNode $node) use ($context) {
|
NodeKind::OBJECT_FIELD => static function (ObjectFieldNode $node) use ($context) {
|
||||||
$parentType = Type::getNamedType($context->getParentInputType());
|
$parentType = Type::getNamedType($context->getParentInputType());
|
||||||
$fieldType = $context->getInputType();
|
$fieldType = $context->getInputType();
|
||||||
if ($fieldType || ! ($parentType instanceof InputObjectType)) {
|
if ($fieldType || ! ($parentType instanceof InputObjectType)) {
|
||||||
@ -193,7 +195,7 @@ class ValuesOfCorrectType extends ValidationRule
|
|||||||
// may throw to indicate failure.
|
// may throw to indicate failure.
|
||||||
try {
|
try {
|
||||||
$type->parseLiteral($node);
|
$type->parseLiteral($node);
|
||||||
} catch (\Exception $error) {
|
} catch (Exception $error) {
|
||||||
// Ensure a reference to the original error is maintained.
|
// Ensure a reference to the original error is maintained.
|
||||||
$context->reportError(
|
$context->reportError(
|
||||||
new Error(
|
new Error(
|
||||||
@ -209,7 +211,7 @@ class ValuesOfCorrectType extends ValidationRule
|
|||||||
$error
|
$error
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} catch (\Throwable $error) {
|
} catch (Throwable $error) {
|
||||||
// Ensure a reference to the original error is maintained.
|
// Ensure a reference to the original error is maintained.
|
||||||
$context->reportError(
|
$context->reportError(
|
||||||
new Error(
|
new Error(
|
||||||
@ -234,7 +236,7 @@ class ValuesOfCorrectType extends ValidationRule
|
|||||||
$suggestions = Utils::suggestionList(
|
$suggestions = Utils::suggestionList(
|
||||||
Printer::doPrint($node),
|
Printer::doPrint($node),
|
||||||
array_map(
|
array_map(
|
||||||
function (EnumValueDefinition $value) {
|
static function (EnumValueDefinition $value) {
|
||||||
return $value->name;
|
return $value->name;
|
||||||
},
|
},
|
||||||
$type->getValues()
|
$type->getValues()
|
||||||
|
@ -18,7 +18,7 @@ class VariablesAreInputTypes extends ValidationRule
|
|||||||
public function getVisitor(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::VARIABLE_DEFINITION => function (VariableDefinitionNode $node) use ($context) {
|
NodeKind::VARIABLE_DEFINITION => static function (VariableDefinitionNode $node) use ($context) {
|
||||||
$type = TypeInfo::typeFromAST($context->getSchema(), $node->type);
|
$type = TypeInfo::typeFromAST($context->getSchema(), $node->type);
|
||||||
|
|
||||||
// If the variable type is not an input type, return an error.
|
// If the variable type is not an input type, return an error.
|
||||||
|
@ -25,7 +25,7 @@ class VariablesDefaultValueAllowed extends ValidationRule
|
|||||||
public function getVisitor(ValidationContext $context)
|
public function getVisitor(ValidationContext $context)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
NodeKind::VARIABLE_DEFINITION => function (VariableDefinitionNode $node) use ($context) {
|
NodeKind::VARIABLE_DEFINITION => static function (VariableDefinitionNode $node) use ($context) {
|
||||||
$name = $node->variable->name->value;
|
$name = $node->variable->name->value;
|
||||||
$defaultValue = $node->defaultValue;
|
$defaultValue = $node->defaultValue;
|
||||||
$type = $context->getInputType();
|
$type = $context->getInputType();
|
||||||
@ -44,10 +44,10 @@ class VariablesDefaultValueAllowed extends ValidationRule
|
|||||||
|
|
||||||
return Visitor::skipNode();
|
return Visitor::skipNode();
|
||||||
},
|
},
|
||||||
NodeKind::SELECTION_SET => function (SelectionSetNode $node) {
|
NodeKind::SELECTION_SET => static function (SelectionSetNode $node) {
|
||||||
return Visitor::skipNode();
|
return Visitor::skipNode();
|
||||||
},
|
},
|
||||||
NodeKind::FRAGMENT_DEFINITION => function (FragmentDefinitionNode $node) {
|
NodeKind::FRAGMENT_DEFINITION => static function (FragmentDefinitionNode $node) {
|
||||||
return Visitor::skipNode();
|
return Visitor::skipNode();
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -71,7 +71,7 @@ class VariablesInAllowedPosition extends ValidationRule
|
|||||||
|
|
||||||
private function effectiveType($varType, $varDef)
|
private function effectiveType($varType, $varDef)
|
||||||
{
|
{
|
||||||
return (! $varDef->defaultValue || $varType instanceof NonNull) ? $varType : new NonNull($varType);
|
return ! $varDef->defaultValue || $varType instanceof NonNull ? $varType : new NonNull($varType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -128,10 +128,10 @@ class ValidationContext
|
|||||||
Visitor::visitWithTypeInfo(
|
Visitor::visitWithTypeInfo(
|
||||||
$typeInfo,
|
$typeInfo,
|
||||||
[
|
[
|
||||||
NodeKind::VARIABLE_DEFINITION => function () {
|
NodeKind::VARIABLE_DEFINITION => static function () {
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
NodeKind::VARIABLE => function (VariableNode $variable) use (
|
NodeKind::VARIABLE => static function (VariableNode $variable) use (
|
||||||
&$newUsages,
|
&$newUsages,
|
||||||
$typeInfo
|
$typeInfo
|
||||||
) {
|
) {
|
||||||
@ -214,6 +214,7 @@ class ValidationContext
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name
|
* @param string $name
|
||||||
|
*
|
||||||
* @return FragmentDefinitionNode|null
|
* @return FragmentDefinitionNode|null
|
||||||
*/
|
*/
|
||||||
public function getFragment($name)
|
public function getFragment($name)
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user