Skip to content

Commit 95b81a8

Browse files
JasonBenettJason Benedetti
and
Jason Benedetti
authored
feat: support 'default' attribute for required parameters (#32)
* feat: support 'default' attribute for required parameters * test: fix CS issue * test: fix PHPStan issue * docs: update changelog * refactor: simplify the parameter sorting Co-authored-by: Jason Benedetti <[email protected]>
1 parent 0da6c4f commit 95b81a8

File tree

7 files changed

+90
-15
lines changed

7 files changed

+90
-15
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7+
## [5.5.0] - 2021-04-27
8+
### Added
9+
- Support for `default` property on required request parameters.
710

811
## [5.4.0] - 2021-04-22
912
### Added

src/Entity/Field.php

+21-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ class Field
2323
private array $objectProperties = [];
2424
private array $enumValues = [];
2525
private string $format = '';
26+
/** @phpstan-ignore-next-line cannot use strict type before PHP8 with "mixed" pseudo type */
27+
private $default;
2628

2729
public function __construct(
2830
string $name,
@@ -154,6 +156,24 @@ public function isArrayOfObjects(): bool
154156
&& $this->getArrayItem()->isObject();
155157
}
156158

159+
/**
160+
* @return mixed
161+
*/
162+
public function getDefault()
163+
{
164+
return $this->default;
165+
}
166+
167+
/**
168+
* @param mixed $default
169+
*/
170+
public function setDefault($default): self
171+
{
172+
$this->default = $default;
173+
174+
return $this;
175+
}
176+
157177
public function getPhpVariableName(): string
158178
{
159179
return CaseCaster::toCamel($this->name);
@@ -208,7 +228,7 @@ public function getPhpDocType(bool $allowNullable = true): string
208228

209229
if ($this->isArray() && !$this->isArrayOfObjects()) {
210230
$arraySuffix = '[]';
211-
$typeHint = $this->getArrayItem()->getPhpDocType();
231+
$typeHint = $this->getArrayItem()->getPhpDocType();
212232
}
213233

214234
return sprintf('%s%s%s', $typeHint, $arraySuffix, $nullableSuffix);

src/Generator/RequestGenerator.php

+31-11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace DoclerLabs\ApiClientGenerator\Generator;
66

7+
use DoclerLabs\ApiClientGenerator\Ast\ParameterNode;
78
use DoclerLabs\ApiClientGenerator\Entity\Field;
89
use DoclerLabs\ApiClientGenerator\Entity\Operation;
910
use DoclerLabs\ApiClientGenerator\Entity\Request;
@@ -98,10 +99,15 @@ protected function generateConstructor(Request $request): ?ClassMethod
9899
if ($field->isRequired()) {
99100
array_push($paramInits, ...$this->generateValidationStmts($field));
100101

101-
$params[] = $this->builder
102+
$param = $this->builder
102103
->param($field->getPhpVariableName())
103-
->setType($field->getPhpTypeHint(), $field->isNullable())
104-
->getNode();
104+
->setType($field->getPhpTypeHint(), $field->isNullable());
105+
106+
if (null !== $field->getDefault()) {
107+
$param->setDefault($field->getDefault());
108+
}
109+
110+
$params[] = $param->getNode();
105111

106112
$paramInits[] = $this->builder->assign(
107113
$this->builder->localPropertyFetch($field->getPhpVariableName()),
@@ -129,6 +135,8 @@ protected function generateConstructor(Request $request): ?ClassMethod
129135
return null;
130136
}
131137

138+
$params = $this->sortParameters(...$params);
139+
132140
return $this->builder
133141
->method('__construct')
134142
->makePublic()
@@ -138,7 +146,7 @@ protected function generateConstructor(Request $request): ?ClassMethod
138146
->getNode();
139147
}
140148

141-
protected function generateSetters(Request $request): array
149+
private function generateSetters(Request $request): array
142150
{
143151
$statements = [];
144152
foreach ($request->getFields() as $fields) {
@@ -152,7 +160,7 @@ protected function generateSetters(Request $request): array
152160
return $statements;
153161
}
154162

155-
protected function generateGetContentType(): ClassMethod
163+
private function generateGetContentType(): ClassMethod
156164
{
157165
$return = $this->builder->return($this->builder->localPropertyFetch('contentType'));
158166
$returnType = 'string';
@@ -166,7 +174,7 @@ protected function generateGetContentType(): ClassMethod
166174
->getNode();
167175
}
168176

169-
protected function generateGetMethod(Request $request): ClassMethod
177+
private function generateGetMethod(Request $request): ClassMethod
170178
{
171179
$return = $this->builder->return($this->builder->val($request->getMethod()));
172180
$returnType = 'string';
@@ -180,7 +188,7 @@ protected function generateGetMethod(Request $request): ClassMethod
180188
->getNode();
181189
}
182190

183-
protected function generateGetRoute(Request $request): ClassMethod
191+
private function generateGetRoute(Request $request): ClassMethod
184192
{
185193
$values = [];
186194
$returnType = 'string';
@@ -216,7 +224,7 @@ protected function generateGetRoute(Request $request): ClassMethod
216224
->getNode();
217225
}
218226

219-
protected function generateGetParametersMethods(Request $request): array
227+
private function generateGetParametersMethods(Request $request): array
220228
{
221229
$methods = [];
222230
$fields = $request->getFields();
@@ -238,7 +246,7 @@ protected function generateGetParametersMethods(Request $request): array
238246
return $methods;
239247
}
240248

241-
protected function generateGetParametersMethod(string $methodName, array $fields): ClassMethod
249+
private function generateGetParametersMethod(string $methodName, array $fields): ClassMethod
242250
{
243251
$returnVal = $this->builder->array([]);
244252
$fieldsArr = [];
@@ -260,7 +268,7 @@ protected function generateGetParametersMethod(string $methodName, array $fields
260268
->getNode();
261269
}
262270

263-
protected function generateGetRawParametersMethod(string $methodName, array $fields): ClassMethod
271+
private function generateGetRawParametersMethod(string $methodName, array $fields): ClassMethod
264272
{
265273
$fieldsArr = [];
266274
$returnType = 'array';
@@ -277,7 +285,7 @@ protected function generateGetRawParametersMethod(string $methodName, array $fie
277285
->getNode();
278286
}
279287

280-
protected function generateGetBody(?Field $body): ClassMethod
288+
private function generateGetBody(?Field $body): ClassMethod
281289
{
282290
if ($body !== null) {
283291
$returnType = $body->getPhpTypeHint();
@@ -369,4 +377,16 @@ private function generateParametersFromFields(array $fields): FuncCall
369377
]
370378
);
371379
}
380+
381+
private function sortParameters(ParameterNode ...$parameterNodes): array
382+
{
383+
usort(
384+
$parameterNodes,
385+
static function (ParameterNode $paramA, ParameterNode $paramB) {
386+
return $paramA->default <=> $paramB->default;
387+
}
388+
);
389+
390+
return $parameterNodes;
391+
}
372392
}

src/Input/Factory/FieldFactory.php

+4
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ public function create(
126126
$field->setFormat($schema->format);
127127
}
128128

129+
if (isset($schema->default)) {
130+
$field->setDefault($schema->default);
131+
}
132+
129133
return $field;
130134
} catch (Throwable $exception) {
131135
throw new InvalidSpecificationException(

src/Input/Parser.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ private function extractCompositeRequestFields(OperationCollection $operations):
4545
$allFields = new FieldCollection();
4646
foreach ($operations as $operation) {
4747
$request = $operation->getRequest();
48-
foreach ($request->getFields() as $origin => $fields) {
48+
foreach ($request->getFields() as $fields) {
4949
foreach ($fields as $field) {
5050
$this->extractField($field, $allFields);
5151
}

test/suite/functional/Generator/Request/PatchResourceRequest.php

+20-2
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,30 @@
88

99
namespace Test\Request;
1010

11+
use DoclerLabs\ApiClientException\RequestValidationException;
1112
use Test\Schema\PatchResourceRequestBody;
13+
use Test\Schema\SerializableInterface;
1214

1315
class PatchResourceRequest implements RequestInterface
1416
{
17+
public const ACCEPT_APPLICATION_JSON = 'application/json';
18+
19+
public const ACCEPT_APPLICATION_XML = 'application/xml';
20+
21+
public const ALLOWED_ACCEPT_LIST = [self::ACCEPT_APPLICATION_JSON, self::ACCEPT_APPLICATION_XML];
22+
23+
private string $accept;
24+
1525
private PatchResourceRequestBody $patchResourceRequestBody;
1626

1727
private string $contentType = 'application/json';
1828

19-
public function __construct(PatchResourceRequestBody $patchResourceRequestBody)
29+
public function __construct(PatchResourceRequestBody $patchResourceRequestBody, string $accept = 'application/json')
2030
{
31+
if (! \in_array($accept, self::ALLOWED_ACCEPT_LIST, true)) {
32+
throw new RequestValidationException(\sprintf('Invalid %s value. Given: `%s` Allowed: %s', 'Accept', $accept, \json_encode(self::ALLOWED_ACCEPT_LIST)));
33+
}
34+
$this->accept = $accept;
2135
$this->patchResourceRequestBody = $patchResourceRequestBody;
2236
}
2337

@@ -53,7 +67,11 @@ public function getCookies(): array
5367

5468
public function getHeaders(): array
5569
{
56-
return ['Content-Type' => $this->contentType];
70+
return \array_merge(['Content-Type' => $this->contentType], \array_map(static function ($value) {
71+
return $value instanceof SerializableInterface ? $value->toArray() : $value;
72+
}, \array_filter(['Accept' => $this->accept], static function ($value) {
73+
return null !== $value;
74+
})));
5775
}
5876

5977
/**

test/suite/functional/Generator/Request/patchResource.yaml

+10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ paths:
77
patch:
88
description: Update resource
99
operationId: patchResource
10+
parameters:
11+
- in: header
12+
name: Accept
13+
required: true
14+
schema:
15+
type: string
16+
default: application/json
17+
enum:
18+
- application/json
19+
- application/xml
1020
requestBody:
1121
$ref: '#/components/requestBodies/UpdateResourceBody'
1222
responses:

0 commit comments

Comments
 (0)