Skip to content
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
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ New features:
- Unauthorized access to fields can now generate GraphQL errors (rather that schema errors in GraphQLite v3)
- Added fine-grained security using the `@Security` annotation. A field can now be [marked accessible or not depending on the context](fine-grained-security.md).
For instance, you can restrict access to the field "viewsCount" of the type `BlogPost` only for post that the current user wrote.
- You can now inject the current logged user in any query / mutation / field using the `@InjectUser` annotation
- Performance:
- You can inject the [Webonyx query plan in a parameter from a resolver](query_plan.md)
- You can use the [dataloader pattern to improve performance drastically via the "prefetchMethod" attribute](prefetch_method.md)
Expand Down
2 changes: 1 addition & 1 deletion src/Mappers/CannotMapTypeException.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public static function mustBeOutputType(string $subTypeName): self

public static function mustBeInputType(string $subTypeName): self
{
return new self('type "' . $subTypeName . '" must be an input type.');
return new self('type "' . $subTypeName . '" must be an input type (if you declared an input type with the name "' . $subTypeName . '", make sure that there are no output type with the same name as this is forbidden by the GraphQL spec).');
}

/**
Expand Down
18 changes: 9 additions & 9 deletions src/TypeRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
class TypeRegistry
{
/** @var array<string,NamedType&Type&(MutableObjectType|InterfaceType|UnionType|(InputObjectType&ResolvableMutableInputInterface))> */
private $outputTypes = [];
private $types = [];

/**
* Registers a type.
Expand All @@ -33,10 +33,10 @@ class TypeRegistry
*/
public function registerType(NamedType $type): void
{
if (isset($this->outputTypes[$type->name])) {
if (isset($this->types[$type->name])) {
throw new GraphQLRuntimeException('Type "' . $type->name . '" is already registered');
}
$this->outputTypes[$type->name] = $type;
$this->types[$type->name] = $type;
}

/**
Expand All @@ -50,29 +50,29 @@ public function registerType(NamedType $type): void
*/
public function getOrRegisterType(NamedType $type): NamedType
{
if (isset($this->outputTypes[$type->name])) {
return $this->outputTypes[$type->name];
if (isset($this->types[$type->name])) {
return $this->types[$type->name];
}
$this->outputTypes[$type->name] = $type;
$this->types[$type->name] = $type;

return $type;
}

public function hasType(string $typeName): bool
{
return isset($this->outputTypes[$typeName]);
return isset($this->types[$typeName]);
}

/**
* @return NamedType&Type&(ObjectType|InterfaceType|UnionType|(InputObjectType&ResolvableMutableInputInterface))
*/
public function getType(string $typeName): NamedType
{
if (! isset($this->outputTypes[$typeName])) {
if (! isset($this->types[$typeName])) {
throw new GraphQLRuntimeException('Could not find type "' . $typeName . '" in registry');
}

return $this->outputTypes[$typeName];
return $this->types[$typeName];
}

public function getMutableObjectType(string $typeName): MutableObjectType
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php


namespace TheCodingMachine\GraphQLite\Fixtures\InputOutputNameConflict\Controllers;


use TheCodingMachine\GraphQLite\Annotations\Query;
use TheCodingMachine\GraphQLite\Annotations\UseInputType;
use TheCodingMachine\GraphQLite\Fixtures\InputOutputNameConflict\Types\InAndOut;

class InAndOutController
{
/**
* @Query()
* @UseInputType(for="$inAndOut", inputType="InAndOut")
*/
public function testInAndOut(InAndOut $inAndOut): InAndOut
{
return $inAndOut;
}
}
40 changes: 40 additions & 0 deletions tests/Fixtures/InputOutputNameConflict/Types/InAndOut.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php


namespace TheCodingMachine\GraphQLite\Fixtures\InputOutputNameConflict\Types;

use TheCodingMachine\GraphQLite\Annotations\Factory;
use TheCodingMachine\GraphQLite\Annotations\Field;
use TheCodingMachine\GraphQLite\Annotations\Type;

/**
* @Type(name="InAndOut")
*/
class InAndOut
{
/**
* @var string
*/
private $value;

public function __construct(string $value)
{
$this->value = $value;
}

/**
* @Field()
*/
public function getValue(): string
{
return $this->value;
}

/**
* @Factory(name="InAndOut")
*/
public static function create(string $value): self
{
return new self($value);
}
}
4 changes: 2 additions & 2 deletions tests/Fixtures/Integration/Types/ContactFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ContactFactory
{
/**
* @Factory()
* @UseInputType(for="$relations", inputType="[ContactRefInput!]!")
* @UseInputType(for="$relations", inputType="[ContactRef!]!")
* @param string $name
* @param Contact|null $manager
* @param Contact[] $relations
Expand All @@ -34,7 +34,7 @@ public function createContact(string $name, DateTimeInterface $birthDate, ?Uploa
}

/**
* @Factory(name="ContactRefInput", default=false)
* @Factory(name="ContactRef", default=false)
* @return Contact
*/
public function getContact(string $name): Contact
Expand Down
18 changes: 17 additions & 1 deletion tests/Integration/EndToEndTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use TheCodingMachine\GraphQLite\GraphQLRuntimeException;
use TheCodingMachine\GraphQLite\InputTypeGenerator;
use TheCodingMachine\GraphQLite\InputTypeUtils;
use TheCodingMachine\GraphQLite\Mappers\CannotMapTypeException;
use TheCodingMachine\GraphQLite\Mappers\CompositeTypeMapper;
use TheCodingMachine\GraphQLite\Mappers\GlobTypeMapper;
use TheCodingMachine\GraphQLite\Mappers\Parameters\ContainerParameterHandler;
Expand Down Expand Up @@ -52,6 +53,7 @@
use TheCodingMachine\GraphQLite\Containers\EmptyContainer;
use TheCodingMachine\GraphQLite\Reflection\CachedDocBlockFactory;
use TheCodingMachine\GraphQLite\Schema;
use TheCodingMachine\GraphQLite\SchemaFactory;
use TheCodingMachine\GraphQLite\Security\AuthenticationServiceInterface;
use TheCodingMachine\GraphQLite\Security\AuthorizationServiceInterface;
use TheCodingMachine\GraphQLite\Security\SecurityExpressionLanguageProvider;
Expand Down Expand Up @@ -451,7 +453,7 @@ public function testEndToEndInputType()
{
name: "bar"
}
]
]
}
) {
name,
Expand Down Expand Up @@ -1364,4 +1366,18 @@ public function getUser(): ?object

$this->assertSame(42, $result->toArray(Debug::RETHROW_UNSAFE_EXCEPTIONS)['data']['injectedUser']);
}

public function testInputOutputNameConflict(): void
{
$schemaFactory = new SchemaFactory(new Psr16Cache(new ArrayAdapter()), new BasicAutoWiringContainer(new EmptyContainer()));
$schemaFactory->addControllerNamespace('TheCodingMachine\\GraphQLite\\Fixtures\\InputOutputNameConflict\\Controllers');
$schemaFactory->addTypeNamespace('TheCodingMachine\\GraphQLite\\Fixtures\\InputOutputNameConflict\\Types');

$schema = $schemaFactory->createSchema();

$this->expectException(CannotMapTypeException::class);
$this->expectExceptionMessage('For parameter $inAndOut, in TheCodingMachine\\GraphQLite\\Fixtures\\InputOutputNameConflict\\Controllers\\InAndOutController::testInAndOut, type "InAndOut" must be an input type (if you declared an input type with the name "InAndOut", make sure that there are no output type with the same name as this is forbidden by the GraphQL spec).');

$schema->validate();
}
}