Skip to content

Commit

Permalink
fix(OpenApiType): Use maxItems instead of maxLength for arrays
Browse files Browse the repository at this point in the history
Signed-off-by: provokateurin <[email protected]>
  • Loading branch information
provokateurin committed Apr 15, 2024
1 parent a2dde48 commit 533fd11
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/ControllerMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public static function parse(string $context, array $definitions, ClassMethod $m
}

if (str_starts_with($type->name, 'OCS') && str_ends_with($type->name, 'Exception')) {
$responses[] = new ControllerMethodResponse($docNode->value->type, $statusCode, "application/json", new OpenApiType(type: "array", maxLength: 0), null);
$responses[] = new ControllerMethodResponse($docNode->value->type, $statusCode, "application/json", new OpenApiType(type: "array", maxItems: 0), null);
} else {
$responses[] = new ControllerMethodResponse($docNode->value->type, $statusCode, "text/plain", new OpenApiType(type: "string"), null);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ public static function wrapOCSResponse(Route $route, ControllerMethodResponse $r
}

public static function cleanEmptyResponseArray(array $schema): array|stdClass {
if (key_exists("type", $schema) && $schema["type"] == "array" && key_exists("maxLength", $schema) && $schema["maxLength"] === 0) {
if (array_key_exists('type', $schema) && $schema['type'] === 'array' && array_key_exists('maxItems', $schema) && $schema['maxItems'] === 0) {
return new stdClass();
}

Expand Down
10 changes: 9 additions & 1 deletion src/OpenApiType.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public function __construct(
public ?int $maxLength = null,
public ?int $minimum = null,
public ?int $maximum = null,
public ?int $minItems = null,
public ?int $maxItems = null,
public ?array $enum = null,
) {
}
Expand Down Expand Up @@ -120,6 +122,12 @@ public function toArray(string $openapiVersion, bool $isParameter = false): arra
if ($this->maximum !== null) {
$values["maximum"] = $this->maximum;
}
if ($this->minItems !== null) {
$values["minItems"] = $this->minItems;
}
if ($this->maxItems !== null) {
$values["maxItems"] = $this->maxItems;
}
if ($this->required !== null) {
$values["required"] = $this->required;
}
Expand Down Expand Up @@ -166,7 +174,7 @@ public static function resolve(string $context, array $definitions, ParamTagValu
}
if ($node instanceof GenericTypeNode && ($node->type->name == "array" || $node->type->name == "list") && count($node->genericTypes) == 1) {
if ($node->genericTypes[0] instanceof IdentifierTypeNode && $node->genericTypes[0]->name == "empty") {
return new OpenApiType(type: "array", maxLength: 0);
return new OpenApiType(type: "array", maxItems: 0);
}
return new OpenApiType(type: "array", items: self::resolve($context, $definitions, $node->genericTypes[0]));
}
Expand Down
1 change: 1 addition & 0 deletions tests/appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,6 @@
['name' => 'Settings#oneOf', 'url' => '/api/{apiVersion}/oneOf', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
['name' => 'Settings#anyOf', 'url' => '/api/{apiVersion}/anyOf', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
['name' => 'Settings#floatDouble', 'url' => '/api/{apiVersion}/floatDouble', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
['name' => 'Settings#emptyArray', 'url' => '/api/{apiVersion}/emptyArray', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
],
];
12 changes: 12 additions & 0 deletions tests/lib/Controller/SettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -526,4 +526,16 @@ public function anyOf(): DataResponse {
public function floatDouble(): DataResponse {
return new DataResponse();
}

/**
* Route with empty array
*
* @return DataResponse<Http::STATUS_OK, array{test: array<empty>}, array{}>
*
* 200: OK
*/
#[PasswordConfirmationRequired]
public function emptyArray(): DataResponse {
return new DataResponse();
}
}
83 changes: 83 additions & 0 deletions tests/openapi-administration.json
Original file line number Diff line number Diff line change
Expand Up @@ -3021,6 +3021,89 @@
}
}
},
"/ocs/v2.php/apps/notifications/api/{apiVersion}/emptyArray": {
"post": {
"operationId": "settings-empty-array",
"summary": "Route with empty array",
"description": "This endpoint requires admin access\nThis endpoint requires password confirmation",
"tags": [
"settings"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "apiVersion",
"in": "path",
"required": true,
"schema": {
"type": "string",
"enum": [
"v2"
],
"default": "v2"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "object",
"required": [
"test"
],
"properties": {
"test": {
"type": "array",
"maxItems": 0
}
}
}
}
}
}
}
}
}
}
}
}
},
"/ocs/v2.php/tests/attribute-ocs/{param}": {
"get": {
"operationId": "routing-attributeocs-route",
Expand Down
83 changes: 83 additions & 0 deletions tests/openapi-full.json
Original file line number Diff line number Diff line change
Expand Up @@ -3148,6 +3148,89 @@
}
}
},
"/ocs/v2.php/apps/notifications/api/{apiVersion}/emptyArray": {
"post": {
"operationId": "settings-empty-array",
"summary": "Route with empty array",
"description": "This endpoint requires admin access\nThis endpoint requires password confirmation",
"tags": [
"settings"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "apiVersion",
"in": "path",
"required": true,
"schema": {
"type": "string",
"enum": [
"v2"
],
"default": "v2"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "object",
"required": [
"test"
],
"properties": {
"test": {
"type": "array",
"maxItems": 0
}
}
}
}
}
}
}
}
}
}
}
}
},
"/ocs/v2.php/tests/attribute-ocs/{param}": {
"get": {
"operationId": "routing-attributeocs-route",
Expand Down

0 comments on commit 533fd11

Please sign in to comment.