Add predicates to for built-in types

ref: graphql/graphql-js#924
This commit is contained in:
Daniel Tschinder 2018-02-09 18:03:31 +01:00
parent c4f11a577e
commit 1da3801614
5 changed files with 69 additions and 57 deletions

View File

@ -74,6 +74,15 @@ class Directive
return $internal['deprecated']; return $internal['deprecated'];
} }
/**
* @param Directive $directive
* @return bool
*/
public static function isSpecifiedDirective(Directive $directive)
{
return in_array($directive->name, array_keys(self::getInternalDirectives()));
}
/** /**
* @return array * @return array
*/ */

View File

@ -2,7 +2,9 @@
namespace GraphQL\Type\Definition; namespace GraphQL\Type\Definition;
use GraphQL\Error\InvariantViolation; use GraphQL\Error\InvariantViolation;
use GraphQL\Language\AST\NamedType;
use GraphQL\Language\AST\TypeDefinitionNode; use GraphQL\Language\AST\TypeDefinitionNode;
use GraphQL\Type\Introspection;
/** /**
* Registry of standard GraphQL types * Registry of standard GraphQL types
@ -23,6 +25,11 @@ abstract class Type implements \JsonSerializable
*/ */
private static $internalTypes; private static $internalTypes;
/**
* @var array
*/
private static $builtInTypes;
/** /**
* @api * @api
* @return IDType * @return IDType
@ -107,6 +114,8 @@ abstract class Type implements \JsonSerializable
} }
/** /**
* Returns all builtin scalar types
*
* @return Type[] * @return Type[]
*/ */
public static function getInternalTypes() public static function getInternalTypes()
@ -114,6 +123,34 @@ abstract class Type implements \JsonSerializable
return self::getInternalType(); return self::getInternalType();
} }
/**
* Returns all builtin in types including base scalar and
* introspection types
*
* @return Type[]
*/
public static function getAllBuiltInTypes()
{
if (null === self::$builtInTypes) {
self::$builtInTypes = array_merge(
Introspection::getTypes(),
self::getInternalTypes()
);
}
return self::$builtInTypes;
}
/**
* Checks if the type is a builtin type
*
* @param Type $type
* @return bool
*/
public static function isBuiltInType(Type $type)
{
return in_array($type->name, array_keys(self::getAllBuiltInTypes()));
}
/** /**
* @api * @api
* @param Type $type * @param Type $type

View File

@ -240,6 +240,15 @@ EOD;
]; ];
} }
/**
* @param Type $type
* @return bool
*/
public static function isIntrospectionType(Type $type)
{
return in_array($type->name, array_keys(self::getTypes()));
}
public static function _schema() public static function _schema()
{ {
if (!isset(self::$map['__Schema'])) { if (!isset(self::$map['__Schema'])) {

View File

@ -61,21 +61,7 @@ class ASTDefinitionBuilder
$this->options = $options; $this->options = $options;
$this->resolveType = $resolveType; $this->resolveType = $resolveType;
$this->cache = [ $this->cache = Type::getAllBuiltInTypes();
'String' => Type::string(),
'Int' => Type::int(),
'Float' => Type::float(),
'Boolean' => Type::boolean(),
'ID' => Type::id(),
'__Schema' => Introspection::_schema(),
'__Directive' => Introspection::_directive(),
'__DirectiveLocation' => Introspection::_directiveLocation(),
'__Type' => Introspection::_type(),
'__Field' => Introspection::_field(),
'__InputValue' => Introspection::_inputValue(),
'__EnumValue' => Introspection::_enumValue(),
'__TypeKind' => Introspection::_typeKind(),
];
} }
/** /**

View File

@ -2,8 +2,8 @@
namespace GraphQL\Utils; namespace GraphQL\Utils;
use GraphQL\Language\Printer; use GraphQL\Language\Printer;
use GraphQL\Type\Introspection;
use GraphQL\Type\Schema; use GraphQL\Type\Schema;
use GraphQL\Type\Definition\CompositeType;
use GraphQL\Type\Definition\EnumType; use GraphQL\Type\Definition\EnumType;
use GraphQL\Type\Definition\InputObjectType; use GraphQL\Type\Definition\InputObjectType;
use GraphQL\Type\Definition\InterfaceType; use GraphQL\Type\Definition\InterfaceType;
@ -31,10 +31,12 @@ class SchemaPrinter
{ {
return self::printFilteredSchema( return self::printFilteredSchema(
$schema, $schema,
function($n) { function($type) {
return !self::isSpecDirective($n); return !Directive::isSpecifiedDirective($type);
},
function ($type) {
return !Type::isBuiltInType($type);
}, },
'self::isDefinedType',
$options $options
); );
} }
@ -48,51 +50,20 @@ class SchemaPrinter
{ {
return self::printFilteredSchema( return self::printFilteredSchema(
$schema, $schema,
[__CLASS__, 'isSpecDirective'], [Directive::class, 'isSpecifiedDirective'],
[__CLASS__, 'isIntrospectionType'], [Introspection::class, 'isIntrospectionType'],
$options $options
); );
} }
private static function isSpecDirective($directiveName)
{
return (
$directiveName === 'skip' ||
$directiveName === 'include' ||
$directiveName === 'deprecated'
);
}
private static function isDefinedType($typename)
{
return !self::isIntrospectionType($typename) && !self::isBuiltInScalar($typename);
}
private static function isIntrospectionType($typename)
{
return strpos($typename, '__') === 0;
}
private static function isBuiltInScalar($typename)
{
return (
$typename === Type::STRING ||
$typename === Type::BOOLEAN ||
$typename === Type::INT ||
$typename === Type::FLOAT ||
$typename === Type::ID
);
}
private static function printFilteredSchema(Schema $schema, $directiveFilter, $typeFilter, $options) private static function printFilteredSchema(Schema $schema, $directiveFilter, $typeFilter, $options)
{ {
$directives = array_filter($schema->getDirectives(), function($directive) use ($directiveFilter) { $directives = array_filter($schema->getDirectives(), function($directive) use ($directiveFilter) {
return $directiveFilter($directive->name); return $directiveFilter($directive);
}); });
$typeMap = $schema->getTypeMap(); $types = $schema->getTypeMap();
$types = array_filter(array_keys($typeMap), $typeFilter); ksort($types);
sort($types); $types = array_filter($types, $typeFilter);
$types = array_map(function($typeName) use ($typeMap) { return $typeMap[$typeName]; }, $types);
return implode("\n\n", array_filter(array_merge( return implode("\n\n", array_filter(array_merge(
[self::printSchemaDefinition($schema)], [self::printSchemaDefinition($schema)],