mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Handle generating request model specs
This commit is contained in:
@@ -8,6 +8,7 @@ use Appwrite\SDK\Specification\Format\OpenAPI3;
|
||||
use Appwrite\SDK\Specification\Format\Swagger2;
|
||||
use Appwrite\SDK\Specification\Specification;
|
||||
use Appwrite\Utopia\Request as AppwriteRequest;
|
||||
use Appwrite\Utopia\Request\Model as RequestModel;
|
||||
use Appwrite\Utopia\Response as AppwriteResponse;
|
||||
use Exception;
|
||||
use Swoole\Http\Request as SwooleRequest;
|
||||
@@ -192,7 +193,8 @@ class Specs extends Action
|
||||
|
||||
foreach ($platforms as $platform) {
|
||||
$routes = [];
|
||||
$models = [];
|
||||
$requestModels = [];
|
||||
$responseModels = [];
|
||||
$services = [];
|
||||
|
||||
foreach ($appRoutes as $key => $method) {
|
||||
@@ -264,9 +266,9 @@ class Specs extends Action
|
||||
|
||||
foreach (Config::getParam('services', []) as $service) {
|
||||
if (
|
||||
!isset($service['docs']) // Skip service if not part of the public API
|
||||
|| !isset($service['sdk'])
|
||||
!isset($service['docs']) // Skip service if not part of the public API
|
||||
|| !$service['docs']
|
||||
|| !isset($service['sdk'])
|
||||
|| !$service['sdk']
|
||||
) {
|
||||
continue;
|
||||
@@ -278,11 +280,21 @@ class Specs extends Action
|
||||
];
|
||||
}
|
||||
|
||||
$models = $response->getModels();
|
||||
$responseModels = $response->getModels();
|
||||
|
||||
foreach ($models as $key => $value) {
|
||||
foreach ($responseModels as $key => $value) {
|
||||
if ($platform !== APP_PLATFORM_CONSOLE && !$value->isPublic()) {
|
||||
unset($models[$key]);
|
||||
unset($responseModels[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($routes as $route) {
|
||||
foreach ($route->getParams() as $param) {
|
||||
$model = $param['model'] ?? null;
|
||||
if ($model !== null && \class_exists($model)) {
|
||||
$instance = new $model();
|
||||
$requestModels[$instance->getType()] = $instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,10 +302,11 @@ class Specs extends Action
|
||||
new App('UTC'),
|
||||
$services,
|
||||
$routes,
|
||||
$models,
|
||||
$requestModels,
|
||||
$responseModels,
|
||||
$keys[$platform],
|
||||
$authCounts[$platform] ?? 0,
|
||||
$platforms[$platform]
|
||||
$platforms[$platform],
|
||||
];
|
||||
|
||||
foreach (['swagger2', 'open-api3'] as $format) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Appwrite\SDK\Specification;
|
||||
|
||||
use Appwrite\Utopia\Request\Model as RequestModel;
|
||||
use Appwrite\Utopia\Response\Model;
|
||||
use Utopia\App;
|
||||
use Utopia\Config\Config;
|
||||
@@ -9,22 +10,6 @@ use Utopia\Route;
|
||||
|
||||
abstract class Format
|
||||
{
|
||||
protected App $app;
|
||||
|
||||
/**
|
||||
* @var array<Route>
|
||||
*/
|
||||
protected array $routes;
|
||||
|
||||
/**
|
||||
* @var array<Model>
|
||||
*/
|
||||
protected array $models;
|
||||
|
||||
protected array $services;
|
||||
protected array $keys;
|
||||
protected int $authCount;
|
||||
protected string $platform;
|
||||
protected array $params = [
|
||||
'name' => '',
|
||||
'description' => '',
|
||||
@@ -51,15 +36,16 @@ abstract class Format
|
||||
]
|
||||
];
|
||||
|
||||
public function __construct(App $app, array $services, array $routes, array $models, array $keys, int $authCount, string $platform)
|
||||
{
|
||||
$this->app = $app;
|
||||
$this->services = $services;
|
||||
$this->routes = $routes;
|
||||
$this->models = $models;
|
||||
$this->keys = $keys;
|
||||
$this->authCount = $authCount;
|
||||
$this->platform = $platform;
|
||||
public function __construct(
|
||||
protected App $app,
|
||||
protected array $services,
|
||||
protected array $routes,
|
||||
protected array $requestModels,
|
||||
protected array $responseModels,
|
||||
protected array $keys,
|
||||
protected int $authCount,
|
||||
protected string $platform,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -740,7 +726,7 @@ abstract class Format
|
||||
foreach ($types as $ruleType) {
|
||||
if (!in_array($ruleType, ['string', 'integer', 'boolean', 'json', 'float'])) {
|
||||
$usedModels[] = $ruleType;
|
||||
foreach ($this->models as $m) {
|
||||
foreach ($this->responseModels as $m) {
|
||||
if ($m->getType() === $ruleType) {
|
||||
$this->getNestedModels($m, $usedModels);
|
||||
}
|
||||
@@ -749,4 +735,24 @@ abstract class Format
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function getNestedRequestModels(RequestModel $model, array &$usedModels): void
|
||||
{
|
||||
foreach ($model->getRules() as $rule) {
|
||||
if (!in_array($model->getType(), $usedModels)) {
|
||||
continue;
|
||||
}
|
||||
$types = (array)$rule['type'];
|
||||
foreach ($types as $ruleType) {
|
||||
if (!in_array($ruleType, ['string', 'integer', 'boolean', 'json', 'float', 'double', 'datetime', 'payload', 'array', 'enum'])) {
|
||||
$usedModels[] = $ruleType;
|
||||
foreach ($this->requestModels as $m) {
|
||||
if ($m->getType() === $ruleType) {
|
||||
$this->getNestedRequestModels($m, $usedModels);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ use Appwrite\SDK\Response;
|
||||
use Appwrite\SDK\Specification\Format;
|
||||
use Appwrite\Template\Template;
|
||||
use Appwrite\Utopia\Database\Validator\Operation;
|
||||
use Appwrite\Utopia\Request\Model as RequestModel;
|
||||
use Appwrite\Utopia\Response\Model;
|
||||
use Appwrite\Utopia\Response\Model\Any;
|
||||
use Utopia\Database\Database;
|
||||
@@ -91,6 +92,7 @@ class OpenAPI3 extends Format
|
||||
}
|
||||
|
||||
$usedModels = [];
|
||||
$usedRequestModels = [];
|
||||
|
||||
foreach ($this->routes as $route) {
|
||||
$url = \str_replace('/v1', '', $route->getPath());
|
||||
@@ -259,7 +261,7 @@ class OpenAPI3 extends Format
|
||||
|
||||
if (\is_array($responseModel)) {
|
||||
foreach ($responseModel as $modelName) {
|
||||
foreach ($this->models as $value) {
|
||||
foreach ($this->responseModels as $value) {
|
||||
if ($value->getType() === $modelName) {
|
||||
$usedModels[] = $modelName;
|
||||
break;
|
||||
@@ -278,7 +280,7 @@ class OpenAPI3 extends Format
|
||||
// lets not assume stuff here!
|
||||
if ($response->getCode() !== 204) {
|
||||
$responseData['model'] = '#/components/schemas/' . $responseModel;
|
||||
foreach ($this->models as $value) {
|
||||
foreach ($this->responseModels as $value) {
|
||||
if ($value->getType() === $responseModel) {
|
||||
$usedModels[] = $responseModel;
|
||||
break;
|
||||
@@ -299,7 +301,7 @@ class OpenAPI3 extends Format
|
||||
/** @var Response $response */
|
||||
$model = $response->getModel();
|
||||
|
||||
foreach ($this->models as $value) {
|
||||
foreach ($this->responseModels as $value) {
|
||||
if (\is_array($model)) {
|
||||
$model = \array_map(fn ($m) => $m === $value->getType() ? $value : $m, $model);
|
||||
} else {
|
||||
@@ -719,37 +721,50 @@ class OpenAPI3 extends Format
|
||||
$bodyRequired[] = $name;
|
||||
}
|
||||
|
||||
$body['content'][$consumes[0]]['schema']['properties'][$name] = [
|
||||
'type' => $node['schema']['type'],
|
||||
'description' => $node['description'],
|
||||
'x-example' => $node['schema']['x-example'] ?? null
|
||||
];
|
||||
$property = &$body['content'][$consumes[0]]['schema']['properties'][$name];
|
||||
$paramModel = $param['model'] ?? null;
|
||||
|
||||
if (isset($node['schema']['enum'])) {
|
||||
/// If the enum flag is Set, add the enum values to the body
|
||||
$body['content'][$consumes[0]]['schema']['properties'][$name]['enum'] = $node['schema']['enum'];
|
||||
$body['content'][$consumes[0]]['schema']['properties'][$name]['x-enum-name'] = $node['schema']['x-enum-name'] ?? null;
|
||||
$body['content'][$consumes[0]]['schema']['properties'][$name]['x-enum-keys'] = $node['schema']['x-enum-keys'] ?? null;
|
||||
}
|
||||
if ($paramModel !== null && \class_exists($paramModel)) {
|
||||
/** @var RequestModel $requestModelInstance */
|
||||
$requestModelInstance = new $paramModel();
|
||||
$requestModelType = $requestModelInstance->getType();
|
||||
$usedRequestModels[] = $requestModelType;
|
||||
|
||||
if ($node['schema']['x-upload-id'] ?? false) {
|
||||
$body['content'][$consumes[0]]['schema']['properties'][$name]['x-upload-id'] = $node['schema']['x-upload-id'];
|
||||
}
|
||||
$property = $array
|
||||
? ['type' => 'array', 'description' => $node['description'], 'items' => ['$ref' => '#/components/schemas/' . $requestModelType]]
|
||||
: ['$ref' => '#/components/schemas/' . $requestModelType];
|
||||
} else {
|
||||
$property = [
|
||||
'type' => $node['schema']['type'],
|
||||
'description' => $node['description'],
|
||||
'x-example' => $node['schema']['x-example'] ?? null
|
||||
];
|
||||
|
||||
if (isset($node['default'])) {
|
||||
$body['content'][$consumes[0]]['schema']['properties'][$name]['default'] = $node['default'];
|
||||
}
|
||||
if (isset($node['schema']['enum'])) {
|
||||
$property['enum'] = $node['schema']['enum'];
|
||||
$property['x-enum-name'] = $node['schema']['x-enum-name'] ?? null;
|
||||
$property['x-enum-keys'] = $node['schema']['x-enum-keys'] ?? null;
|
||||
}
|
||||
|
||||
if (\array_key_exists('items', $node['schema'])) {
|
||||
$body['content'][$consumes[0]]['schema']['properties'][$name]['items'] = $node['schema']['items'];
|
||||
}
|
||||
if ($node['schema']['x-upload-id'] ?? false) {
|
||||
$property['x-upload-id'] = $node['schema']['x-upload-id'];
|
||||
}
|
||||
|
||||
if ($node['x-global'] ?? false) {
|
||||
$body['content'][$consumes[0]]['schema']['properties'][$name]['x-global'] = true;
|
||||
if (isset($node['default'])) {
|
||||
$property['default'] = $node['default'];
|
||||
}
|
||||
|
||||
if (\array_key_exists('items', $node['schema'])) {
|
||||
$property['items'] = $node['schema']['items'];
|
||||
}
|
||||
|
||||
if ($node['x-global'] ?? false) {
|
||||
$property['x-global'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($isNullable) {
|
||||
$body['content'][$consumes[0]]['schema']['properties'][$name]['x-nullable'] = true;
|
||||
$property['nullable'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -767,11 +782,11 @@ class OpenAPI3 extends Format
|
||||
$output['paths'][$url][\strtolower($route->getMethod())] = $temp;
|
||||
}
|
||||
|
||||
foreach ($this->models as $model) {
|
||||
foreach ($this->responseModels as $model) {
|
||||
$this->getNestedModels($model, $usedModels);
|
||||
}
|
||||
|
||||
foreach ($this->models as $model) {
|
||||
foreach ($this->responseModels as $model) {
|
||||
if (!in_array($model->getType(), $usedModels) && $model->getType() !== 'error') {
|
||||
continue;
|
||||
}
|
||||
@@ -931,6 +946,86 @@ class OpenAPI3 extends Format
|
||||
$output['components']['schemas'][$model->getType()]['example'] = $examples;
|
||||
}
|
||||
|
||||
// Generate request model schemas
|
||||
foreach ($this->requestModels as $model) {
|
||||
$this->getNestedRequestModels($model, $usedRequestModels);
|
||||
}
|
||||
|
||||
foreach ($this->requestModels as $model) {
|
||||
if (!in_array($model->getType(), $usedRequestModels)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$required = $model->getRequired();
|
||||
$rules = $model->getRules();
|
||||
|
||||
$output['components']['schemas'][$model->getType()] = [
|
||||
'description' => $model->getName(),
|
||||
'type' => 'object',
|
||||
];
|
||||
|
||||
if (!empty($rules)) {
|
||||
$output['components']['schemas'][$model->getType()]['properties'] = [];
|
||||
}
|
||||
|
||||
if (!empty($required)) {
|
||||
$output['components']['schemas'][$model->getType()]['required'] = $required;
|
||||
}
|
||||
|
||||
foreach ($rules as $name => $rule) {
|
||||
$ruleType = $rule['type'];
|
||||
$isArray = $rule['array'] ?? false;
|
||||
|
||||
[$type, $format] = match ($ruleType) {
|
||||
'string', 'datetime', 'payload' => ['string', null],
|
||||
'enum' => ['string', null],
|
||||
'json' => ['object', null],
|
||||
'array' => ['array', null],
|
||||
'integer' => ['integer', 'int32'],
|
||||
'float' => ['number', 'float'],
|
||||
'double' => ['number', 'double'],
|
||||
'boolean' => ['boolean', null],
|
||||
default => ['object', null],
|
||||
};
|
||||
|
||||
$property = &$output['components']['schemas'][$model->getType()]['properties'][$name];
|
||||
$property = ['type' => $isArray ? 'array' : $type, 'description' => $rule['description'] ?? '', 'x-example' => $rule['example'] ?? null];
|
||||
|
||||
if ($ruleType === 'json') {
|
||||
$property['additionalProperties'] = true;
|
||||
}
|
||||
|
||||
if ($isArray) {
|
||||
$property['items'] = ['type' => $type];
|
||||
if ($format) {
|
||||
$property['items']['format'] = $format;
|
||||
}
|
||||
} elseif ($format) {
|
||||
$property['format'] = $format;
|
||||
}
|
||||
|
||||
// Handle nested model references
|
||||
if ($type === 'object' && $ruleType && $ruleType !== 'json') {
|
||||
$refKey = $isArray ? 'anyOf' : 'oneOf';
|
||||
$property['items'] = \is_array($ruleType)
|
||||
? [$refKey => \array_map(fn ($t) => ['$ref' => '#/components/schemas/' . $t], $ruleType)]
|
||||
: ['$ref' => '#/components/schemas/' . $ruleType];
|
||||
}
|
||||
|
||||
if ($ruleType === 'enum' && !empty($rule['enum'])) {
|
||||
$target = $isArray ? $property['items'] : $property;
|
||||
$target['enum'] = \array_values($rule['enum']);
|
||||
$isArray ? $property['items'] = $target : $property = $target;
|
||||
}
|
||||
|
||||
if (!in_array($name, $required)) {
|
||||
$property['nullable'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$output['components']['schemas'][$model->getType()]['example'] = \array_map(fn ($r) => $r['example'] ?? null, $rules);
|
||||
}
|
||||
|
||||
\ksort($output['paths']);
|
||||
|
||||
return $output;
|
||||
|
||||
@@ -9,6 +9,7 @@ use Appwrite\SDK\Response;
|
||||
use Appwrite\SDK\Specification\Format;
|
||||
use Appwrite\Template\Template;
|
||||
use Appwrite\Utopia\Database\Validator\Operation;
|
||||
use Appwrite\Utopia\Request\Model as RequestModel;
|
||||
use Appwrite\Utopia\Response\Model;
|
||||
use Appwrite\Utopia\Response\Model\Any;
|
||||
use Utopia\Database\Database;
|
||||
@@ -88,6 +89,7 @@ class Swagger2 extends Format
|
||||
}
|
||||
|
||||
$usedModels = [];
|
||||
$usedRequestModels = [];
|
||||
|
||||
foreach ($this->routes as $route) {
|
||||
/** @var Route $route */
|
||||
@@ -267,7 +269,7 @@ class Swagger2 extends Format
|
||||
$responseModel = $response->getModel();
|
||||
if (\is_array($responseModel)) {
|
||||
foreach ($responseModel as $modelName) {
|
||||
foreach ($this->models as $value) {
|
||||
foreach ($this->responseModels as $value) {
|
||||
if ($value->getType() === $modelName) {
|
||||
$usedModels[] = $modelName;
|
||||
break;
|
||||
@@ -286,7 +288,7 @@ class Swagger2 extends Format
|
||||
// lets not assume stuff here!
|
||||
if ($response->getCode() !== 204) {
|
||||
$responseData['model'] = '#/definitions/' . $responseModel;
|
||||
foreach ($this->models as $value) {
|
||||
foreach ($this->responseModels as $value) {
|
||||
if ($value->getType() === $responseModel) {
|
||||
$usedModels[] = $responseModel;
|
||||
break;
|
||||
@@ -307,7 +309,7 @@ class Swagger2 extends Format
|
||||
/** @var Response $response */
|
||||
$model = $response->getModel();
|
||||
|
||||
foreach ($this->models as $value) {
|
||||
foreach ($this->responseModels as $value) {
|
||||
if (\is_array($model)) {
|
||||
$model = \array_map(fn ($m) => $m === $value->getType() ? $value : $m, $model);
|
||||
} else {
|
||||
@@ -707,30 +709,43 @@ class Swagger2 extends Format
|
||||
$bodyRequired[] = $name;
|
||||
}
|
||||
|
||||
$body['schema']['properties'][$name] = [
|
||||
'type' => $node['type'],
|
||||
'description' => $node['description'],
|
||||
'default' => $node['default'] ?? null,
|
||||
'x-example' => $node['x-example'] ?? null,
|
||||
];
|
||||
$property = &$body['schema']['properties'][$name];
|
||||
$paramModel = $param['model'] ?? null;
|
||||
|
||||
if (isset($node['enum'])) {
|
||||
/// If the enum flag is Set, add the enum values to the body
|
||||
$body['schema']['properties'][$name]['enum'] = $node['enum'];
|
||||
$body['schema']['properties'][$name]['x-enum-name'] = $node['x-enum-name'] ?? null;
|
||||
$body['schema']['properties'][$name]['x-enum-keys'] = $node['x-enum-keys'] ?? null;
|
||||
}
|
||||
if ($paramModel !== null && \class_exists($paramModel)) {
|
||||
/** @var RequestModel $requestModelInstance */
|
||||
$requestModelInstance = new $paramModel();
|
||||
$requestModelType = $requestModelInstance->getType();
|
||||
$usedRequestModels[] = $requestModelType;
|
||||
|
||||
if ($node['x-global'] ?? false) {
|
||||
$body['schema']['properties'][$name]['x-global'] = true;
|
||||
$property = $array
|
||||
? ['type' => 'array', 'description' => $node['description'], 'items' => ['$ref' => '#/definitions/' . $requestModelType]]
|
||||
: ['$ref' => '#/definitions/' . $requestModelType];
|
||||
} else {
|
||||
$property = [
|
||||
'type' => $node['type'],
|
||||
'description' => $node['description'],
|
||||
'default' => $node['default'] ?? null,
|
||||
'x-example' => $node['x-example'] ?? null,
|
||||
];
|
||||
|
||||
if (isset($node['enum'])) {
|
||||
$property['enum'] = $node['enum'];
|
||||
$property['x-enum-name'] = $node['x-enum-name'] ?? null;
|
||||
$property['x-enum-keys'] = $node['x-enum-keys'] ?? null;
|
||||
}
|
||||
|
||||
if ($node['x-global'] ?? false) {
|
||||
$property['x-global'] = true;
|
||||
}
|
||||
|
||||
if (\array_key_exists('items', $node)) {
|
||||
$property['items'] = $node['items'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($isNullable) {
|
||||
$body['schema']['properties'][$name]['x-nullable'] = true;
|
||||
}
|
||||
|
||||
if (\array_key_exists('items', $node)) {
|
||||
$body['schema']['properties'][$name]['items'] = $node['items'];
|
||||
$property['x-nullable'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -750,11 +765,11 @@ class Swagger2 extends Format
|
||||
$output['paths'][$url][\strtolower($route->getMethod())] = $temp;
|
||||
}
|
||||
|
||||
foreach ($this->models as $model) {
|
||||
foreach ($this->responseModels as $model) {
|
||||
$this->getNestedModels($model, $usedModels);
|
||||
}
|
||||
|
||||
foreach ($this->models as $model) {
|
||||
foreach ($this->responseModels as $model) {
|
||||
if (!in_array($model->getType(), $usedModels)) {
|
||||
continue;
|
||||
}
|
||||
@@ -927,6 +942,89 @@ class Swagger2 extends Format
|
||||
$output['definitions'][$model->getType()]['example'] = $examples;
|
||||
}
|
||||
|
||||
// Generate request model definitions
|
||||
foreach ($this->requestModels as $model) {
|
||||
$this->getNestedRequestModels($model, $usedRequestModels);
|
||||
}
|
||||
|
||||
foreach ($this->requestModels as $model) {
|
||||
if (!in_array($model->getType(), $usedRequestModels)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$required = $model->getRequired();
|
||||
$rules = $model->getRules();
|
||||
|
||||
$output['definitions'][$model->getType()] = [
|
||||
'description' => $model->getName(),
|
||||
'type' => 'object',
|
||||
];
|
||||
|
||||
if (!empty($rules)) {
|
||||
$output['definitions'][$model->getType()]['properties'] = [];
|
||||
}
|
||||
|
||||
if (!empty($required)) {
|
||||
$output['definitions'][$model->getType()]['required'] = $required;
|
||||
}
|
||||
|
||||
foreach ($rules as $name => $rule) {
|
||||
$ruleType = $rule['type'];
|
||||
$isArray = $rule['array'] ?? false;
|
||||
|
||||
[$type, $format] = match ($ruleType) {
|
||||
'string', 'datetime' => ['string', null],
|
||||
'enum' => ['string', null],
|
||||
'json' => ['object', null],
|
||||
'array' => ['array', null],
|
||||
'integer' => ['integer', 'int32'],
|
||||
'float' => ['number', 'float'],
|
||||
'double' => ['number', 'double'],
|
||||
'boolean' => ['boolean', null],
|
||||
'payload' => ['payload', null],
|
||||
default => ['object', null],
|
||||
};
|
||||
|
||||
$property = &$output['definitions'][$model->getType()]['properties'][$name];
|
||||
|
||||
if ($ruleType === 'json') {
|
||||
$property = ['type' => $type, 'additionalProperties' => true, 'description' => $rule['description'] ?? '', 'x-example' => $rule['example'] ?? null];
|
||||
continue;
|
||||
}
|
||||
|
||||
$property = ['type' => $isArray ? 'array' : $type, 'description' => $rule['description'] ?? '', 'x-example' => $rule['example'] ?? null];
|
||||
|
||||
if ($isArray) {
|
||||
$property['items'] = ['type' => $type];
|
||||
if ($format) {
|
||||
$property['items']['format'] = $format;
|
||||
}
|
||||
} elseif ($format) {
|
||||
$property['format'] = $format;
|
||||
}
|
||||
|
||||
// Handle nested model references
|
||||
if ($type === 'object' && $ruleType && $ruleType !== 'json') {
|
||||
$refKey = $isArray ? 'x-anyOf' : 'x-oneOf';
|
||||
$property['items'] = \is_array($ruleType)
|
||||
? [$refKey => \array_map(fn ($t) => ['$ref' => '#/definitions/' . $t], $ruleType)]
|
||||
: ['type' => 'object', '$ref' => '#/definitions/' . $ruleType];
|
||||
}
|
||||
|
||||
if ($ruleType === 'enum' && !empty($rule['enum'])) {
|
||||
$target = $isArray ? $property['items'] : $property;
|
||||
$target['enum'] = \array_values($rule['enum']);
|
||||
$isArray ? $property['items'] = $target : $property = $target;
|
||||
}
|
||||
|
||||
if (!in_array($name, $required)) {
|
||||
$property['x-nullable'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$output['definitions'][$model->getType()]['example'] = \array_map(fn ($r) => $r['example'] ?? null, $rules);
|
||||
}
|
||||
|
||||
\ksort($output['paths']);
|
||||
|
||||
return $output;
|
||||
|
||||
@@ -9,11 +9,8 @@ abstract class Model
|
||||
public const TYPE_FLOAT = 'double';
|
||||
public const TYPE_BOOLEAN = 'boolean';
|
||||
public const TYPE_JSON = 'json';
|
||||
public const TYPE_MODEL = 'json';
|
||||
public const TYPE_DATETIME = 'datetime';
|
||||
public const TYPE_DATETIME_EXAMPLE = '2020-10-15T06:38:00.000+00:00';
|
||||
public const TYPE_RELATIONSHIP = 'relationship';
|
||||
public const TYPE_PAYLOAD = 'payload';
|
||||
public const TYPE_ARRAY = 'array';
|
||||
public const TYPE_ENUM = 'enum';
|
||||
|
||||
@@ -22,11 +19,6 @@ abstract class Model
|
||||
*/
|
||||
protected array $rules = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public array $conditions = [];
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
@@ -95,13 +87,11 @@ abstract class Model
|
||||
public function getRequired(): array
|
||||
{
|
||||
$list = [];
|
||||
|
||||
foreach ($this->rules as $key => $rule) {
|
||||
if ($rule['required'] ?? false) {
|
||||
$list[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user