Skip to content

Commit 01f6898

Browse files
authored
Resolved built-in scalar type resolution in BaseTypeMapper::mapNameToType (#784)
webonyx/graphql-php v15.31.0 changed Schema::getType() to call the typeLoader callback before checking built-in scalars. Since the RootTypeMapper chain throws TypeNotFoundException for unrecognized type names, built-in scalars like ID, String, Int, Float, and Boolean were never reached, causing "Unknown type" errors when used in outputType annotations (e.g. #[Field(outputType: 'ID')]).
1 parent 5e7a714 commit 01f6898

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

src/Mappers/Root/BaseTypeMapper.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,9 @@ public function toGraphQLInputType(Type $type, InputType|null $subType, string $
107107
*
108108
* @throws CannotMapTypeException
109109
*/
110-
private function mapBaseType(Type $type): BooleanType|FloatType|IDType|IntType|StringType|UploadType|DateTimeType|ScalarType|null
110+
private function mapBaseType(
111+
Type $type,
112+
): BooleanType|FloatType|IDType|IntType|StringType|UploadType|DateTimeType|ScalarType|null
111113
{
112114
if ($type instanceof Integer) {
113115
return GraphQLType::int();
@@ -180,11 +182,15 @@ private static function getDateTimeType(): DateTimeType
180182
*/
181183
public function mapNameToType(string $typeName): NamedType&GraphQLType
182184
{
183-
// No need to map base types, only types added by us.
184185
return match ($typeName) {
185-
'Upload'=>self::getUploadType(),
186-
'DateTime'=>self::getDateTimeType(),
187-
default=>$this->next->mapNameToType($typeName)
186+
'ID' => GraphQLType::id(),
187+
'String' => GraphQLType::string(),
188+
'Int' => GraphQLType::int(),
189+
'Float' => GraphQLType::float(),
190+
'Boolean' => GraphQLType::boolean(),
191+
'Upload' => self::getUploadType(),
192+
'DateTime' => self::getDateTimeType(),
193+
default => $this->next->mapNameToType($typeName),
188194
};
189195
}
190196
}

tests/Mappers/Root/BaseTypeMapperTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
namespace TheCodingMachine\GraphQLite\Mappers\Root;
44

55
use GraphQL\Type\Definition\BooleanType;
6+
use GraphQL\Type\Definition\IDType;
67
use GraphQL\Type\Definition\IntType;
78
use GraphQL\Type\Definition\ListOfType;
89
use GraphQL\Type\Definition\NonNull;
10+
use GraphQL\Type\Definition\StringType;
911
use GraphQL\Type\Definition\WrappingType;
1012
use phpDocumentor\Reflection\DocBlock;
1113
use phpDocumentor\Reflection\Fqsen;
@@ -81,6 +83,34 @@ public function testOutputGenericIterables(string $phpdocType, string $expectedI
8183
}
8284
}
8385

86+
/**
87+
* Built-in scalars (ID, String, Int, Float, Boolean) must be resolved by
88+
* mapNameToType so that webonyx/graphql-php's Schema::getType() — which
89+
* calls the typeLoader before checking builtInScalars — doesn't throw.
90+
*/
91+
#[DataProvider('builtInScalarNamesProvider')]
92+
public function testMapNameToTypeResolvesBuiltInScalars(string $scalarName, string $expectedType): void
93+
{
94+
$baseTypeMapper = new BaseTypeMapper(
95+
new FinalRootTypeMapper($this->getTypeMapper()),
96+
$this->getTypeMapper(),
97+
$this->getRootTypeMapper(),
98+
);
99+
100+
$result = $baseTypeMapper->mapNameToType($scalarName);
101+
102+
$this->assertInstanceOf($expectedType, $result);
103+
}
104+
105+
public static function builtInScalarNamesProvider(): iterable
106+
{
107+
yield 'ID' => ['ID', IDType::class];
108+
yield 'String' => ['String', StringType::class];
109+
yield 'Int' => ['Int', IntType::class];
110+
yield 'Float' => ['Float', \GraphQL\Type\Definition\FloatType::class];
111+
yield 'Boolean' => ['Boolean', BooleanType::class];
112+
}
113+
84114
public static function genericIterablesProvider(): iterable
85115
{
86116
yield '\ArrayIterator with nullable int item' => ['\ArrayIterator<int|null>', IntType::class];

0 commit comments

Comments
 (0)