Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow customizing PhpEnumType #1623

Merged
merged 3 commits into from
Oct 26, 2024
Merged
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ You can find and compare releases at the [GitHub release page](https://github.co

## Unreleased

## v15.17.0

### Added

- Allow customizing PhpEnumType https://github.com/webonyx/graphql-php/pull/1623

## v15.16.1

### Fixed
Expand Down
6 changes: 3 additions & 3 deletions src/Type/Definition/EnumType.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
* description?: string|null,
* values: EnumValues|callable(): EnumValues,
* astNode?: EnumTypeDefinitionNode|null,
* extensionASTNodes?: array<int, EnumTypeExtensionNode>|null
* extensionASTNodes?: array<EnumTypeExtensionNode>|null
* }
*/
class EnumType extends Type implements InputType, OutputType, LeafType, NullableType, NamedType
Expand All @@ -39,7 +39,7 @@ class EnumType extends Type implements InputType, OutputType, LeafType, Nullable

public ?EnumTypeDefinitionNode $astNode;

/** @var array<int, EnumTypeExtensionNode> */
/** @var array<EnumTypeExtensionNode> */
public array $extensionASTNodes;

/** @phpstan-var EnumTypeConfig */
Expand Down Expand Up @@ -264,7 +264,7 @@ public function astNode(): ?EnumTypeDefinitionNode
return $this->astNode;
}

/** @return array<int, EnumTypeExtensionNode> */
/** @return array<EnumTypeExtensionNode> */
public function extensionASTNodes(): array
{
return $this->extensionASTNodes;
Expand Down
6 changes: 3 additions & 3 deletions src/Type/Definition/InputObjectType.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* fields: iterable<FieldConfig>|callable(): iterable<FieldConfig>,
* parseValue?: callable(array<string, mixed>): mixed,
* astNode?: InputObjectTypeDefinitionNode|null,
* extensionASTNodes?: array<int, InputObjectTypeExtensionNode>|null
* extensionASTNodes?: array<InputObjectTypeExtensionNode>|null
* }
*/
class InputObjectType extends Type implements InputType, NullableType, NamedType
Expand All @@ -29,7 +29,7 @@ class InputObjectType extends Type implements InputType, NullableType, NamedType

public ?InputObjectTypeDefinitionNode $astNode;

/** @var array<int, InputObjectTypeExtensionNode> */
/** @var array<InputObjectTypeExtensionNode> */
public array $extensionASTNodes;

/** @phpstan-var InputObjectConfig */
Expand Down Expand Up @@ -203,7 +203,7 @@ public function astNode(): ?InputObjectTypeDefinitionNode
return $this->astNode;
}

/** @return array<int, InputObjectTypeExtensionNode> */
/** @return array<InputObjectTypeExtensionNode> */
public function extensionASTNodes(): array
{
return $this->extensionASTNodes;
Expand Down
6 changes: 3 additions & 3 deletions src/Type/Definition/InterfaceType.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* interfaces?: iterable<InterfaceTypeReference>|callable(): iterable<InterfaceTypeReference>,
* resolveType?: ResolveType|null,
* astNode?: InterfaceTypeDefinitionNode|null,
* extensionASTNodes?: array<int, InterfaceTypeExtensionNode>|null
* extensionASTNodes?: array<InterfaceTypeExtensionNode>|null
* }
*/
class InterfaceType extends Type implements AbstractType, OutputType, CompositeType, NullableType, HasFieldsType, NamedType, ImplementingType
Expand All @@ -31,7 +31,7 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT

public ?InterfaceTypeDefinitionNode $astNode;

/** @var array<int, InterfaceTypeExtensionNode> */
/** @var array<InterfaceTypeExtensionNode> */
public array $extensionASTNodes;

/** @phpstan-var InterfaceConfig */
Expand Down Expand Up @@ -99,7 +99,7 @@ public function astNode(): ?InterfaceTypeDefinitionNode
return $this->astNode;
}

