Skip to content

Commit d7c135e

Browse files
Merge pull request #168 from nextcloud/fix/openapitype/array-syntax-ambiguities
2 parents e366070 + dd13b3f commit d7c135e

8 files changed

+55
-49
lines changed

generate-spec

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ if (file_exists($definitionsPath)) {
154154
}
155155
}
156156
foreach (array_keys($definitions) as $name) {
157-
$schemas[Helpers::cleanSchemaName($name)] = OpenApiType::resolve('Response definitions', $definitions, $definitions[$name])->toArray();
157+
$schemas[Helpers::cleanSchemaName($name)] = OpenApiType::resolve('Response definitions: ' . $name, $definitions, $definitions[$name])->toArray();
158158
}
159159
} else {
160160
Logger::debug('Response definitions', 'No response definitions were loaded');

src/OpenApiType.php

+7-1
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,19 @@ public static function resolve(string $context, array $definitions, ParamTagValu
174174
}
175175

176176
if ($node instanceof ArrayTypeNode) {
177+
Logger::error($context, "The 'TYPE[]' syntax for arrays is forbidden due to ambiguities. Use 'list<TYPE>' for JSON arrays or 'array<string, TYPE>' for JSON objects instead.");
178+
177179
return new OpenApiType(
178180
context: $context,
179181
type: 'array',
180182
items: self::resolve($context . ': items', $definitions, $node->type),
181183
);
182184
}
183185
if ($node instanceof GenericTypeNode && ($node->type->name === 'array' || $node->type->name === 'list' || $node->type->name === 'non-empty-list') && count($node->genericTypes) === 1) {
186+
if ($node->type->name === 'array') {
187+
Logger::error($context, "The 'array<TYPE>' syntax for arrays is forbidden due to ambiguities. Use 'list<TYPE>' for JSON arrays or 'array<string, TYPE>' for JSON objects instead.");
188+
}
189+
184190
if ($node->genericTypes[0] instanceof IdentifierTypeNode && $node->genericTypes[0]->name === 'empty') {
185191
return new OpenApiType(
186192
context: $context,
@@ -203,8 +209,8 @@ public static function resolve(string $context, array $definitions, ParamTagValu
203209
$properties = [];
204210
$required = [];
205211
foreach ($node->items as $item) {
206-
$type = self::resolve($context, $definitions, $item->valueType);
207212
$name = $item->keyName instanceof ConstExprStringNode ? $item->keyName->value : $item->keyName->name;
213+
$type = self::resolve($context . ': ' . $name, $definitions, $item->valueType);
208214
$properties[$name] = $type;
209215
if (!$item->optional) {
210216
$required[] = $name;

tests/lib/Controller/AdminSettingsController.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class AdminSettingsController extends OCSController {
1818
/**
1919
* Route is only in the admin scope because there is no "NoAdminRequired" annotation or attribute
2020
*
21-
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
21+
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
2222
*
2323
* 200: Personal settings updated
2424
*/
@@ -29,7 +29,7 @@ public function adminScopeImplicitFromAdminRequired(): DataResponse {
2929
/**
3030
* Route is in the default scope because the method overwrites with the Attribute
3131
*
32-
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
32+
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
3333
*
3434
* 200: Personal settings updated
3535
*/
@@ -41,7 +41,7 @@ public function movedToDefaultScope(): DataResponse {
4141
/**
4242
* Route in default scope with tags
4343
*
44-
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
44+
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
4545
*
4646
* 200: Personal settings updated
4747
*/
@@ -53,7 +53,7 @@ public function movedToSettingsTag(): DataResponse {
5353
/**
5454
* Route in default scope with tags but without named parameters on the attribute
5555
*
56-
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
56+
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
5757
*
5858
* 200: Personal settings updated
5959
*/

tests/lib/Controller/ExAppSettingsController.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class ExAppSettingsController extends OCSController {
2020
/**
2121
* Route is in ex_app scope because of the attribute
2222
*
23-
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
23+
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
2424
*
2525
* 200: Personal settings updated
2626
*/
@@ -32,7 +32,7 @@ public function exAppScopeAttribute(): DataResponse {
3232
/**
3333
* Route is in ex_app scope because of the override
3434
*
35-
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
35+
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
3636
*
3737
* 200: Personal settings updated
3838
*/

tests/lib/Controller/FederationController.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class FederationController extends OCSController {
2929
*
3030
* Route is in federation scope as per controller scope
3131
*
32-
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
32+
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
3333
*
3434
* 200: OK
3535
*/
@@ -43,7 +43,7 @@ public function federationByController(): DataResponse {
4343
* Route is only in the default scope (moved from federation)
4444
*
4545
* @param NotificationsRequestProperty $property Property
46-
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
46+
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
4747
*
4848
* 200: Personal settings updated
4949
*/

tests/lib/Controller/RoutingController.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
class RoutingController extends OCSController {
1717
/**
1818
* OCS Route with attribute
19-
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
19+
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
2020
*
2121
* 200: Success
2222
*/
@@ -30,7 +30,7 @@ public function attributeOCS() {
3030
* @NoCSRFRequired
3131
*
3232
* Index Route with attribute
33-
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
33+
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
3434
*
3535
* 200: Success
3636
*/

0 commit comments

Comments
 (0)