Skip to content

Commit

Permalink
Allow customizing PhpEnumType
Browse files Browse the repository at this point in the history
  • Loading branch information
spawnia authored Oct 26, 2024
1 parent 088f24d commit c1c9e5b
Show file tree
Hide file tree
Showing 14 changed files with 112 additions and 67 deletions.
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

0 comments on commit c1c9e5b

Please sign in to comment.