Skip to content

Commit 3b3da99

Browse files
committed
Introduce OptionalType with default value
1 parent 9366022 commit 3b3da99

File tree

5 files changed

+38
-6
lines changed

5 files changed

+38
-6
lines changed

src/Bridge/ApiPlatform/ApiPlatformDtoResourceVisitor.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Riverwaysoft\DtoConverter\Dto\ApiClient\ApiEndpointMethod;
1717
use Riverwaysoft\DtoConverter\Dto\ApiClient\ApiEndpointParam;
1818
use Riverwaysoft\DtoConverter\Dto\PhpType\PhpBaseType;
19+
use Riverwaysoft\DtoConverter\Dto\PhpType\PhpOptionalType;
1920
use Riverwaysoft\DtoConverter\Dto\PhpType\PhpTypeFactory;
2021
use Riverwaysoft\DtoConverter\Dto\PhpType\PhpTypeInterface;
2122

@@ -135,7 +136,7 @@ private function createApiEndpoint(Node\Expr\ArrayItem $item, bool $isCollection
135136

136137
// All API Platform GET methods can be filtered
137138
if ($isCollection && $method->equals(ApiEndpointMethod::get())) {
138-
$queryParams[] = new ApiEndpointParam('filters', PhpBaseType::object());
139+
$queryParams[] = new ApiEndpointParam('filters', new PhpOptionalType(PhpBaseType::object()));
139140
}
140141

141142
$output = $arrayItemValue ? ($this->findArrayAttributeValueByKey('output', $arrayItemValue) ?? $mainOutput) : $mainOutput;
@@ -151,7 +152,7 @@ private function createApiEndpoint(Node\Expr\ArrayItem $item, bool $isCollection
151152
}
152153
}
153154

154-
$inputType = $input !== null ? new ApiEndpointParam(name: 'body', type: PhpTypeFactory::create($input)) : null;
155+
$inputType = $input !== null ? new ApiEndpointParam('body', PhpTypeFactory::create($input)) : null;
155156

156157
return new ApiEndpoint(
157158
route: $route,

src/Dto/ApiClient/ApiEndpointParam.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public function jsonSerialize(): mixed
1818
{
1919
return [
2020
'name' => $this->name,
21-
'type' => $this->type
21+
'type' => $this->type,
2222
];
2323
}
2424
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Riverwaysoft\DtoConverter\Dto\PhpType;
6+
7+
class PhpOptionalType implements PhpTypeInterface
8+
{
9+
public function __construct(
10+
private PhpTypeInterface $type,
11+
) {
12+
}
13+
14+
public function getType(): PhpTypeInterface
15+
{
16+
return $this->type;
17+
}
18+
19+
public function jsonSerialize(): mixed
20+
{
21+
return [
22+
'type' => $this->type,
23+
'isOptional' => true,
24+
];
25+
}
26+
}

src/Language/TypeScript/TypeScriptGenerator.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Riverwaysoft\DtoConverter\Dto\ExpressionType;
1515
use Riverwaysoft\DtoConverter\Dto\PhpType\PhpBaseType;
1616
use Riverwaysoft\DtoConverter\Dto\PhpType\PhpListType;
17+
use Riverwaysoft\DtoConverter\Dto\PhpType\PhpOptionalType;
1718
use Riverwaysoft\DtoConverter\Dto\PhpType\PhpTypeInterface;
1819
use Riverwaysoft\DtoConverter\Dto\PhpType\PhpUnionType;
1920
use Riverwaysoft\DtoConverter\Dto\PhpType\PhpUnknownType;
@@ -220,6 +221,10 @@ private function getTypeScriptTypeFromPhp(PhpTypeInterface $type, DtoType|null $
220221
return sprintf('%s[]', $listType);
221222
}
222223

224+
if ($type instanceof PhpOptionalType) {
225+
return sprintf('%s | null = null', $this->getTypeScriptTypeFromPhp($type->getType(), $dto, $dtoList));
226+
}
227+
223228
if ($type instanceof PhpBaseType) {
224229
/** @var PhpBaseType $type */
225230
return match (true) {

tests/__snapshots__/TypeScriptGeneratorTest__testApiClientGenerationWithApiPlatformResource__1.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export type StudentNotesOutput = {
3232
export type StudentNotesUpdateInput = {
3333
};
3434

35-
export const apiChatsGet = (filters: any): Promise<CollectionResponse<ChatOutput>> => {
35+
export const apiChatsGet = (filters: any | null = null): Promise<CollectionResponse<ChatOutput>> => {
3636
return axios
3737
.get<CollectionResponse<ChatOutput>>(`/api/chats`, { params: filters })
3838
.then((response) => response.data);
@@ -62,7 +62,7 @@ export const apiChatsIdMutePut = (id: string): Promise<ChatOutput> => {
6262
.then((response) => response.data);
6363
}
6464

65-
export const apiChatsAdminZoneGet = (filters: any): Promise<CollectionResponse<AdminZoneChatOutput>> => {
65+
export const apiChatsAdminZoneGet = (filters: any | null = null): Promise<CollectionResponse<AdminZoneChatOutput>> => {
6666
return axios
6767
.get<CollectionResponse<AdminZoneChatOutput>>(`/api/chats_admin_zone`, { params: filters })
6868
.then((response) => response.data);
@@ -86,7 +86,7 @@ export const apiChatsAdminZoneIdGet = (id: string): Promise<AdminZoneChatOutput>
8686
.then((response) => response.data);
8787
}
8888

89-
export const apiStudentNotesGet = (filters: any): Promise<CollectionResponse<StudentNotesOutput>> => {
89+
export const apiStudentNotesGet = (filters: any | null = null): Promise<CollectionResponse<StudentNotesOutput>> => {
9090
return axios
9191
.get<CollectionResponse<StudentNotesOutput>>(`/api/student_notes`, { params: filters })
9292
.then((response) => response.data);

0 commit comments

Comments
 (0)