/** @return array<int, InterfaceTypeExtensionNode> */
/** @return array<InterfaceTypeExtensionNode> */
public function extensionASTNodes(): array
{
return $this->extensionASTNodes;
Expand Down
4 changes: 2 additions & 2 deletions src/Type/Definition/NamedType.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* @property string $name
* @property string|null $description
* @property (Node&TypeDefinitionNode)|null $astNode
* @property array<int, Node&TypeExtensionNode> $extensionASTNodes
* @property array<Node&TypeExtensionNode> $extensionASTNodes
*/
interface NamedType
{
Expand All @@ -36,6 +36,6 @@ public function description(): ?string;
/** @return (Node&TypeDefinitionNode)|null */
public function astNode(): ?Node;

/** @return array<int, Node&TypeExtensionNode> */
/** @return array<Node&TypeExtensionNode> */
public function extensionASTNodes(): array;
}
6 changes: 3 additions & 3 deletions src/Type/Definition/ObjectType.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
* interfaces?: iterable<InterfaceTypeReference>|callable(): iterable<InterfaceTypeReference>,
* isTypeOf?: (callable(mixed $objectValue, mixed $context, ResolveInfo $resolveInfo): (bool|Deferred|null))|null,
* astNode?: ObjectTypeDefinitionNode|null,
* extensionASTNodes?: array<int, ObjectTypeExtensionNode>|null
* extensionASTNodes?: array<ObjectTypeExtensionNode>|null
* }
*/
class ObjectType extends Type implements OutputType, CompositeType, NullableType, HasFieldsType, NamedType, ImplementingType
Expand All @@ -73,7 +73,7 @@ class ObjectType extends Type implements OutputType, CompositeType, NullableType

public ?ObjectTypeDefinitionNode $astNode;

/** @var array<int, ObjectTypeExtensionNode> */
/** @var array<ObjectTypeExtensionNode> */
public array $extensionASTNodes;

