Skip to content

Commit

Permalink
Merge pull request #168 from nextcloud/fix/openapitype/array-syntax-a…
Browse files Browse the repository at this point in the history
…mbiguities
  • Loading branch information
provokateurin authored Nov 6, 2024
2 parents e366070 + dd13b3f commit d7c135e
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 49 deletions.
2 changes: 1 addition & 1 deletion generate-spec
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ if (file_exists($definitionsPath)) {
}
}
foreach (array_keys($definitions) as $name) {
$schemas[Helpers::cleanSchemaName($name)] = OpenApiType::resolve('Response definitions', $definitions, $definitions[$name])->toArray();
$schemas[Helpers::cleanSchemaName($name)] = OpenApiType::resolve('Response definitions: ' . $name, $definitions, $definitions[$name])->toArray();
}
} else {
Logger::debug('Response definitions', 'No response definitions were loaded');
Expand Down
8 changes: 7 additions & 1 deletion src/OpenApiType.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,19 @@ public static function resolve(string $context, array $definitions, ParamTagValu
}

if ($node instanceof ArrayTypeNode) {
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.");

return new OpenApiType(
context: $context,
type: 'array',
items: self::resolve($context . ': items', $definitions, $node->type),
);
}
if ($node instanceof GenericTypeNode && ($node->type->name === 'array' || $node->type->name === 'list' || $node->type->name === 'non-empty-list') && count($node->genericTypes) === 1) {
if ($node->type->name === 'array') {
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.");
}

if ($node->genericTypes[0] instanceof IdentifierTypeNode && $node->genericTypes[0]->name === 'empty') {
return new OpenApiType(
context: $context,
Expand All @@ -203,8 +209,8 @@ public static function resolve(string $context, array $definitions, ParamTagValu
$properties = [];
$required = [];
foreach ($node->items as $item) {
$type = self::resolve($context, $definitions, $item->valueType);
$name = $item->keyName instanceof ConstExprStringNode ? $item->keyName->value : $item->keyName->name;
$type = self::resolve($context . ': ' . $name, $definitions, $item->valueType);
$properties[$name] = $type;
if (!$item->optional) {
$required[] = $name;
Expand Down
8 changes: 4 additions & 4 deletions tests/lib/Controller/AdminSettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class AdminSettingsController extends OCSController {
/**
* Route is only in the admin scope because there is no "NoAdminRequired" annotation or attribute
*
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
*
* 200: Personal settings updated
*/
Expand All @@ -29,7 +29,7 @@ public function adminScopeImplicitFromAdminRequired(): DataResponse {
/**
* Route is in the default scope because the method overwrites with the Attribute
*
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
*
* 200: Personal settings updated
*/
Expand All @@ -41,7 +41,7 @@ public function movedToDefaultScope(): DataResponse {
/**
* Route in default scope with tags
*
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
*
* 200: Personal settings updated
*/
Expand All @@ -53,7 +53,7 @@ public function movedToSettingsTag(): DataResponse {
/**
* Route in default scope with tags but without named parameters on the attribute
*
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
*
* 200: Personal settings updated
*/
Expand Down
4 changes: 2 additions & 2 deletions tests/lib/Controller/ExAppSettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class ExAppSettingsController extends OCSController {
/**
* Route is in ex_app scope because of the attribute
*
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
*
* 200: Personal settings updated
*/
Expand All @@ -32,7 +32,7 @@ public function exAppScopeAttribute(): DataResponse {
/**
* Route is in ex_app scope because of the override
*
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
*
* 200: Personal settings updated
*/
Expand Down
4 changes: 2 additions & 2 deletions tests/lib/Controller/FederationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class FederationController extends OCSController {
*
* Route is in federation scope as per controller scope
*
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
*
* 200: OK
*/
Expand All @@ -43,7 +43,7 @@ public function federationByController(): DataResponse {
* Route is only in the default scope (moved from federation)
*
* @param NotificationsRequestProperty $property Property
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
*
* 200: Personal settings updated
*/
Expand Down
4 changes: 2 additions & 2 deletions tests/lib/Controller/RoutingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
class RoutingController extends OCSController {
/**
* OCS Route with attribute
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
*
* 200: Success
*/
Expand All @@ -30,7 +30,7 @@ public function attributeOCS() {
* @NoCSRFRequired
*
* Index Route with attribute
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
* @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
*
* 200: Success
*/
Expand Down
Loading

0 comments on commit d7c135e

Please sign in to comment.