Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/continuous_integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ jobs:
name: "codeCoverage"
path: "build"

- uses: codecov/[email protected].1 # upload the coverage to codecov
- uses: codecov/[email protected].2 # upload the coverage to codecov
with:
fail_ci_if_error: true # optional (default = false)
# Do not upload in forks, and only on php8, latest deps
Expand Down
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ parameters:
level: 8
checkGenericClassInNonGenericObjectType: false
reportUnmatchedIgnoredErrors: false
treatPhpDocTypesAsCertain: false
ignoreErrors:
- "#PHPDoc tag \\@throws with type Psr\\\\Container\\\\ContainerExceptionInterface is not subtype of Throwable#"
- "#Parameter .* of class ReflectionMethod constructor expects string(\\|null)?, object\\|string given.#"
Expand Down
9 changes: 7 additions & 2 deletions src/Exceptions/GraphQLException.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@
class GraphQLException extends Exception implements GraphQLExceptionInterface
{
/** @param array<string, mixed> $extensions */
public function __construct(string $message, int $code = 0, Throwable|null $previous = null, private string $category = 'Exception', private array $extensions = [])
{
public function __construct(
string $message,
int $code = 0,
Throwable|null $previous = null,
protected string $category = 'Exception',
protected array $extensions = [],
) {
parent::__construct($message, $code, $previous);
}

Expand Down
10 changes: 6 additions & 4 deletions src/GlobControllerQueryProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
*/
final class GlobControllerQueryProvider implements QueryProviderInterface
{
/** @var array<string,string>|null */
/** @var array<int,string>|null */
private array|null $instancesList = null;
private ClassNameMapper $classNameMapper;
private AggregateControllerQueryProvider|null $aggregateControllerQueryProvider = null;
Expand Down Expand Up @@ -73,9 +73,11 @@ private function getAggregateControllerQueryProvider(): AggregateControllerQuery
private function getInstancesList(): array
{
if ($this->instancesList === null) {
$this->instancesList = $this->cacheContract->get('globQueryProvider', function () {
return $this->buildInstancesList();
});
$this->instancesList = $this->cacheContract->get(
'globQueryProvider',
fn () => $this->buildInstancesList(),
);

if (! is_array($this->instancesList)) {
throw new InvalidArgumentException('The instance list returned is not an array. There might be an issue with your PSR-16 cache implementation.');
}
Expand Down
31 changes: 24 additions & 7 deletions src/Mappers/Root/MyCLabsEnumTypeMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,36 @@ class MyCLabsEnumTypeMapper implements RootTypeMapperInterface
/** @var array<string, EnumType> */
private array $cacheByName = [];

/** @var array<string, class-string<Enum>> */
private array|null $nameToClassMapping = null;

/** @param NS[] $namespaces List of namespaces containing enums. Used when searching an enum by name. */
public function __construct(private readonly RootTypeMapperInterface $next, private readonly AnnotationReader $annotationReader, private readonly CacheInterface $cacheService, private readonly array $namespaces)
{
public function __construct(
private readonly RootTypeMapperInterface $next,
private readonly AnnotationReader $annotationReader,
private readonly CacheInterface $cacheService,
private readonly array $namespaces,
) {
}

public function toGraphQLOutputType(Type $type, OutputType|null $subType, ReflectionMethod|ReflectionProperty $reflector, DocBlock $docBlockObj): OutputType&\GraphQL\Type\Definition\Type
public function toGraphQLOutputType(
Type $type,
OutputType|null $subType,
ReflectionMethod|ReflectionProperty $reflector,
DocBlock $docBlockObj,
): OutputType&\GraphQL\Type\Definition\Type
{
$result = $this->map($type);
return $result ?? $this->next->toGraphQLOutputType($type, $subType, $reflector, $docBlockObj);
}

public function toGraphQLInputType(Type $type, InputType|null $subType, string $argumentName, ReflectionMethod|ReflectionProperty $reflector, DocBlock $docBlockObj): InputType&\GraphQL\Type\Definition\Type
public function toGraphQLInputType(
Type $type,
InputType|null $subType,
string $argumentName,
ReflectionMethod|ReflectionProperty $reflector,
DocBlock $docBlockObj,
): InputType&\GraphQL\Type\Definition\Type
{
$result = $this->map($type);
return $result ?? $this->next->toGraphQLInputType($type, $subType, $argumentName, $reflector, $docBlockObj);
Expand Down Expand Up @@ -83,6 +101,7 @@ private function mapByClassName(string $enumClass): EnumType|null
return $this->cacheByName[$type->name] = $this->cache[$enumClass] = $type;
}


private function getTypeName(ReflectionClass $refClass): string
{
$enumType = $this->annotationReader->getEnumTypeAnnotation($refClass);
Expand Down Expand Up @@ -131,9 +150,6 @@ public function mapNameToType(string $typeName): NamedType&\GraphQL\Type\Definit
return $this->next->mapNameToType($typeName);
}

/** @var array<string, class-string<Enum>> */
private array|null $nameToClassMapping = null;

/**
* Go through all classes in the defined namespaces and loads the cache.
*
Expand All @@ -150,6 +166,7 @@ private function getNameToClassMapping(): array
continue;
}

/** @var class-string<Enum> $className */
$nameToClassMapping[$this->getTypeName($classRef)] = $className;
}
}
Expand Down
13 changes: 10 additions & 3 deletions src/Utils/Namespaces/NS.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,27 @@ final class NS
private array|null $classes = null;

/** @param string $namespace The namespace that contains the GraphQL types (they must have a `@Type` annotation) */
public function __construct(private readonly string $namespace, private readonly CacheInterface $cache, private readonly ClassNameMapper $classNameMapper, private readonly int|null $globTTL, private readonly bool $recursive)
{
public function __construct(
private readonly string $namespace,
private readonly CacheInterface $cache,
private readonly ClassNameMapper $classNameMapper,
private readonly int|null $globTTL,
private readonly bool $recursive,
) {
}

/**
* Returns the array of globbed classes.
* Only instantiable classes are returned.
*
* @return array<string,ReflectionClass<object>> Key: fully qualified class name
* @return array<class-string,ReflectionClass<object>> Key: fully qualified class name
*/
public function getClassList(): array
{
if ($this->classes === null) {
$this->classes = [];
$explorer = new GlobClassExplorer($this->namespace, $this->cache, $this->globTTL, $this->classNameMapper, $this->recursive);
/** @var array<class-string, string> $classes Override class-explorer lib */
$classes = $explorer->getClassMap();
foreach ($classes as $className => $phpFile) {
if (! class_exists($className, false) && ! interface_exists($className, false)) {
Expand All @@ -66,6 +72,7 @@ public function getClassList(): array
}
}

// @phpstan-ignore-next-line - Not sure why we cannot annotate the $classes above
return $this->classes;
}

Expand Down