Skip to content

Commit b25728c

Browse files
authored
Accept any array as inputs and serialize it as a list (#71)
1 parent 736a87c commit b25728c

17 files changed

Lines changed: 258 additions & 24 deletions

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
## v0.24.0
11+
12+
### Added
13+
14+
- Accept any array as inputs and serialize it as a list
15+
1016
## v0.23.1
1117

1218
### Fixed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Spawnia\Sailor\Input\Operations;
6+
7+
/**
8+
* @extends \Spawnia\Sailor\Operation<\Spawnia\Sailor\Input\Operations\TakeList\TakeListResult>
9+
*/
10+
class TakeList extends \Spawnia\Sailor\Operation
11+
{
12+
/**
13+
* @param array<int|null>|null $values
14+
*/
15+
public static function execute($values = 'Special default value that allows Sailor to differentiate between explicitly passing null and not passing a value at all.'): TakeList\TakeListResult
16+
{
17+
return self::executeOperation(
18+
$values,
19+
);
20+
}
21+
22+
protected static function converters(): array
23+
{
24+
static $converters;
25+
26+
return $converters ??= [
27+
['values', new \Spawnia\Sailor\Convert\NullConverter(new \Spawnia\Sailor\Convert\ListConverter(new \Spawnia\Sailor\Convert\NullConverter(new \Spawnia\Sailor\Convert\IntConverter)))],
28+
];
29+
}
30+
31+
public static function document(): string
32+
{
33+
return /* @lang GraphQL */ 'mutation TakeList($values: [Int]) {
34+
__typename
35+
takeList(values: $values)
36+
}';
37+
}
38+
39+
public static function endpoint(): string
40+
{
41+
return 'input';
42+
}
43+
44+
public static function config(): string
45+
{
46+
return \Safe\realpath(__DIR__ . '/../../sailor.php');
47+
}
48+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Spawnia\Sailor\Input\Operations\TakeList;
6+
7+
/**
8+
* @property string $__typename
9+
* @property array<int, int|null>|null $takeList
10+
*/
11+
class TakeList extends \Spawnia\Sailor\ObjectLike
12+
{
13+
/**
14+
* @param array<int, int|null>|null $takeList
15+
*/
16+
public static function make($takeList = 'Special default value that allows Sailor to differentiate between explicitly passing null and not passing a value at all.'): self
17+
{
18+
$instance = new self;
19+
20+
$instance->__typename = 'Mutation';
21+
if ($takeList !== self::UNDEFINED) {
22+
$instance->takeList = $takeList;
23+
}
24+
25+
return $instance;
26+
}
27+
28+
protected function converters(): array
29+
{
30+
static $converters;
31+
32+
return $converters ??= [
33+
'__typename' => new \Spawnia\Sailor\Convert\NonNullConverter(new \Spawnia\Sailor\Convert\StringConverter),
34+
'takeList' => new \Spawnia\Sailor\Convert\NullConverter(new \Spawnia\Sailor\Convert\ListConverter(new \Spawnia\Sailor\Convert\NullConverter(new \Spawnia\Sailor\Convert\IntConverter))),
35+
];
36+
}
37+
38+
public static function endpoint(): string
39+
{
40+
return 'input';
41+
}
42+
43+
public static function config(): string
44+
{
45+
return \Safe\realpath(__DIR__ . '/../../../sailor.php');
46+
}
47+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Spawnia\Sailor\Input\Operations\TakeList;
6+
7+
class TakeListErrorFreeResult extends \Spawnia\Sailor\ErrorFreeResult
8+
{
9+
public TakeList $data;
10+
11+
public static function endpoint(): string
12+
{
13+
return 'input';
14+
}
15+
16+
public static function config(): string
17+
{
18+
return \Safe\realpath(__DIR__ . '/../../../sailor.php');
19+
}
20+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Spawnia\Sailor\Input\Operations\TakeList;
6+
7+
class TakeListResult extends \Spawnia\Sailor\Result
8+
{
9+
public ?TakeList $data = null;
10+
11+
protected function setData(\stdClass $data): void
12+
{
13+
$this->data = TakeList::fromStdClass($data);
14+
}
15+
16+
/**
17+
* Useful for instantiation of successful mocked results.
18+
*
19+
* @return static
20+
*/
21+
public static function fromData(TakeList $data): self
22+
{
23+
$instance = new static;
24+
$instance->data = $data;
25+
26+
return $instance;
27+
}
28+
29+
public function errorFree(): TakeListErrorFreeResult
30+
{
31+
return TakeListErrorFreeResult::fromResult($this);
32+
}
33+
34+
public static function endpoint(): string
35+
{
36+
return 'input';
37+
}
38+
39+
public static function config(): string
40+
{
41+
return \Safe\realpath(__DIR__ . '/../../../sailor.php');
42+
}
43+
}

examples/input/expected/Types/SomeInput.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66

77
/**
88
* @property string $required
9-
* @property array<int, array<int, int|null>> $matrix
9+
* @property array<array<int|null>> $matrix
1010
* @property string|null $optional
1111
* @property \Spawnia\Sailor\Input\Types\SomeInput|null $nested
1212
*/
1313
class SomeInput extends \Spawnia\Sailor\ObjectLike
1414
{
1515
/**
1616
* @param string $required
17-
* @param array<int, array<int, int|null>> $matrix
17+
* @param array<array<int|null>> $matrix
1818
* @param string|null $optional
1919
* @param \Spawnia\Sailor\Input\Types\SomeInput|null $nested
2020
*/

examples/input/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
type Mutation {
2+
takeList(values: [Int]): [Int]
23
takeSomeInput(input: SomeInput): Int
34
}
45

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
mutation TakeList($values: [Int]) {
2+
takeList(values: $values)
3+
}

src/Codegen/ObjectLikeBuilder.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111
use Spawnia\Sailor\ObjectLike;
1212

1313
/**
14-
* @phpstan-type PropertyArgs array{string, Type, string, string, string, mixed}
14+
* @phpstan-type PropertyArgs array{string, Type, string, string, mixed}
1515
*/
1616
class ObjectLikeBuilder
1717
{
18+
private bool $isInputType;
19+
1820
private ClassType $class;
1921

2022
private Method $make;
@@ -31,7 +33,7 @@ class ObjectLikeBuilder
3133
*/
3234
private array $optionalProperties = [];
3335

34-
public function __construct(string $name, string $namespace)
36+
public function __construct(string $name, string $namespace, bool $isInputType)
3537
{
3638
$class = new ClassType(
3739
$name,
@@ -59,12 +61,13 @@ public function __construct(string $name, string $namespace)
5961
$this->converters = $converters;
6062

6163
$this->class = $class;
64+
$this->isInputType = $isInputType;
6265
}
6366

6467
/**
6568
* @param mixed $defaultValue any value
6669
*/
67-
public function addProperty(string $name, Type $type, string $phpDocType, string $phpType, string $typeConverter, $defaultValue): void
70+
public function addProperty(string $name, Type $type, string $phpDocType, string $typeConverter, $defaultValue): void
6871
{
6972
// Fields may be referenced multiple times in a query through fragments, but they
7073
// are only included once in the result sent from the server, thus we eliminate duplicates here.
@@ -74,7 +77,7 @@ public function addProperty(string $name, Type $type, string $phpDocType, string
7477
}
7578
}
7679

77-
$args = [$name, $type, $phpDocType, $phpType, $typeConverter, $defaultValue];
80+
$args = [$name, $type, $phpDocType, $typeConverter, $defaultValue];
7881

7982
if ($type instanceof NonNull && null === $defaultValue) {
8083
$this->requiredProperties[] = $args;
@@ -102,9 +105,9 @@ public function build(): ClassType
102105
/**
103106
* @param mixed $defaultValue any value
104107
*/
105-
protected function buildProperty(string $name, Type $type, string $phpDocType, string $phpType, string $typeConverter, $defaultValue): void
108+
protected function buildProperty(string $name, Type $type, string $phpDocType, string $typeConverter, $defaultValue): void
106109
{
107-
$wrappedPhpDocType = TypeWrapper::phpDoc($type, $phpDocType);
110+
$wrappedPhpDocType = TypeWrapper::phpDoc($type, $phpDocType, $this->isInputType);
108111

109112
$this->class->addComment("@property {$wrappedPhpDocType} \${$name}");
110113

0 commit comments

Comments
 (0)