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; public $subscription;
/** /**
* @var Type[] * @var Type[]|callable
*/ */
public $types; public $types;
@ -88,8 +88,8 @@ class Config
if (isset($options['types'])) { if (isset($options['types'])) {
Utils::invariant( Utils::invariant(
is_array($options['types']), is_array($options['types']) || is_callable($options['types']),
'Schema types must be array if provided but got: %s', 'Schema types must be array or callable if provided but got: %s',
Utils::getVariableType($options['types']) Utils::getVariableType($options['types'])
); );
$config->setTypes($options['types']); $config->setTypes($options['types']);
@ -110,6 +110,7 @@ class Config
'Schema type loader must be callable if provided but got: %s', 'Schema type loader must be callable if provided but got: %s',
Utils::getVariableType($options['typeLoader']) Utils::getVariableType($options['typeLoader'])
); );
$config->setTypeLoader($options['typeLoader']);
} }
if (isset($options['descriptor'])) { if (isset($options['descriptor'])) {
@ -188,20 +189,11 @@ class Config
} }
/** /**
* @param Type[] $types * @param Type[]|callable $types
* @return Config * @return Config
*/ */
public function setTypes($types) 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; $this->types = $types;
return $this; return $this;
} }
@ -220,15 +212,6 @@ class Config
*/ */
public function setDirectives(array $directives) 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; $this->directives = $directives;
return $this; return $this;
} }

View File

@ -224,19 +224,43 @@ class Schema
private function collectAllTypes() private function collectAllTypes()
{ {
$initialTypes = [ $initialTypes = array_merge(
$this->config->query, [
$this->config->mutation, $this->config->query,
$this->config->subscription, $this->config->mutation,
Introspection::_schema() $this->config->subscription,
]; Introspection::_schema()
if (!empty($this->config->types)) { ],
$initialTypes = array_merge($initialTypes, $this->config->types); array_values($this->resolvedTypes)
} );
$typeMap = []; $typeMap = [];
foreach ($initialTypes as $type) { foreach ($initialTypes as $type) {
$typeMap = TypeInfo::extractTypes($type, $typeMap); $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(); return $typeMap + Type::getInternalTypes();
} }