From aa0111550b1ae583c95a6a24a61bd764da1f58c2 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Thu, 27 Mar 2025 21:04:14 +1300 Subject: [PATCH] Handle parameter class for spec generation --- src/Appwrite/Platform/Tasks/Specs.php | 18 ++++-- src/Appwrite/Specification/Format.php | 4 +- .../Specification/Format/Swagger2.php | 61 ++++++++----------- 3 files changed, 40 insertions(+), 43 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/Specs.php b/src/Appwrite/Platform/Tasks/Specs.php index 5b10c1ef25..1e9f956606 100644 --- a/src/Appwrite/Platform/Tasks/Specs.php +++ b/src/Appwrite/Platform/Tasks/Specs.php @@ -3,6 +3,7 @@ namespace Appwrite\Platform\Tasks; use Appwrite\SDK\AuthType; +use Appwrite\SDK\Method; use Appwrite\Specification\Format\OpenAPI3; use Appwrite\Specification\Format\Swagger2; use Appwrite\Specification\Specification; @@ -49,11 +50,10 @@ class Specs extends Action ->desc('Generate Appwrite API specifications') ->param('version', 'latest', new Text(16), 'Spec version', true) ->param('mode', 'normal', new WhiteList(['normal', 'mocks']), 'Spec Mode', true) - ->inject('register') - ->callback(fn (string $version, string $mode, Registry $register) => $this->action($version, $mode, $register)); + ->callback([$this, 'action']); } - public function action(string $version, string $mode, Registry $register): void + public function action(string $version, string $mode): void { $appRoutes = App::getRoutes(); $response = $this->getResponse(); @@ -194,7 +194,7 @@ class Specs extends Action } foreach ($sdks as $sdk) { - /** @var \Appwrite\SDK\Method $sdks */ + /** @var Method $sdk */ $hide = $sdk->isHidden(); if ($hide === true || (\is_array($hide) && \in_array($platform, $hide))) { @@ -273,7 +273,15 @@ class Specs extends Action } } - $arguments = [new App('UTC'), $services, $routes, $models, $keys[$platform], $authCounts[$platform] ?? 0]; + $arguments = [ + new App('UTC'), + $services, + $routes, + $models, + $keys[$platform], + $authCounts[$platform] ?? 0 + ]; + foreach (['swagger2', 'open-api3'] as $format) { $formatInstance = match ($format) { 'swagger2' => new Swagger2(...$arguments), diff --git a/src/Appwrite/Specification/Format.php b/src/Appwrite/Specification/Format.php index 8396f5cb7c..e9377382d2 100644 --- a/src/Appwrite/Specification/Format.php +++ b/src/Appwrite/Specification/Format.php @@ -12,12 +12,12 @@ abstract class Format protected App $app; /** - * @var Route[] + * @var array */ protected array $routes; /** - * @var Model[] + * @var array */ protected array $models; diff --git a/src/Appwrite/Specification/Format/Swagger2.php b/src/Appwrite/Specification/Format/Swagger2.php index 73b7cec923..dfede91ccd 100644 --- a/src/Appwrite/Specification/Format/Swagger2.php +++ b/src/Appwrite/Specification/Format/Swagger2.php @@ -3,16 +3,20 @@ namespace Appwrite\Specification\Format; use Appwrite\SDK\AuthType; +use Appwrite\SDK\Method; use Appwrite\SDK\MethodType; +use Appwrite\SDK\Response; use Appwrite\Specification\Format; use Appwrite\Template\Template; use Appwrite\Utopia\Response\Model; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; +use Utopia\Route; use Utopia\Validator; use Utopia\Validator\ArrayList; use Utopia\Validator\Nullable; use Utopia\Validator\Range; +use Utopia\Validator\WhiteList; class Swagger2 extends Format { @@ -27,28 +31,13 @@ class Swagger2 extends Format if (!in_array($model->getType(), $usedModels)) { continue; } - - if (\is_array($rule['type'])) { - foreach ($rule['type'] as $ruleType) { - if (!in_array($ruleType, ['string', 'integer', 'boolean', 'json', 'float'])) { - $usedModels[] = $ruleType; - - foreach ($this->models as $m) { - if ($m->getType() === $ruleType) { - $this->getNestedModels($m, $usedModels); - continue; - } - } - } - } - } else { - if (!in_array($rule['type'], ['string', 'integer', 'boolean', 'json', 'float'])) { - $usedModels[] = $rule['type']; - + $types = (array)$rule['type']; + foreach ($types as $ruleType) { + if (!in_array($ruleType, ['string', 'integer', 'boolean', 'json', 'float'])) { + $usedModels[] = $ruleType; foreach ($this->models as $m) { - if ($m->getType() === $rule['type']) { + if ($m->getType() === $ruleType) { $this->getNestedModels($m, $usedModels); - continue; } } } @@ -117,11 +106,12 @@ class Swagger2 extends Format $usedModels = []; foreach ($this->routes as $route) { - /** @var \Utopia\Route $route */ + /** @var Route $route */ $url = \str_replace('/v1', '', $route->getPath()); + $scope = $route->getLabel('scope', ''); - /** @var \Appwrite\SDK\Method $sdk */ + /** @var Method $sdk */ $sdk = $route->getLabel('sdk', false); if (empty($sdk)) { @@ -129,7 +119,7 @@ class Swagger2 extends Format } $additionalMethods = null; - if (is_array($sdk)) { + if (\is_array($sdk)) { $additionalMethods = $sdk; $sdk = $sdk[0]; } @@ -152,10 +142,8 @@ class Swagger2 extends Format case AuthType::SESSION: $sdkPlatforms[] = APP_PLATFORM_CLIENT; break; - case AuthType::KEY: - $sdkPlatforms[] = APP_PLATFORM_SERVER; - break; case AuthType::JWT: + case AuthType::KEY: $sdkPlatforms[] = APP_PLATFORM_SERVER; break; case AuthType::ADMIN: @@ -203,7 +191,7 @@ class Swagger2 extends Format if (!empty($additionalMethods)) { $temp['x-appwrite']['methods'] = []; foreach ($additionalMethods as $method) { - /** @var \Appwrite\SDK\Method $method */ + /** @var Method $method */ $desc = $method->getDescriptionFilePath(); $additionalMethod = [ @@ -214,16 +202,16 @@ class Swagger2 extends Format 'description' => ($desc) ? \file_get_contents($desc) : '', ]; - foreach ($method->getParameters() as $name => $param) { - $additionalMethod['parameters'][] = $name; + foreach ($method->getParameters() as $parameter) { + $additionalMethod['parameters'][] = $parameter->getName(); - if (!$param['optional']) { - $additionalMethod['required'][] = $name; + if (!$parameter->isOptional()) { + $additionalMethod['required'][] = $parameter->getName(); } } foreach ($method->getResponses() as $response) { - /** @var \Appwrite\SDK\Response $response */ + /** @var Response $response */ if (\is_array($response->getModel())) { $additionalMethod['responses'][] = [ 'code' => $response->getCode(), @@ -242,9 +230,8 @@ class Swagger2 extends Format } // Handle Responses - foreach ($sdk->getResponses() as $response) { - /** @var \Appwrite\SDK\Response $response */ + /** @var Response $response */ $model = $response->getModel(); foreach ($this->models as $value) { @@ -339,7 +326,9 @@ class Swagger2 extends Format foreach ($parameters as $name => $param) { // Set params /** @var Validator $validator */ - $validator = (\is_callable($param['validator'])) ? call_user_func_array($param['validator'], $this->app->getResources($param['injections'])) : $param['validator']; + $validator = (\is_callable($param['validator'])) + ? ($param['validator'])($this->app->getResources($param['injections'])) + : $param['validator']; $node = [ 'name' => $name, @@ -484,7 +473,7 @@ class Swagger2 extends Format $node['type'] = $validator->getType(); break; case 'Utopia\Validator\WhiteList': - /** @var \Utopia\Validator\WhiteList $validator */ + /** @var WhiteList $validator */ $node['type'] = $validator->getType(); $node['x-example'] = $validator->getList()[0];