TASK: Allow Schema extensions

This commit is contained in:
Torsten Blindert 2018-10-01 19:46:36 +02:00
parent 0c33cfa88f
commit b1cd086177
7 changed files with 94 additions and 0 deletions

View File

@ -69,6 +69,9 @@ class NodeKind
const DIRECTIVE_DEFINITION = 'DirectiveDefinition';
// Type System Extensions
const SCHEMA_EXTENSION = 'SchemaExtension';
/** @var string[] */
public static $classMap = [
self::NAME => NameNode::class,

View File

@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace GraphQL\Language\AST;
class SchemaTypeExtensionNode extends Node implements TypeExtensionNode
{
/** @var string */
public $kind = NodeKind::SCHEMA_EXTENSION;
/** @var DirectiveNode[]|null */
public $directives;
/** @var OperationTypeDefinitionNode[]|null */
public $operationTypes;
}

View File

@ -44,6 +44,7 @@ use GraphQL\Language\AST\OperationTypeDefinitionNode;
use GraphQL\Language\AST\ScalarTypeDefinitionNode;
use GraphQL\Language\AST\ScalarTypeExtensionNode;
use GraphQL\Language\AST\SchemaDefinitionNode;
use GraphQL\Language\AST\SchemaTypeExtensionNode;
use GraphQL\Language\AST\SelectionSetNode;
use GraphQL\Language\AST\StringValueNode;
use GraphQL\Language\AST\TypeExtensionNode;
@ -1446,6 +1447,8 @@ class Parser
if ($keywordToken->kind === Token::NAME) {
switch ($keywordToken->value) {
case 'schema':
return $this->parseSchemaTypeExtension();
case 'scalar':
return $this->parseScalarTypeExtension();
case 'type':
@ -1464,6 +1467,33 @@ class Parser
throw $this->unexpected($keywordToken);
}
/**
* @return SchemaTypeExtensionNode
* @throws SyntaxError
*/
private function parseSchemaTypeExtension()
{
$start = $this->lexer->token;
$this->expectKeyword('extend');
$this->expectKeyword('schema');
$directives = $this->parseDirectives(true);
$operationTypes = $this->peek(Token::BRACE_L)
? $this->many(
Token::BRACE_L,
[$this, 'parseOperationTypeDefinition'],
Token::BRACE_R
) : [];
if (count($directives) === 0 && count($operationTypes) === 0) {
$this->unexpected();
}
return new SchemaTypeExtensionNode([
'directives' => $directives,
'operationTypes' => $operationTypes,
'loc' => $this->loc($start)
]);
}
/**
* @return ScalarTypeExtensionNode
* @throws SyntaxError

View File

@ -41,6 +41,7 @@ use GraphQL\Language\AST\OperationTypeDefinitionNode;
use GraphQL\Language\AST\ScalarTypeDefinitionNode;
use GraphQL\Language\AST\ScalarTypeExtensionNode;
use GraphQL\Language\AST\SchemaDefinitionNode;
use GraphQL\Language\AST\SchemaTypeExtensionNode;
use GraphQL\Language\AST\SelectionSetNode;
use GraphQL\Language\AST\StringValueNode;
use GraphQL\Language\AST\UnionTypeDefinitionNode;
@ -335,6 +336,17 @@ class Printer
);
}),
NodeKind::SCHEMA_EXTENSION => function (SchemaTypeExtensionNode $def) {
return $this->join(
[
'extend schema',
$this->join($def->directives, ' '),
$this->block($def->operationTypes)
],
' '
);
},
NodeKind::SCALAR_TYPE_EXTENSION => function (ScalarTypeExtensionNode $def) {
return $this->join(
[

View File

@ -165,6 +165,8 @@ class Visitor
NodeKind::INPUT_OBJECT_TYPE_EXTENSION => ['name', 'directives', 'fields'],
NodeKind::DIRECTIVE_DEFINITION => ['description', 'name', 'arguments', 'locations'],
NodeKind::SCHEMA_EXTENSION => ['directives', 'operationTypes']
];
/**

View File

@ -8,6 +8,7 @@ use GraphQL\Error\Error;
use GraphQL\Error\InvariantViolation;
use GraphQL\GraphQL;
use GraphQL\Language\AST\SchemaDefinitionNode;
use GraphQL\Language\AST\SchemaTypeExtensionNode;
use GraphQL\Type\Definition\AbstractType;
use GraphQL\Type\Definition\Directive;
use GraphQL\Type\Definition\InterfaceType;
@ -67,6 +68,9 @@ class Schema
/** @var InvariantViolation[]|null */
private $validationErrors;
/** @var SchemaTypeExtensionNode[] */
public $extensionASTNodes;
/**
* @api
* @param mixed[]|SchemaConfig $config
@ -111,6 +115,8 @@ class Schema
}
$this->config = $config;
$this->extensionASTNodes = $config->extensionASTNodes;
if ($config->query) {
$this->resolvedTypes[$config->query->name] = $config->query;
}

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace GraphQL\Type;
use GraphQL\Language\AST\SchemaDefinitionNode;
use GraphQL\Language\AST\SchemaTypeExtensionNode;
use GraphQL\Type\Definition\Directive;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
@ -51,6 +52,9 @@ class SchemaConfig
/** @var bool */
public $assumeValid;
/** @var SchemaTypeExtensionNode[] */
public $extensionASTNodes;
/**
* Converts an array of options to instance of SchemaConfig
* (or just returns empty config when array is not passed).
@ -100,6 +104,10 @@ class SchemaConfig
if (isset($options['assumeValid'])) {
$config->setAssumeValid((bool) $options['assumeValid']);
}
if (isset($options['extensionASTNodes'])) {
$config->setExtensionASTNodes($options['extensionASTNodes']);
}
}
return $config;
@ -266,4 +274,20 @@ class SchemaConfig
return $this;
}
/**
* @return SchemaTypeExtensionNode[]
*/
public function getExtensionASTNodes(): array
{
return $this->extensionASTNodes;
}
/**
* @param SchemaTypeExtensionNode[] $extensionASTNodes
*/
public function setExtensionASTNodes(array $extensionASTNodes): void
{
$this->extensionASTNodes = $extensionASTNodes;
}
}