Skip to content

Commit 2109fc6

Browse files
authored
Merge pull request #130 from raky2702/rakovicky/schema_transformer
Schema transformer
2 parents f670762 + 6057bef commit 2109fc6

File tree

3 files changed

+184
-21
lines changed

3 files changed

+184
-21
lines changed

src/Handlers/OpenApiHandler.php

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Tomaj\NetteApi\Authorization\NoAuthorization;
1919
use Tomaj\NetteApi\Authorization\QueryApiKeyAuthentication;
2020
use Tomaj\NetteApi\Link\ApiLink;
21+
use Tomaj\NetteApi\Misc\OpenApiTransform;
2122
use Tomaj\NetteApi\Output\JsonOutput;
2223
use Tomaj\NetteApi\Output\RedirectOutput;
2324
use Tomaj\NetteApi\Params\GetInputParam;
@@ -585,7 +586,7 @@ private function createIn($type)
585586

586587
private function transformSchema(array $schema)
587588
{
588-
$this->transformTypes($schema);
589+
OpenApiTransform::transformTypes($schema);
589590

590591
if (isset($schema['definitions'])) {
591592
foreach ($schema['definitions'] as $name => $definition) {
@@ -596,26 +597,6 @@ private function transformSchema(array $schema)
596597
return json_decode(str_replace('#/definitions/', '#/components/schemas/', json_encode($schema, JSON_UNESCAPED_SLASHES)), true);
597598
}
598599

599-
private function transformTypes(array &$schema, ?string $parent = null)
600-
{
601-
foreach ($schema as $key => &$value) {
602-
if ($parent === 'properties') {
603-
continue;
604-
}
605-
if ($key === 'type' && is_array($value)) {
606-
if (count($value) === 2 && in_array('null', $value)) {
607-
unset($value[array_search('null', $value)]);
608-
$value = implode(',', $value);
609-
$schema['nullable'] = true;
610-
} else {
611-
throw new InvalidArgumentException('Type cannot be array and if so, one element have to be "null"');
612-
}
613-
} elseif (is_array($value)) {
614-
$this->transformTypes($value, $key);
615-
}
616-
}
617-
}
618-
619600
private function addDefinition($name, $definition)
620601
{
621602
if (isset($this->definitions[$name])) {

src/Misc/OpenApiTransform.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tomaj\NetteApi\Misc;
6+
7+
class OpenApiTransform
8+
{
9+
/**
10+
* @param string|int|null $parent
11+
*/
12+
public static function transformTypes(array &$schema, $parent = null): void
13+
{
14+
foreach ($schema as $key => &$value) {
15+
if ($key === 'type' && is_array($value) && $parent !== 'properties') {
16+
if (count($value) > 1 && in_array('null', $value, true)) {
17+
unset($value[array_search('null', $value)]);
18+
$schema['nullable'] = true;
19+
}
20+
if (count($value) === 1) {
21+
$value = implode(',', $value);
22+
} elseif (count($value) > 1) {
23+
foreach ($schema['type'] as $type) {
24+
$schema['oneOf'][] = ['type' => $type];
25+
}
26+
unset($schema['type']);
27+
}
28+
} elseif (is_array($value)) {
29+
self::transformTypes($value, $key);
30+
}
31+
}
32+
}
33+
}

tests/Misc/SchemaTransformerTest.php

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tomaj\NetteApi\Test\Params;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use Tomaj\NetteApi\Misc\OpenApiTransform;
9+
10+
class SchemaTransformerTest extends TestCase
11+
{
12+
public function testSingeTypeRequest()
13+
{
14+
$schema = [
15+
'type' => 'object',
16+
'properties' => [
17+
'image' => ['type' => 'string']
18+
]
19+
];
20+
$expected = [
21+
'type' => 'object',
22+
'properties' => [
23+
'image' => [
24+
'type' => 'string'
25+
]
26+
]
27+
];
28+
29+
OpenApiTransform::transformTypes($schema);
30+
$this->assertEquals($expected, $schema);
31+
}
32+
33+
public function testTypePropertyRequest()
34+
{
35+
$schema = [
36+
'type' => 'object',
37+
'properties' => [
38+
'type' => ['type' => 'string']
39+
]
40+
];
41+
$expected = [
42+
'type' => 'object',
43+
'properties' => [
44+
'type' => [
45+
'type' => 'string'
46+
]
47+
]
48+
];
49+
50+
OpenApiTransform::transformTypes($schema);
51+
$this->assertEquals($expected, $schema);
52+
}
53+
54+
public function testNullStringRequest()
55+
{
56+
$schema = [
57+
'type' => 'object',
58+
'properties' => [
59+
'image' => ['type' => ['string', 'null']],
60+
]
61+
];
62+
$expected = [
63+
'type' => 'object',
64+
'properties' => [
65+
'image' => [
66+
'type' => 'string',
67+
'nullable' => true
68+
]
69+
]
70+
];
71+
72+
OpenApiTransform::transformTypes($schema);
73+
$this->assertEquals($expected, $schema);
74+
}
75+
76+
public function testIntegerStringRequest()
77+
{
78+
$schema = [
79+
'type' => 'object',
80+
'properties' => [
81+
'image' => ['type' => ['string', 'integer']],
82+
]
83+
];
84+
$expected = [
85+
'type' => 'object',
86+
'properties' => [
87+
'image' => [
88+
'oneOf' => [
89+
['type' => 'string'],
90+
['type' => 'integer'],
91+
],
92+
]
93+
]
94+
];
95+
96+
OpenApiTransform::transformTypes($schema);
97+
$this->assertEquals($expected, $schema);
98+
}
99+
100+
public function testNullIntegerStringRequest()
101+
{
102+
$schema = [
103+
'type' => 'object',
104+
'properties' => [
105+
'image' => ['type' => ['string', 'integer', 'null']],
106+
]
107+
];
108+
$expected = [
109+
'type' => 'object',
110+
'properties' => [
111+
'image' => [
112+
'oneOf' => [
113+
['type' => 'string'],
114+
['type' => 'integer'],
115+
],
116+
'nullable' => true
117+
]
118+
]
119+
];
120+
121+
OpenApiTransform::transformTypes($schema);
122+
$this->assertEquals($expected, $schema);
123+
}
124+
125+
public function testTypePropertyNullIntegerStringRequest()
126+
{
127+
$schema = [
128+
'type' => 'object',
129+
'properties' => [
130+
'type' => ['type' => ['string', 'integer', 'null']],
131+
]
132+
];
133+
$expected = [
134+
'type' => 'object',
135+
'properties' => [
136+
'type' => [
137+
'oneOf' => [
138+
['type' => 'string'],
139+
['type' => 'integer'],
140+
],
141+
'nullable' => true
142+
]
143+
]
144+
];
145+
146+
OpenApiTransform::transformTypes($schema);
147+
$this->assertEquals($expected, $schema);
148+
}
149+
}

0 commit comments

Comments
 (0)