Merge pull request #3473 from appwrite/feat-specs-nested-models
feat: nested models in spec
This commit is contained in:
commit
4ffca32653
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -123,105 +123,94 @@ $cli
|
|||
],
|
||||
];
|
||||
|
||||
foreach (['swagger2', 'open-api3'] as $format) {
|
||||
foreach ($platforms as $platform) {
|
||||
$routes = [];
|
||||
$models = [];
|
||||
$services = [];
|
||||
foreach ($platforms as $platform) {
|
||||
$routes = [];
|
||||
$models = [];
|
||||
$services = [];
|
||||
|
||||
foreach ($appRoutes as $key => $method) {
|
||||
foreach ($method as $route) {
|
||||
/** @var \Utopia\Route $route */
|
||||
$routeSecurity = $route->getLabel('sdk.auth', []);
|
||||
$sdkPlatofrms = [];
|
||||
foreach ($appRoutes as $key => $method) {
|
||||
foreach ($method as $route) {
|
||||
/** @var \Utopia\Route $route */
|
||||
$routeSecurity = $route->getLabel('sdk.auth', []);
|
||||
$sdkPlaforms = [];
|
||||
|
||||
foreach ($routeSecurity as $value) {
|
||||
switch ($value) {
|
||||
case APP_AUTH_TYPE_SESSION:
|
||||
$sdkPlatofrms[] = APP_PLATFORM_CLIENT;
|
||||
break;
|
||||
case APP_AUTH_TYPE_KEY:
|
||||
$sdkPlatofrms[] = APP_PLATFORM_SERVER;
|
||||
break;
|
||||
case APP_AUTH_TYPE_JWT:
|
||||
$sdkPlatofrms[] = APP_PLATFORM_SERVER;
|
||||
break;
|
||||
case APP_AUTH_TYPE_ADMIN:
|
||||
$sdkPlatofrms[] = APP_PLATFORM_CONSOLE;
|
||||
break;
|
||||
}
|
||||
foreach ($routeSecurity as $value) {
|
||||
switch ($value) {
|
||||
case APP_AUTH_TYPE_SESSION:
|
||||
$sdkPlaforms[] = APP_PLATFORM_CLIENT;
|
||||
break;
|
||||
case APP_AUTH_TYPE_KEY:
|
||||
$sdkPlaforms[] = APP_PLATFORM_SERVER;
|
||||
break;
|
||||
case APP_AUTH_TYPE_JWT:
|
||||
$sdkPlaforms[] = APP_PLATFORM_SERVER;
|
||||
break;
|
||||
case APP_AUTH_TYPE_ADMIN:
|
||||
$sdkPlaforms[] = APP_PLATFORM_CONSOLE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (empty($routeSecurity)) {
|
||||
$sdkPlatofrms[] = APP_PLATFORM_CLIENT;
|
||||
}
|
||||
|
||||
if (!$route->getLabel('docs', true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($route->getLabel('sdk.mock', false) && !$mocks) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$route->getLabel('sdk.mock', false) && $mocks) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (empty($route->getLabel('sdk.namespace', null))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($platform !== APP_PLATFORM_CONSOLE && !\in_array($platforms[$platform], $sdkPlatofrms)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$routes[] = $route;
|
||||
$modelLabel = $route->getLabel('sdk.response.model', 'none');
|
||||
\is_array($modelLabel) ? \array_map(function ($m) use ($response) {
|
||||
return $response->getModel($m);
|
||||
}, $modelLabel) : $response->getModel($modelLabel);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Config::getParam('services', []) as $service) {
|
||||
if (
|
||||
!isset($service['docs']) // Skip service if not part of the public API
|
||||
|| !isset($service['sdk'])
|
||||
|| !$service['docs']
|
||||
|| !$service['sdk']
|
||||
) {
|
||||
if (empty($routeSecurity)) {
|
||||
$sdkPlaforms[] = APP_PLATFORM_CLIENT;
|
||||
}
|
||||
|
||||
if (!$route->getLabel('docs', true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$services[] = [
|
||||
'name' => $service['key'] ?? '',
|
||||
'description' => $service['subtitle'] ?? '',
|
||||
'x-globalAttributes' => $service['globalAttributes'] ?? [],
|
||||
];
|
||||
}
|
||||
|
||||
$models = $response->getModels();
|
||||
|
||||
foreach ($models as $key => $value) {
|
||||
if ($platform !== APP_PLATFORM_CONSOLE && !$value->isPublic()) {
|
||||
unset($models[$key]);
|
||||
if ($route->getLabel('sdk.mock', false) && !$mocks) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$route->getLabel('sdk.mock', false) && $mocks) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (empty($route->getLabel('sdk.namespace', null))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($platform !== APP_PLATFORM_CONSOLE && !\in_array($platforms[$platform], $sdkPlaforms)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$routes[] = $route;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Config::getParam('services', []) as $service) {
|
||||
if (
|
||||
!isset($service['docs']) // Skip service if not part of the public API
|
||||
|| !isset($service['sdk'])
|
||||
|| !$service['docs']
|
||||
|| !$service['sdk']
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ($format) {
|
||||
case 'swagger2':
|
||||
$formatInstance = new Swagger2(new App('UTC'), $services, $routes, $models, $keys[$platform], $authCounts[$platform] ?? 0);
|
||||
break;
|
||||
$services[] = [
|
||||
'name' => $service['key'] ?? '',
|
||||
'description' => $service['subtitle'] ?? '',
|
||||
'x-globalAttributes' => $service['globalAttributes'] ?? [],
|
||||
];
|
||||
}
|
||||
|
||||
case 'open-api3':
|
||||
$formatInstance = new OpenAPI3(new App('UTC'), $services, $routes, $models, $keys[$platform], $authCounts[$platform] ?? 0);
|
||||
break;
|
||||
$models = $response->getModels();
|
||||
|
||||
default:
|
||||
throw new Exception('Format not found: ' . $format);
|
||||
break;
|
||||
foreach ($models as $key => $value) {
|
||||
if ($platform !== APP_PLATFORM_CONSOLE && !$value->isPublic()) {
|
||||
unset($models[$key]);
|
||||
}
|
||||
}
|
||||
// var_dump($models);
|
||||
$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),
|
||||
'open-api3' => new OpenAPI3(...$arguments),
|
||||
default => throw new Exception('Format not found: ' . $format)
|
||||
};
|
||||
|
||||
$specs = new Specification($formatInstance);
|
||||
$endpoint = App::getEnv('_APP_HOME', '[HOSTNAME]');
|
||||
|
|
|
@ -8,40 +8,22 @@ use Appwrite\Utopia\Response\Model;
|
|||
|
||||
abstract class Format
|
||||
{
|
||||
/**
|
||||
* @var App
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $services;
|
||||
protected App $app;
|
||||
|
||||
/**
|
||||
* @var Route[]
|
||||
*/
|
||||
protected $routes;
|
||||
protected array $routes;
|
||||
|
||||
/**
|
||||
* @var Model[]
|
||||
*/
|
||||
protected $models;
|
||||
protected array $models;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $keys;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $authCount;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $params = [
|
||||
protected array $services;
|
||||
protected array $keys;
|
||||
protected int $authCount;
|
||||
protected array $params = [
|
||||
'name' => '',
|
||||
'description' => '',
|
||||
'endpoint' => 'https://localhost',
|
||||
|
@ -56,14 +38,6 @@ abstract class Format
|
|||
'license.url' => '',
|
||||
];
|
||||
|
||||
/**
|
||||
* @param App $app
|
||||
* @param array $services
|
||||
* @param Route[] $routes
|
||||
* @param Model[] $models
|
||||
* @param array $keys
|
||||
* @param int $authCount
|
||||
*/
|
||||
public function __construct(App $app, array $services, array $routes, array $models, array $keys, int $authCount)
|
||||
{
|
||||
$this->app = $app;
|
||||
|
@ -121,10 +95,6 @@ abstract class Format
|
|||
*/
|
||||
public function getParam(string $key, string $default = ''): string
|
||||
{
|
||||
if (!isset($this->params[$key])) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $this->params[$key];
|
||||
return $this->params[$key] ?? $default;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,35 +4,40 @@ namespace Appwrite\Specification\Format;
|
|||
|
||||
use Appwrite\Specification\Format;
|
||||
use Appwrite\Template\Template;
|
||||
use Appwrite\Utopia\Response\Model;
|
||||
use Utopia\Validator;
|
||||
|
||||
class OpenAPI3 extends Format
|
||||
{
|
||||
/**
|
||||
* Get Name.
|
||||
*
|
||||
* Get format name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'Open API 3';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse
|
||||
*
|
||||
* Parses Appwrite App to given format
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getNestedModels(Model $model, array &$usedModels): void
|
||||
{
|
||||
foreach ($model->getRules() as $rule) {
|
||||
if (
|
||||
in_array($model->getType(), $usedModels)
|
||||
&& !in_array($rule['type'], ['string', 'integer', 'boolean', 'json', 'float', 'double'])
|
||||
) {
|
||||
$usedModels[] = $rule['type'];
|
||||
foreach ($this->models as $m) {
|
||||
if ($m->getType() === $rule['type']) {
|
||||
$this->getNestedModels($m, $usedModels);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function parse(): array
|
||||
{
|
||||
/**
|
||||
* Specifications (v3.0.0):
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md
|
||||
*/
|
||||
* Specifications (v3.0.0):
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md
|
||||
*/
|
||||
$output = [
|
||||
'openapi' => '3.0.0',
|
||||
'info' => [
|
||||
|
@ -89,7 +94,7 @@ class OpenAPI3 extends Format
|
|||
|
||||
$usedModels = [];
|
||||
|
||||
foreach ($this->routes as $route) { /** @var \Utopia\Route $route */
|
||||
foreach ($this->routes as $route) {
|
||||
$url = \str_replace('/v1', '', $route->getPath());
|
||||
$scope = $route->getLabel('scope', '');
|
||||
$hide = $route->getLabel('sdk.hide', false);
|
||||
|
@ -104,34 +109,32 @@ class OpenAPI3 extends Format
|
|||
$produces = $route->getLabel('sdk.response.type', null);
|
||||
$model = $route->getLabel('sdk.response.model', 'none');
|
||||
$routeSecurity = $route->getLabel('sdk.auth', []);
|
||||
$sdkPlatofrms = [];
|
||||
$sdkPlatforms = [];
|
||||
|
||||
foreach ($routeSecurity as $value) {
|
||||
switch ($value) {
|
||||
case APP_AUTH_TYPE_SESSION:
|
||||
$sdkPlatofrms[] = APP_PLATFORM_CLIENT;
|
||||
$sdkPlatforms[] = APP_PLATFORM_CLIENT;
|
||||
break;
|
||||
case APP_AUTH_TYPE_KEY:
|
||||
$sdkPlatofrms[] = APP_PLATFORM_SERVER;
|
||||
$sdkPlatforms[] = APP_PLATFORM_SERVER;
|
||||
break;
|
||||
case APP_AUTH_TYPE_JWT:
|
||||
$sdkPlatofrms[] = APP_PLATFORM_SERVER;
|
||||
$sdkPlatforms[] = APP_PLATFORM_SERVER;
|
||||
break;
|
||||
case APP_AUTH_TYPE_ADMIN:
|
||||
$sdkPlatofrms[] = APP_PLATFORM_CONSOLE;
|
||||
$sdkPlatforms[] = APP_PLATFORM_CONSOLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($routeSecurity)) {
|
||||
$sdkPlatofrms[] = APP_PLATFORM_CLIENT;
|
||||
$sdkPlatforms[] = APP_PLATFORM_CLIENT;
|
||||
}
|
||||
|
||||
$temp = [
|
||||
'summary' => $route->getDesc(),
|
||||
'operationId' => $route->getLabel('sdk.namespace', 'default') . ucfirst($id),
|
||||
// 'consumes' => [],
|
||||
// 'produces' => [$produces],
|
||||
'tags' => [$route->getLabel('sdk.namespace', 'default')],
|
||||
'description' => ($desc) ? \file_get_contents($desc) : '',
|
||||
'responses' => [],
|
||||
|
@ -146,20 +149,14 @@ class OpenAPI3 extends Format
|
|||
'rate-time' => $route->getLabel('abuse-time', 3600),
|
||||
'rate-key' => $route->getLabel('abuse-key', 'url:{url},ip:{ip}'),
|
||||
'scope' => $route->getLabel('scope', ''),
|
||||
'platforms' => $sdkPlatofrms,
|
||||
'platforms' => $sdkPlatforms,
|
||||
'packaging' => $route->getLabel('sdk.packaging', false),
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($this->models as $key => $value) {
|
||||
foreach ($this->models as $value) {
|
||||
if (\is_array($model)) {
|
||||
$model = \array_map(function ($m) use ($value) {
|
||||
if ($m === $value->getType()) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return $m;
|
||||
}, $model);
|
||||
$model = \array_map(fn ($m) => $m === $value->getType() ? $value : $m, $model);
|
||||
} else {
|
||||
if ($value->getType() === $model) {
|
||||
$model = $value;
|
||||
|
@ -168,9 +165,9 @@ class OpenAPI3 extends Format
|
|||
}
|
||||
}
|
||||
|
||||
if (!(\is_array($model)) && $model->isNone()) {
|
||||
if (!(\is_array($model)) && $model->isNone()) {
|
||||
$temp['responses'][(string)$route->getLabel('sdk.response.code', '500')] = [
|
||||
'description' => (in_array($produces, [
|
||||
'description' => in_array($produces, [
|
||||
'image/*',
|
||||
'image/jpeg',
|
||||
'image/gif',
|
||||
|
@ -179,16 +176,11 @@ class OpenAPI3 extends Format
|
|||
'image/svg-x',
|
||||
'image/x-icon',
|
||||
'image/bmp',
|
||||
])) ? 'Image' : 'File',
|
||||
// 'schema' => [
|
||||
// 'type' => 'file'
|
||||
// ],
|
||||
]) ? 'Image' : 'File',
|
||||
];
|
||||
} else {
|
||||
if (\is_array($model)) {
|
||||
$modelDescription = \join(', or ', \array_map(function ($m) {
|
||||
return $m->getName();
|
||||
}, $model));
|
||||
$modelDescription = \join(', or ', \array_map(fn ($m) => $m->getName(), $model));
|
||||
|
||||
// model has multiple possible responses, we will use oneOf
|
||||
foreach ($model as $m) {
|
||||
|
@ -200,9 +192,7 @@ class OpenAPI3 extends Format
|
|||
'content' => [
|
||||
$produces => [
|
||||
'schema' => [
|
||||
'oneOf' => \array_map(function ($m) {
|
||||
return ['$ref' => '#/components/schemas/' . $m->getType()];
|
||||
}, $model)
|
||||
'oneOf' => \array_map(fn ($m) => ['$ref' => '#/components/schemas/' . $m->getType()], $model)
|
||||
],
|
||||
],
|
||||
],
|
||||
|
@ -255,7 +245,10 @@ class OpenAPI3 extends Format
|
|||
$bodyRequired = [];
|
||||
|
||||
foreach ($route->getParams() as $name => $param) { // Set params
|
||||
$validator = (\is_callable($param['validator'])) ? call_user_func_array($param['validator'], $this->app->getResources($param['injections'])) : $param['validator']; /* @var $validator \Utopia\Validator */
|
||||
/**
|
||||
* @var \Utopia\Validator $validator
|
||||
*/
|
||||
$validator = (\is_callable($param['validator'])) ? call_user_func_array($param['validator'], $this->app->getResources($param['injections'])) : $param['validator'];
|
||||
|
||||
$node = [
|
||||
'name' => $name,
|
||||
|
@ -329,7 +322,8 @@ class OpenAPI3 extends Format
|
|||
$node['schema']['format'] = 'password';
|
||||
$node['schema']['x-example'] = 'password';
|
||||
break;
|
||||
case 'Utopia\Validator\Range': /** @var \Utopia\Validator\Range $validator */
|
||||
case 'Utopia\Validator\Range':
|
||||
/** @var \Utopia\Validator\Range $validator */
|
||||
$node['schema']['type'] = $validator->getType() === Validator::TYPE_FLOAT ? 'number' : $validator->getType();
|
||||
$node['schema']['format'] = $validator->getType() == Validator::TYPE_INTEGER ? 'int32' : 'float';
|
||||
$node['schema']['x-example'] = $validator->getMin();
|
||||
|
@ -351,7 +345,8 @@ class OpenAPI3 extends Format
|
|||
$node['schema']['format'] = 'url';
|
||||
$node['schema']['x-example'] = 'https://example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\WhiteList': /** @var \Utopia\Validator\WhiteList $validator */
|
||||
case 'Utopia\Validator\WhiteList':
|
||||
/** @var \Utopia\Validator\WhiteList $validator */
|
||||
$node['schema']['type'] = $validator->getType();
|
||||
$node['schema']['x-example'] = $validator->getList()[0];
|
||||
|
||||
|
@ -413,20 +408,11 @@ class OpenAPI3 extends Format
|
|||
$temp['requestBody'] = $body;
|
||||
}
|
||||
|
||||
//$temp['consumes'] = $consumes;
|
||||
|
||||
$output['paths'][$url][\strtolower($route->getMethod())] = $temp;
|
||||
}
|
||||
|
||||
foreach ($this->models as $model) {
|
||||
foreach ($model->getRules() as $rule) {
|
||||
if (
|
||||
in_array($model->getType(), $usedModels)
|
||||
&& !in_array($rule['type'], ['string', 'integer', 'boolean', 'json', 'float'])
|
||||
) {
|
||||
$usedModels[] = $rule['type'];
|
||||
}
|
||||
}
|
||||
$this->getNestedModels($model, $usedModels);
|
||||
}
|
||||
|
||||
foreach ($this->models as $model) {
|
||||
|
|
|
@ -4,34 +4,39 @@ namespace Appwrite\Specification\Format;
|
|||
|
||||
use Appwrite\Specification\Format;
|
||||
use Appwrite\Template\Template;
|
||||
use Appwrite\Utopia\Response\Model;
|
||||
use Utopia\Validator;
|
||||
|
||||
class Swagger2 extends Format
|
||||
{
|
||||
/**
|
||||
* Get Name.
|
||||
*
|
||||
* Get format name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'Swagger 2';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse
|
||||
*
|
||||
* Parses Appwrite App to given format
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getNestedModels(Model $model, array &$usedModels): void
|
||||
{
|
||||
foreach ($model->getRules() as $rule) {
|
||||
if (
|
||||
in_array($model->getType(), $usedModels)
|
||||
&& !in_array($rule['type'], ['string', 'integer', 'boolean', 'json', 'float', 'double'])
|
||||
) {
|
||||
$usedModels[] = $rule['type'];
|
||||
foreach ($this->models as $m) {
|
||||
if ($m->getType() === $rule['type']) {
|
||||
$this->getNestedModels($m, $usedModels);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function parse(): array
|
||||
{
|
||||
/*
|
||||
* Specifications (v3.0.0):
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md
|
||||
* Specifications (v2.0):
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md
|
||||
*/
|
||||
$output = [
|
||||
'swagger' => '2.0',
|
||||
|
@ -87,7 +92,8 @@ class Swagger2 extends Format
|
|||
|
||||
$usedModels = [];
|
||||
|
||||
foreach ($this->routes as $route) { /** @var \Utopia\Route $route */
|
||||
foreach ($this->routes as $route) {
|
||||
/** @var \Utopia\Route $route */
|
||||
$url = \str_replace('/v1', '', $route->getPath());
|
||||
$scope = $route->getLabel('scope', '');
|
||||
$hide = $route->getLabel('sdk.hide', false);
|
||||
|
@ -102,27 +108,27 @@ class Swagger2 extends Format
|
|||
$produces = $route->getLabel('sdk.response.type', null);
|
||||
$model = $route->getLabel('sdk.response.model', 'none');
|
||||
$routeSecurity = $route->getLabel('sdk.auth', []);
|
||||
$sdkPlatofrms = [];
|
||||
$sdkPlatforms = [];
|
||||
|
||||
foreach ($routeSecurity as $value) {
|
||||
switch ($value) {
|
||||
case APP_AUTH_TYPE_SESSION:
|
||||
$sdkPlatofrms[] = APP_PLATFORM_CLIENT;
|
||||
$sdkPlatforms[] = APP_PLATFORM_CLIENT;
|
||||
break;
|
||||
case APP_AUTH_TYPE_KEY:
|
||||
$sdkPlatofrms[] = APP_PLATFORM_SERVER;
|
||||
$sdkPlatforms[] = APP_PLATFORM_SERVER;
|
||||
break;
|
||||
case APP_AUTH_TYPE_JWT:
|
||||
$sdkPlatofrms[] = APP_PLATFORM_SERVER;
|
||||
$sdkPlatforms[] = APP_PLATFORM_SERVER;
|
||||
break;
|
||||
case APP_AUTH_TYPE_ADMIN:
|
||||
$sdkPlatofrms[] = APP_PLATFORM_CONSOLE;
|
||||
$sdkPlatforms[] = APP_PLATFORM_CONSOLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($routeSecurity)) {
|
||||
$sdkPlatofrms[] = APP_PLATFORM_CLIENT;
|
||||
$sdkPlatforms[] = APP_PLATFORM_CLIENT;
|
||||
}
|
||||
|
||||
$temp = [
|
||||
|
@ -144,7 +150,7 @@ class Swagger2 extends Format
|
|||
'rate-time' => $route->getLabel('abuse-time', 3600),
|
||||
'rate-key' => $route->getLabel('abuse-key', 'url:{url},ip:{ip}'),
|
||||
'scope' => $route->getLabel('scope', ''),
|
||||
'platforms' => $sdkPlatofrms,
|
||||
'platforms' => $sdkPlatforms,
|
||||
'packaging' => $route->getLabel('sdk.packaging', false),
|
||||
],
|
||||
];
|
||||
|
@ -153,14 +159,9 @@ class Swagger2 extends Format
|
|||
$temp['produces'][] = $produces;
|
||||
}
|
||||
|
||||
foreach ($this->models as $key => $value) {
|
||||
foreach ($this->models as $value) {
|
||||
if (\is_array($model)) {
|
||||
$model = \array_map(function ($m) use ($value) {
|
||||
if ($m === $value->getType()) {
|
||||
return $value;
|
||||
}
|
||||
return $m;
|
||||
}, $model);
|
||||
$model = \array_map(fn ($m) => $m === $value->getType() ? $value : $m, $model);
|
||||
} else {
|
||||
if ($value->getType() === $model) {
|
||||
$model = $value;
|
||||
|
@ -171,7 +172,7 @@ class Swagger2 extends Format
|
|||
|
||||
if (!(\is_array($model)) && $model->isNone()) {
|
||||
$temp['responses'][(string)$route->getLabel('sdk.response.code', '500')] = [
|
||||
'description' => (in_array($produces, [
|
||||
'description' => in_array($produces, [
|
||||
'image/*',
|
||||
'image/jpeg',
|
||||
'image/gif',
|
||||
|
@ -180,16 +181,14 @@ class Swagger2 extends Format
|
|||
'image/svg-x',
|
||||
'image/x-icon',
|
||||
'image/bmp',
|
||||
])) ? 'Image' : 'File',
|
||||
]) ? 'Image' : 'File',
|
||||
'schema' => [
|
||||
'type' => 'file'
|
||||
],
|
||||
];
|
||||
} else {
|
||||
if (\is_array($model)) {
|
||||
$modelDescription = \join(', or ', \array_map(function ($m) {
|
||||
return $m->getName();
|
||||
}, $model));
|
||||
$modelDescription = \join(', or ', \array_map(fn ($m) => $m->getName(), $model));
|
||||
// model has multiple possible responses, we will use oneOf
|
||||
foreach ($model as $m) {
|
||||
$usedModels[] = $m->getType();
|
||||
|
@ -244,7 +243,8 @@ class Swagger2 extends Format
|
|||
$bodyRequired = [];
|
||||
|
||||
foreach ($route->getParams() as $name => $param) { // Set params
|
||||
$validator = (\is_callable($param['validator'])) ? call_user_func_array($param['validator'], $this->app->getResources($param['injections'])) : $param['validator']; /** @var \Utopia\Validator $validator */
|
||||
/** @var \Utopia\Validator $validator */
|
||||
$validator = (\is_callable($param['validator'])) ? call_user_func_array($param['validator'], $this->app->getResources($param['injections'])) : $param['validator'];
|
||||
|
||||
$node = [
|
||||
'name' => $name,
|
||||
|
@ -294,7 +294,6 @@ class Swagger2 extends Format
|
|||
$node['type'] = 'object';
|
||||
$node['default'] = (empty($param['default'])) ? new \stdClass() : $param['default'];
|
||||
$node['x-example'] = '{}';
|
||||
//$node['format'] = 'json';
|
||||
break;
|
||||
case 'Utopia\Storage\Validator\File':
|
||||
$consumes = ['multipart/form-data'];
|
||||
|
@ -320,7 +319,8 @@ class Swagger2 extends Format
|
|||
$node['format'] = 'password';
|
||||
$node['x-example'] = 'password';
|
||||
break;
|
||||
case 'Utopia\Validator\Range': /** @var \Utopia\Validator\Range $validator */
|
||||
case 'Utopia\Validator\Range':
|
||||
/** @var \Utopia\Validator\Range $validator */
|
||||
$node['type'] = $validator->getType() === Validator::TYPE_FLOAT ? 'number' : $validator->getType();
|
||||
$node['format'] = $validator->getType() == Validator::TYPE_INTEGER ? 'int32' : 'float';
|
||||
$node['x-example'] = $validator->getMin();
|
||||
|
@ -342,7 +342,8 @@ class Swagger2 extends Format
|
|||
$node['format'] = 'url';
|
||||
$node['x-example'] = 'https://example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\WhiteList': /** @var \Utopia\Validator\WhiteList $validator */
|
||||
case 'Utopia\Validator\WhiteList':
|
||||
/** @var \Utopia\Validator\WhiteList $validator */
|
||||
$node['type'] = $validator->getType();
|
||||
$node['x-example'] = $validator->getList()[0];
|
||||
|
||||
|
@ -410,14 +411,7 @@ class Swagger2 extends Format
|
|||
}
|
||||
|
||||
foreach ($this->models as $model) {
|
||||
foreach ($model->getRules() as $rule) {
|
||||
if (
|
||||
in_array($model->getType(), $usedModels)
|
||||
&& !in_array($rule['type'], ['string', 'integer', 'boolean', 'json', 'float'])
|
||||
) {
|
||||
$usedModels[] = $rule['type'];
|
||||
}
|
||||
}
|
||||
$this->getNestedModels($model, $usedModels);
|
||||
}
|
||||
|
||||
foreach ($this->models as $model) {
|
||||
|
@ -485,15 +479,11 @@ class Swagger2 extends Format
|
|||
if (\is_array($rule['type'])) {
|
||||
if ($rule['array']) {
|
||||
$items = [
|
||||
'x-anyOf' => \array_map(function ($type) {
|
||||
return ['$ref' => '#/definitions/' . $type];
|
||||
}, $rule['type'])
|
||||
'x-anyOf' => \array_map(fn ($type) => ['$ref' => '#/definitions/' . $type], $rule['type'])
|
||||
];
|
||||
} else {
|
||||
$items = [
|
||||
'x-oneOf' => \array_map(function ($type) {
|
||||
return ['$ref' => '#/definitions/' . $type];
|
||||
}, $rule['type'])
|
||||
'x-oneOf' => \array_map(fn ($type) => ['$ref' => '#/definitions/' . $type], $rule['type'])
|
||||
];
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -4,14 +4,8 @@ namespace Appwrite\Specification;
|
|||
|
||||
class Specification
|
||||
{
|
||||
/**
|
||||
* @var Format
|
||||
*/
|
||||
protected $format;
|
||||
protected Format $format;
|
||||
|
||||
/**
|
||||
* @param Format $format
|
||||
*/
|
||||
public function __construct(Format $format)
|
||||
{
|
||||
$this->format = $format;
|
||||
|
|
Loading…
Reference in a new issue