Allow types schema option to be callable

This commit is contained in:
Vladimir Razuvaev 2017-07-28 17:53:57 +07:00
parent 6a20483b87
commit 3a8301f6c6
2 changed files with 38 additions and 31 deletions

View File

@ -31,7 +31,7 @@ class Config
public $subscription;
/**
* @var Type[]
* @var Type[]|callable
*/
public $types;
@ -88,8 +88,8 @@ class Config
if (isset($options['types'])) {
Utils::invariant(
is_array($options['types']),
'Schema types must be array if provided but got: %s',
is_array($options['types']) || is_callable($options['types']),
'Schema types must be array or callable if provided but got: %s',
Utils::getVariableType($options['types'])
);
$config->setTypes($options['types']);
@ -110,6 +110,7 @@ class Config
'Schema type loader must be callable if provided but got: %s',
Utils::getVariableType($options['typeLoader'])
);
$config->setTypeLoader($options['typeLoader']);
}
if (isset($options['descriptor'])) {
@ -188,20 +189,11 @@ class Config
}
/**
* @param Type[] $types
* @param Type[]|callable $types
* @return Config
*/
public function setTypes($types)
{
foreach ($types as $index => $type) {
Utils::invariant(
$type instanceof Type,
'Schema types must be GraphQL\Type\Definition\Type[], but entry at index "%s" is "%s"',
$index,
Utils::getVariableType($type)
);
}
$this->types = $types;
return $this;
}
@ -220,15 +212,6 @@ class Config
*/
public function setDirectives(array $directives)
{
foreach ($directives as $index => $directive) {
Utils::invariant(
$directive instanceof Directive,
'Schema directives must be GraphQL\Type\Definition\Directive[] if provided but but entry at index "%s" is "%s"',
$index,
Utils::getVariableType($directive)
);
}
$this->directives = $directives;
return $this;
}

View File

@ -224,19 +224,43 @@ class Schema
private function collectAllTypes()
{
$initialTypes = [
$this->config->query,
$this->config->mutation,
$this->config->subscription,
Introspection::_schema()
];
if (!empty($this->config->types)) {
$initialTypes = array_merge($initialTypes, $this->config->types);
}
$initialTypes = array_merge(
[
$this->config->query,
$this->config->mutation,
$this->config->subscription,
Introspection::_schema()
],
array_values($this->resolvedTypes)
);
$typeMap = [];
foreach ($initialTypes as $type) {
$typeMap = TypeInfo::extractTypes($type, $typeMap);
}
$types = $this->config->types;
if (is_callable($types)) {
$types = $types();
Utils::invariant(
is_array($types) || $types instanceof \Traversable,
'Schema types callable must return array or instance of Traversable but got: %s',
Utils::getVariableType($types)
);
}
if (!empty($types)) {
foreach ($types as $type) {
Utils::invariant(
$type instanceof Type,
'Each entry of schema types must be instance of GraphQL\Type\Definition\Type but got: %s',
Utils::getVariableType($types)
);
$typeMap = TypeInfo::extractTypes($type, $typeMap);
}
}
return $typeMap + Type::getInternalTypes();
}