/**
Expand Down Expand Up @@ -172,7 +172,7 @@ public function astNode(): ?ObjectTypeDefinitionNode
return $this->astNode;
}

/** @return array<int, ObjectTypeExtensionNode> */
/** @return array<ObjectTypeExtensionNode> */
public function extensionASTNodes(): array
{
return $this->extensionASTNodes;
Expand Down
25 changes: 18 additions & 7 deletions src/Type/Definition/PhpEnumType.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace GraphQL\Type\Definition;

use GraphQL\Error\SerializationError;
use GraphQL\Language\AST\EnumTypeDefinitionNode;
use GraphQL\Language\AST\EnumTypeExtensionNode;
use GraphQL\Utils\PhpDoc;
use GraphQL\Utils\Utils;

Expand All @@ -16,16 +18,23 @@ class PhpEnumType extends EnumType
protected string $enumClass;

/**
* @param class-string<\UnitEnum> $enum
* @param class-string<\UnitEnum> $enumClass The fully qualified class name of a native PHP enum
* @param string|null $name The name the enum will have in the schema, defaults to the basename of the given class
* @param string|null $description The description the enum will have in the schema, defaults to PHPDoc of the given class
* @param array<EnumTypeExtensionNode>|null $extensionASTNodes
*
* @throws \Exception
* @throws \ReflectionException
*/
public function __construct(string $enum, ?string $name = null)
{
$this->enumClass = $enum;
$reflection = new \ReflectionEnum($enum);
public function __construct(
string $enumClass,
?string $name = null,
?string $description = null,
?EnumTypeDefinitionNode $astNode = null,
?array $extensionASTNodes = null
) {
$this->enumClass = $enumClass;
$reflection = new \ReflectionEnum($enumClass);

/**
* @var array<string, PartialEnumValueConfig> $enumDefinitions
Expand All @@ -40,9 +49,11 @@ public function __construct(string $enum, ?string $name = null)
}

parent::__construct([
'name' => $name ?? $this->baseName($enum),
'name' => $name ?? $this->baseName($enumClass),
'values' => $enumDefinitions,
'description' => $this->extractDescription($reflection),
'description' => $description ?? $this->extractDescription($reflection),
'astNode' => $astNode,
'extensionASTNodes' => $extensionASTNodes,
]);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Type/Definition/ScalarType.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public function astNode(): ?ScalarTypeDefinitionNode
return $this->astNode;
}

/** @return array<int, ScalarTypeExtensionNode> */
/** @return array<ScalarTypeExtensionNode> */
public function extensionASTNodes(): array
{
return $this->extensionASTNodes;
Expand Down
2 changes: 1 addition & 1 deletion src/Type/Definition/UnionType.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public function astNode(): ?UnionTypeDefinitionNode
return $this->astNode;
}

/** @return array<int, UnionTypeExtensionNode> */
/** @return array<UnionTypeExtensionNode> */
public function extensionASTNodes(): array
{
return $this->extensionASTNodes;
Expand Down
2 changes: 1 addition & 1 deletion src/Type/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class Schema

public ?SchemaDefinitionNode $astNode;

/** @var array<int, SchemaExtensionNode> */
/** @var array<SchemaExtensionNode> */
public array $extensionASTNodes = [];

/**
Expand Down
36 changes: 17 additions & 19 deletions src/Type/SchemaValidationContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -386,36 +386,38 @@ private function validateFields(Type $type): void
/**
* @param Schema|ObjectType|InterfaceType|UnionType|EnumType|InputObjectType|Directive $obj
*
* @return array<int, SchemaDefinitionNode|SchemaExtensionNode>|array<int, ObjectTypeDefinitionNode|ObjectTypeExtensionNode>|array<int, InterfaceTypeDefinitionNode|InterfaceTypeExtensionNode>|array<int, UnionTypeDefinitionNode|UnionTypeExtensionNode>|array<int, EnumTypeDefinitionNode|EnumTypeExtensionNode>|array<int, InputObjectTypeDefinitionNode|InputObjectTypeExtensionNode>|array<int, DirectiveDefinitionNode>
* @return list<SchemaDefinitionNode|SchemaExtensionNode>|list<ObjectTypeDefinitionNode|ObjectTypeExtensionNode>|list<InterfaceTypeDefinitionNode|InterfaceTypeExtensionNode>|list<UnionTypeDefinitionNode|UnionTypeExtensionNode>|list< EnumTypeDefinitionNode|EnumTypeExtensionNode>|list<InputObjectTypeDefinitionNode|InputObjectTypeExtensionNode>|list<DirectiveDefinitionNode>
*/
private function getAllNodes(object $obj): array
{
$astNode = $obj->astNode;

if ($obj instanceof Schema) {
$astNode = $obj->astNode;
$extensionNodes = $obj->extensionASTNodes;
} elseif ($obj instanceof Directive) {
$astNode = $obj->astNode;
$extensionNodes = [];
} else {
$astNode = $obj->astNode;
$extensionNodes = $obj->extensionASTNodes;
}

return $astNode !== null
? \array_merge([$astNode], $extensionNodes)
: $extensionNodes;
$allNodes = $astNode === null
? []
: [$astNode];
foreach ($extensionNodes as $extensionNode) {
$allNodes[] = $extensionNode;
}

return $allNodes;
}

/**
* @param ObjectType|InterfaceType $type
*
* @return array<int, FieldDefinitionNode>
* @return list<FieldDefinitionNode>
*/
private function getAllFieldNodes(Type $type, string $fieldName): array
{
$allNodes = $type->astNode !== null
? \array_merge([$type->astNode], $type->extensionASTNodes)
: $type->extensionASTNodes;
$allNodes = array_filter([$type->astNode, ...$type->extensionASTNodes]);

$matchingFieldNodes = [];

Expand Down Expand Up @@ -574,13 +576,11 @@ private function getImplementsInterfaceNode(ImplementingType $type, NamedType $s
* @param ObjectType|InterfaceType $type
* @param Type&NamedType $shouldBeInterface
*
* @return array<int, NamedTypeNode>
* @return list<NamedTypeNode>
*/
private function getAllImplementsInterfaceNodes(ImplementingType $type, NamedType $shouldBeInterface): array
{
$allNodes = $type->astNode !== null
? \array_merge([$type->astNode], $type->extensionASTNodes)
: $type->extensionASTNodes;
$allNodes = array_filter([$type->astNode, ...$type->extensionASTNodes]);

$shouldBeInterfaceName = $shouldBeInterface->name;
$matchingInterfaceNodes = [];
Expand Down Expand Up @@ -735,12 +735,10 @@ private function validateUnionMembers(UnionType $union): void
}
}

/** @return array<int, NamedTypeNode> */
/** @return list<NamedTypeNode> */
private function getUnionMemberTypeNodes(UnionType $union, string $typeName): array
{
$allNodes = $union->astNode !== null
? \array_merge([$union->astNode], $union->extensionASTNodes)
: $union->extensionASTNodes;
$allNodes = array_filter([$union->astNode, ...$union->extensionASTNodes]);

$types = [];
foreach ($allNodes as $node) {
Expand Down
14 changes: 7 additions & 7 deletions src/Utils/ASTDefinitionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ private function makeSchemaDef(Node $def): Type
private function makeTypeDef(ObjectTypeDefinitionNode $def): ObjectType
{
$name = $def->name->value;
/** @var array<int, ObjectTypeExtensionNode> $extensionASTNodes (proven by schema validation) */
/** @var array<ObjectTypeExtensionNode> $extensionASTNodes (proven by schema validation) */
$extensionASTNodes = $this->typeExtensionsMap[$name] ?? [];
$allNodes = [$def, ...$extensionASTNodes];

Expand Down Expand Up @@ -453,7 +453,7 @@ private function makeImplementedInterfaces(array $nodes): array
private function makeInterfaceDef(InterfaceTypeDefinitionNode $def): InterfaceType
{
$name = $def->name->value;
/** @var array<int, InterfaceTypeExtensionNode> $extensionASTNodes (proven by schema validation) */
/** @var array<InterfaceTypeExtensionNode> $extensionASTNodes (proven by schema validation) */
$extensionASTNodes = $this->typeExtensionsMap[$name] ?? [];
$allNodes = [$def, ...$extensionASTNodes];

Expand All @@ -475,7 +475,7 @@ private function makeInterfaceDef(InterfaceTypeDefinitionNode $def): InterfaceTy
private function makeEnumDef(EnumTypeDefinitionNode $def): EnumType
{
$name = $def->name->value;
/** @var array<int, EnumTypeExtensionNode> $extensionASTNodes (proven by schema validation) */
/** @var array<EnumTypeExtensionNode> $extensionASTNodes (proven by schema validation) */
$extensionASTNodes = $this->typeExtensionsMap[$name] ?? [];

$values = [];
Expand All @@ -502,7 +502,7 @@ private function makeEnumDef(EnumTypeDefinitionNode $def): EnumType
private function makeUnionDef(UnionTypeDefinitionNode $def): UnionType
{
$name = $def->name->value;
/** @var array<int, UnionTypeExtensionNode> $extensionASTNodes (proven by schema validation) */
/** @var array<UnionTypeExtensionNode> $extensionASTNodes (proven by schema validation) */
$extensionASTNodes = $this->typeExtensionsMap[$name] ?? [];

return new UnionType([
Expand Down Expand Up @@ -531,23 +531,23 @@ private function makeUnionDef(UnionTypeDefinitionNode $def): UnionType
private function makeScalarDef(ScalarTypeDefinitionNode $def): CustomScalarType
{
$name = $def->name->value;
/** @var array<int, ScalarTypeExtensionNode> $extensionASTNodes (proven by schema validation) */
/** @var array<ScalarTypeExtensionNode> $extensionASTNodes (proven by schema validation) */
$extensionASTNodes = $this->typeExtensionsMap[$name] ?? [];

return new CustomScalarType([
'name' => $name,
'description' => $def->description->value ?? null,
'serialize' => static fn ($value) => $value,
'astNode' => $def,
'extensionASTNodes' => $extensionASTNodes,
'serialize' => static fn ($value) => $value,
]);
}

/** @throws InvariantViolation */
private function makeInputObjectDef(InputObjectTypeDefinitionNode $def): InputObjectType
{
$name = $def->name->value;
/** @var array<int, InputObjectTypeExtensionNode> $extensionASTNodes (proven by schema validation) */
/** @var array<InputObjectTypeExtensionNode> $extensionASTNodes (proven by schema validation) */
$extensionASTNodes = $this->typeExtensionsMap[$name] ?? [];

return new InputObjectType([
Expand Down
Loading
Loading