66use GraphQL \Language \DirectiveLocation ;
77use GraphQL \Language \Printer ;
88use GraphQL \Type \Definition \Argument ;
9+ use GraphQL \Type \Definition \BooleanType ;
910use GraphQL \Type \Definition \Directive ;
1011use GraphQL \Type \Definition \EnumType ;
1112use GraphQL \Type \Definition \EnumValueDefinition ;
1213use GraphQL \Type \Definition \FieldDefinition ;
14+ use GraphQL \Type \Definition \FloatType ;
15+ use GraphQL \Type \Definition \IDType ;
1316use GraphQL \Type \Definition \InputObjectField ;
1417use GraphQL \Type \Definition \InputObjectType ;
1518use GraphQL \Type \Definition \InterfaceType ;
19+ use GraphQL \Type \Definition \IntType ;
1620use GraphQL \Type \Definition \ListOfType ;
1721use GraphQL \Type \Definition \NamedType ;
1822use GraphQL \Type \Definition \NonNull ;
1923use GraphQL \Type \Definition \ObjectType ;
2024use GraphQL \Type \Definition \ResolveInfo ;
2125use GraphQL \Type \Definition \ScalarType ;
26+ use GraphQL \Type \Definition \StringType ;
2227use GraphQL \Type \Definition \Type ;
2328use GraphQL \Type \Definition \UnionType ;
2429use GraphQL \Type \Definition \WrappingType ;
2530use GraphQL \Utils \AST ;
2631use GraphQL \Utils \Utils ;
2732
28- class BuiltInTypes
33+ class BuiltInDefinitions
2934{
35+ protected const SCALAR_TYPE_NAMES = [
36+ Type::INT ,
37+ Type::FLOAT ,
38+ Type::STRING ,
39+ Type::BOOLEAN ,
40+ Type::ID ,
41+ ];
42+
43+ public const INTROSPECTION_TYPE_NAMES = [
44+ Introspection::SCHEMA_OBJECT_NAME ,
45+ Introspection::TYPE_OBJECT_NAME ,
46+ Introspection::DIRECTIVE_OBJECT_NAME ,
47+ Introspection::FIELD_OBJECT_NAME ,
48+ Introspection::INPUT_VALUE_OBJECT_NAME ,
49+ Introspection::ENUM_VALUE_OBJECT_NAME ,
50+ Introspection::TYPE_KIND_ENUM_NAME ,
51+ Introspection::DIRECTIVE_LOCATION_ENUM_NAME ,
52+ ];
53+
54+ public const BUILT_IN_TYPE_NAMES = [
55+ ...self ::SCALAR_TYPE_NAMES ,
56+ ...self ::INTROSPECTION_TYPE_NAMES ,
57+ ];
58+
59+ public const BUILT_IN_DIRECTIVE_NAMES = [
60+ Directive::INCLUDE_NAME ,
61+ Directive::SKIP_NAME ,
62+ Directive::DEPRECATED_NAME ,
63+ Directive::ONE_OF_NAME ,
64+ ];
65+
66+ /** Singleton containing standard built-in definitions. */
3067 private static ?self $ standard = null ;
3168
3269 /** @var array<string, ScalarType> */
33- private array $ scalars = [];
70+ private array $ scalarTypes = [];
3471
3572 private ?ObjectType $ schemaTypeInstance = null ;
3673
@@ -55,54 +92,97 @@ class BuiltInTypes
5592 private array $ directives = [];
5693
5794 /** @var array<string, Type&NamedType>|null */
58- private ?array $ allTypesCache = null ;
95+ private ?array $ typesCache = null ;
5996
6097 /** @var array<string, ScalarType> */
61- private array $ standardTypeOverrides ;
98+ private array $ scalarTypeOverrides ;
6299
63- /** @param array<string, ScalarType> $standardTypeOverrides */
64- public function __construct (array $ standardTypeOverrides = [])
100+ /** @param array<string, ScalarType> $scalarTypeOverrides */
101+ public function __construct (array $ scalarTypeOverrides = [])
65102 {
66- $ this ->standardTypeOverrides = $ standardTypeOverrides ;
103+ $ this ->scalarTypeOverrides = $ scalarTypeOverrides ;
67104 }
68105
69106 public static function standard (): self
70107 {
71108 return self ::$ standard ??= new self ();
72109 }
73110
74- public static function resetStandard (): void
111+ /** @param array<ScalarType> $types */
112+ public static function overrideScalarTypes (array $ types ): void
75113 {
76- self ::$ standard = null ;
114+ // Preserve non-overridden scalar instances from the current standard.
115+ $ scalarOverrides = self ::$ standard !== null
116+ ? self ::$ standard ->scalarTypes ()
117+ : [];
118+
119+ foreach ($ types as $ type ) {
120+ // @phpstan-ignore-next-line generic type is not enforced by PHP
121+ if (! $ type instanceof ScalarType) {
122+ $ typeClass = ScalarType::class;
123+ $ notType = Utils::printSafe ($ type );
124+ throw new InvariantViolation ("Expecting instance of {$ typeClass }, got {$ notType }" );
125+ }
126+
127+ if (! in_array ($ type ->name , self ::SCALAR_TYPE_NAMES , true )) {
128+ $ builtInScalarNames = implode (', ' , self ::SCALAR_TYPE_NAMES );
129+ $ notBuiltInName = Utils::printSafe ($ type ->name );
130+ throw new InvariantViolation ("Expecting one of the following names for a built-in scalar type: {$ builtInScalarNames }; got {$ notBuiltInName }" ); // @phpstan-ignore missingType.checkedException (validation is part of the public contract)
131+ }
132+
133+ $ scalarOverrides [$ type ->name ] = $ type ;
134+ }
135+
136+ self ::$ standard = new self ($ scalarOverrides );
137+ }
138+
139+ public static function isIntrospectionType (NamedType $ type ): bool
140+ {
141+ return in_array ($ type ->name , self ::INTROSPECTION_TYPE_NAMES , true );
142+ }
143+
144+ public static function isBuiltInDirective (Directive $ directive ): bool
145+ {
146+ return in_array ($ directive ->name , self ::BUILT_IN_DIRECTIVE_NAMES , true );
77147 }
78148
79149 public function int (): ScalarType
80150 {
81- return $ this ->scalars [Type::INT ] ??= $ this ->standardTypeOverrides [Type::INT ] ?? Type::int ();
151+ return $ this ->scalarTypes [Type::INT ]
152+ ??= $ this ->scalarTypeOverrides [Type::INT ]
153+ ?? new IntType (); // @phpstan-ignore missingType.checkedException (static configuration is known to be correct)
82154 }
83155
84156 public function float (): ScalarType
85157 {
86- return $ this ->scalars [Type::FLOAT ] ??= $ this ->standardTypeOverrides [Type::FLOAT ] ?? Type::float ();
158+ return $ this ->scalarTypes [Type::FLOAT ]
159+ ??= $ this ->scalarTypeOverrides [Type::FLOAT ]
160+ ?? new FloatType (); // @phpstan-ignore missingType.checkedException (static configuration is known to be correct)
87161 }
88162
89163 public function string (): ScalarType
90164 {
91- return $ this ->scalars [Type::STRING ] ??= $ this ->standardTypeOverrides [Type::STRING ] ?? Type::string ();
165+ return $ this ->scalarTypes [Type::STRING ]
166+ ??= $ this ->scalarTypeOverrides [Type::STRING ]
167+ ?? new StringType (); // @phpstan-ignore missingType.checkedException (static configuration is known to be correct)
92168 }
93169
94170 public function boolean (): ScalarType
95171 {
96- return $ this ->scalars [Type::BOOLEAN ] ??= $ this ->standardTypeOverrides [Type::BOOLEAN ] ?? Type::boolean ();
172+ return $ this ->scalarTypes [Type::BOOLEAN ]
173+ ??= $ this ->scalarTypeOverrides [Type::BOOLEAN ]
174+ ?? new BooleanType (); // @phpstan-ignore missingType.checkedException (static configuration is known to be correct)
97175 }
98176
99177 public function id (): ScalarType
100178 {
101- return $ this ->scalars [Type::ID ] ??= $ this ->standardTypeOverrides [Type::ID ] ?? Type::id ();
179+ return $ this ->scalarTypes [Type::ID ]
180+ ??= $ this ->scalarTypeOverrides [Type::ID ]
181+ ?? new IDType (); // @phpstan-ignore missingType.checkedException (static configuration is known to be correct)
102182 }
103183
104184 /** @return array<string, ScalarType> */
105- public function standardTypes (): array
185+ public function scalarTypes (): array
106186 {
107187 return [
108188 Type::INT => $ this ->int (),
@@ -113,6 +193,16 @@ public function standardTypes(): array
113193 ];
114194 }
115195
196+ public static function isBuiltInTypeName (string $ name ): bool
197+ {
198+ return in_array ($ name , BuiltInDefinitions::BUILT_IN_TYPE_NAMES , true );
199+ }
200+
201+ public static function isBuiltInType (NamedType $ type ): bool
202+ {
203+ return in_array ($ type ->name , BuiltInDefinitions::BUILT_IN_TYPE_NAMES , true );
204+ }
205+
116206 public function schemaType (): ObjectType
117207 {
118208 return $ this ->schemaTypeInstance ??= new ObjectType ([ // @phpstan-ignore missingType.checkedException (static configuration is known to be correct)
@@ -773,11 +863,11 @@ public function directives(): array
773863 }
774864
775865 /** @return array<string, Type&NamedType> */
776- public function allTypes (): array
866+ public function types (): array
777867 {
778- return $ this ->allTypesCache ??= array_merge (
868+ return $ this ->typesCache ??= array_merge (
779869 $ this ->introspectionTypes (),
780- $ this ->standardTypes ()
870+ $ this ->scalarTypes ()
781871 );
782872 }
783873}
0 commit comments