welcome back to dyb-tech
This commit is contained in:
@@ -0,0 +1,795 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Context;
|
||||
use OpenApi\Generator;
|
||||
use OpenApi\Annotations as OA;
|
||||
use OpenApi\Util;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
/**
|
||||
* The openapi annotation base class.
|
||||
*/
|
||||
abstract class AbstractAnnotation implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* While the OpenAPI Specification tries to accommodate most use cases, additional data can be added to extend the specification at certain points.
|
||||
* For further details see https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specificationExtensions
|
||||
* The keys inside the array will be prefixed with `x-`.
|
||||
*
|
||||
* @var array<string,mixed>
|
||||
*/
|
||||
public $x = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Arbitrary attachables for this annotation.
|
||||
* These will be ignored but can be used for custom processing.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $attachables = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @var Context|null
|
||||
*/
|
||||
public $_context = null;
|
||||
|
||||
/**
|
||||
* Annotations that couldn't be merged by mapping or postprocessing.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $_unmerged = [];
|
||||
|
||||
/**
|
||||
* The properties which are required by [the spec](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md).
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $_required = [];
|
||||
|
||||
/**
|
||||
* Specify the type of the property.
|
||||
*
|
||||
* Examples:
|
||||
* 'name' => 'string' // a string
|
||||
* 'required' => 'boolean', // true or false
|
||||
* 'tags' => '[string]', // array containing strings
|
||||
* 'in' => ["query", "header", "path", "formData", "body"] // must be one on these
|
||||
* 'oneOf' => [Schema::class] // array of schema objects.
|
||||
*
|
||||
* @var array<string,string|array<string>>
|
||||
*/
|
||||
public static $_types = [];
|
||||
|
||||
/**
|
||||
* Declarative mapping of Annotation types to properties.
|
||||
* Examples:
|
||||
* Info::clas => 'info', // Set @OA\Info annotation as the info property.
|
||||
* Parameter::clas => ['parameters'], // Append @OA\Parameter annotations the parameters array.
|
||||
* PathItem::clas => ['paths', 'path'], // Append @OA\PathItem annotations the paths array and use path as key.
|
||||
*
|
||||
* @var array<class-string<AbstractAnnotation>,string|array<string>>
|
||||
*/
|
||||
public static $_nested = [];
|
||||
|
||||
/**
|
||||
* Reverse mapping of $_nested with the allowed parent annotations.
|
||||
*
|
||||
* @var array<class-string<AbstractAnnotation>>
|
||||
*/
|
||||
public static $_parents = [];
|
||||
|
||||
/**
|
||||
* List of properties are blacklisted from the JSON output.
|
||||
*
|
||||
* @var array<string>
|
||||
*/
|
||||
public static $_blacklist = ['_context', '_unmerged', '_analysis', 'attachables'];
|
||||
|
||||
public function __construct(array $properties)
|
||||
{
|
||||
if (isset($properties['_context'])) {
|
||||
$this->_context = $properties['_context'];
|
||||
unset($properties['_context']);
|
||||
} elseif (Generator::$context) {
|
||||
$this->_context = Generator::$context;
|
||||
} else {
|
||||
$this->_context = Context::detect(1);
|
||||
}
|
||||
|
||||
if ($this->_context->is('annotations') === false) {
|
||||
$this->_context->annotations = [];
|
||||
}
|
||||
|
||||
$this->_context->annotations[] = $this;
|
||||
$nestedContext = new Context(['nested' => $this], $this->_context);
|
||||
foreach ($properties as $property => $value) {
|
||||
if (property_exists($this, $property)) {
|
||||
$this->{$property} = $value;
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $key => $annotation) {
|
||||
if ($annotation instanceof AbstractAnnotation) {
|
||||
$this->{$property}[$key] = $this->nested($annotation, $nestedContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ($property !== 'value') {
|
||||
$this->{$property} = $value;
|
||||
} elseif (is_array($value)) {
|
||||
$annotations = [];
|
||||
foreach ($value as $annotation) {
|
||||
if ($annotation instanceof AbstractAnnotation) {
|
||||
$annotations[] = $annotation;
|
||||
} else {
|
||||
$this->_context->logger->warning('Unexpected field in ' . $this->identity() . ' in ' . $this->_context);
|
||||
}
|
||||
}
|
||||
$this->merge($annotations);
|
||||
} elseif (is_object($value)) {
|
||||
$this->merge([$value]);
|
||||
} else {
|
||||
if (!Generator::isDefault($value)) {
|
||||
$this->_context->logger->warning('Unexpected parameter "' . $property . '" in ' . $this->identity());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this instanceof OpenApi) {
|
||||
if ($this->_context->root()->version) {
|
||||
// override via `Generator::setVersion()`
|
||||
$this->openapi = $this->_context->root()->version;
|
||||
} else {
|
||||
$this->_context->root()->version = $this->openapi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __get(string $property)
|
||||
{
|
||||
$properties = get_object_vars($this);
|
||||
$this->_context->logger->warning('Property "' . $property . '" doesn\'t exist in a ' . $this->identity() . ', existing properties: "' . implode('", "', array_keys($properties)) . '" in ' . $this->_context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function __set(string $property, $value): void
|
||||
{
|
||||
$fields = get_object_vars($this);
|
||||
foreach (static::$_blacklist as $_property) {
|
||||
unset($fields[$_property]);
|
||||
}
|
||||
$this->_context->logger->warning('Ignoring unexpected property "' . $property . '" for ' . $this->identity() . ', expecting "' . implode('", "', array_keys($fields)) . '" in ' . $this->_context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge given annotations to their mapped properties configured in static::$_nested.
|
||||
*
|
||||
* Annotations that couldn't be merged are added to the _unmerged array.
|
||||
*
|
||||
* @param AbstractAnnotation[] $annotations
|
||||
* @param bool $ignore Ignore unmerged annotations
|
||||
*
|
||||
* @return AbstractAnnotation[] The unmerged annotations
|
||||
*/
|
||||
public function merge(array $annotations, bool $ignore = false): array
|
||||
{
|
||||
$unmerged = [];
|
||||
$nestedContext = new Context(['nested' => $this], $this->_context);
|
||||
|
||||
foreach ($annotations as $annotation) {
|
||||
$mapped = false;
|
||||
if ($details = $this->matchNested($annotation)) {
|
||||
$property = $details->value;
|
||||
if (is_array($property)) {
|
||||
$property = $property[0];
|
||||
if (Generator::isDefault($this->{$property})) {
|
||||
$this->{$property} = [];
|
||||
}
|
||||
$this->{$property}[] = $this->nested($annotation, $nestedContext);
|
||||
$mapped = true;
|
||||
} elseif (Generator::isDefault($this->{$property})) {
|
||||
// ignore duplicate nested if only one expected
|
||||
$this->{$property} = $this->nested($annotation, $nestedContext);
|
||||
$mapped = true;
|
||||
}
|
||||
}
|
||||
if (!$mapped) {
|
||||
$unmerged[] = $annotation;
|
||||
}
|
||||
}
|
||||
if (!$ignore) {
|
||||
foreach ($unmerged as $annotation) {
|
||||
$this->_unmerged[] = $this->nested($annotation, $nestedContext);
|
||||
}
|
||||
}
|
||||
|
||||
return $unmerged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the properties from the given object into this annotation.
|
||||
* Prevents overwriting properties that are already configured.
|
||||
*
|
||||
* @param object $object
|
||||
*/
|
||||
public function mergeProperties($object): void
|
||||
{
|
||||
$currentValues = get_object_vars($this);
|
||||
foreach ($object as $property => $value) {
|
||||
if ($property === '_context') {
|
||||
continue;
|
||||
}
|
||||
if (Generator::isDefault($currentValues[$property])) {
|
||||
// Overwrite default values
|
||||
$this->{$property} = $value;
|
||||
continue;
|
||||
}
|
||||
if ($property === '_unmerged') {
|
||||
$this->_unmerged = array_merge($this->_unmerged, $value);
|
||||
continue;
|
||||
}
|
||||
if ($currentValues[$property] !== $value) {
|
||||
// New value is not the same?
|
||||
if (Generator::isDefault($value)) {
|
||||
continue;
|
||||
}
|
||||
$identity = method_exists($object, 'identity') ? $object->identity() : get_class($object);
|
||||
$context1 = $this->_context;
|
||||
$context2 = property_exists($object, '_context') ? $object->_context : 'unknown';
|
||||
if (is_object($this->{$property}) && $this->{$property} instanceof AbstractAnnotation) {
|
||||
$context1 = $this->{$property}->_context;
|
||||
}
|
||||
$this->_context->logger->error('Multiple definitions for ' . $identity . '->' . $property . "\n Using: " . $context1 . "\n Skipping: " . $context2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the documentation in YAML format.
|
||||
*/
|
||||
public function toYaml(?int $flags = null): string
|
||||
{
|
||||
if ($flags === null) {
|
||||
$flags = Yaml::DUMP_OBJECT_AS_MAP ^ Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE;
|
||||
}
|
||||
|
||||
return Yaml::dump(json_decode($this->toJson(JSON_INVALID_UTF8_IGNORE)), 10, 2, $flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the documentation in JSON format.
|
||||
*/
|
||||
public function toJson(?int $flags = null): string
|
||||
{
|
||||
if ($flags === null) {
|
||||
$flags = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_IGNORE;
|
||||
}
|
||||
|
||||
return json_encode($this, $flags);
|
||||
}
|
||||
|
||||
public function __debugInfo()
|
||||
{
|
||||
$properties = [];
|
||||
foreach (get_object_vars($this) as $property => $value) {
|
||||
if (!Generator::isDefault($value)) {
|
||||
$properties[$property] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
$data = new \stdClass();
|
||||
|
||||
// Strip undefined values.
|
||||
foreach (get_object_vars($this) as $property => $value) {
|
||||
if (!Generator::isDefault($value)) {
|
||||
$data->{$property} = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Strip properties that are for internal (swagger-php) use.
|
||||
foreach (static::$_blacklist as $property) {
|
||||
unset($data->{$property});
|
||||
}
|
||||
|
||||
// Correct empty array to empty objects.
|
||||
foreach (static::$_types as $property => $type) {
|
||||
if ($type === 'object' && is_array($data->{$property}) && empty($data->{$property})) {
|
||||
$data->{$property} = new \stdClass();
|
||||
}
|
||||
}
|
||||
|
||||
// Inject vendor properties.
|
||||
unset($data->x);
|
||||
if (is_array($this->x)) {
|
||||
foreach ($this->x as $property => $value) {
|
||||
$prefixed = 'x-' . $property;
|
||||
$data->{$prefixed} = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Map nested keys
|
||||
foreach (static::$_nested as $nested) {
|
||||
if (is_string($nested) || count($nested) === 1) {
|
||||
continue;
|
||||
}
|
||||
$property = $nested[0];
|
||||
if (Generator::isDefault($this->{$property})) {
|
||||
continue;
|
||||
}
|
||||
$keyField = $nested[1];
|
||||
$object = new \stdClass();
|
||||
foreach ($this->{$property} as $key => $item) {
|
||||
if (is_numeric($key) === false && is_array($item)) {
|
||||
$object->{$key} = $item;
|
||||
} else {
|
||||
$key = $item->{$keyField};
|
||||
if (!Generator::isDefault($key) && empty($object->{$key})) {
|
||||
if ($item instanceof \JsonSerializable) {
|
||||
$object->{$key} = $item->jsonSerialize();
|
||||
} else {
|
||||
$object->{$key} = $item;
|
||||
}
|
||||
unset($object->{$key}->{$keyField});
|
||||
}
|
||||
}
|
||||
}
|
||||
$data->{$property} = $object;
|
||||
}
|
||||
|
||||
// $ref
|
||||
if (isset($data->ref)) {
|
||||
// Only specific https://github.com/OAI/OpenAPI-Specification/blob/3.1.0/versions/3.1.0.md#reference-object
|
||||
$ref = ['$ref' => $data->ref];
|
||||
if ($this->_context->version === OpenApi::VERSION_3_1_0) {
|
||||
foreach (['summary', 'description'] as $prop) {
|
||||
if (property_exists($this, $prop)) {
|
||||
if (!Generator::isDefault($this->{$prop})) {
|
||||
$ref[$prop] = $data->{$prop};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (property_exists($this, 'nullable') && $this->nullable === true) {
|
||||
$ref = ['oneOf' => [$ref]];
|
||||
if ($this->_context->version == OpenApi::VERSION_3_1_0) {
|
||||
$ref['oneOf'][] = ['type' => 'null'];
|
||||
} else {
|
||||
$ref['nullable'] = $data->nullable;
|
||||
}
|
||||
unset($data->nullable);
|
||||
|
||||
// preserve other properties
|
||||
foreach (get_object_vars($this) as $property => $value) {
|
||||
if ('_' == $property[0] || in_array($property, ['ref', 'nullable'])) {
|
||||
continue;
|
||||
}
|
||||
if (!Generator::isDefault($value)) {
|
||||
$ref[$property] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
$data = (object) $ref;
|
||||
}
|
||||
|
||||
if ($this->_context->version === OpenApi::VERSION_3_1_0) {
|
||||
if (isset($data->nullable)) {
|
||||
if (true === $data->nullable) {
|
||||
if (isset($data->oneOf)) {
|
||||
$data->oneOf[] = ['type' => 'null'];
|
||||
} elseif (isset($data->anyOf)) {
|
||||
$data->anyOf[] = ['type' => 'null'];
|
||||
} elseif (isset($data->allOf)) {
|
||||
$data->allOf[] = ['type' => 'null'];
|
||||
} else {
|
||||
$data->type = (array) $data->type;
|
||||
$data->type[] = 'null';
|
||||
}
|
||||
}
|
||||
unset($data->nullable);
|
||||
}
|
||||
|
||||
if (isset($data->minimum) && isset($data->exclusiveMinimum)) {
|
||||
if (true === $data->exclusiveMinimum) {
|
||||
$data->exclusiveMinimum = $data->minimum;
|
||||
unset($data->minimum);
|
||||
} elseif (false === $data->exclusiveMinimum) {
|
||||
unset($data->exclusiveMinimum);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($data->maximum) && isset($data->exclusiveMaximum)) {
|
||||
if (true === $data->exclusiveMaximum) {
|
||||
$data->exclusiveMaximum = $data->maximum;
|
||||
unset($data->maximum);
|
||||
} elseif (false === $data->exclusiveMaximum) {
|
||||
unset($data->exclusiveMaximum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate annotation tree, and log notices & warnings.
|
||||
*
|
||||
* @param array $stack the path of annotations above this annotation in the tree
|
||||
* @param array $skip (prevent stack overflow, when traversing an infinite dependency graph)
|
||||
* @param string $ref Current ref path?
|
||||
* @param object $context a free-form context contains
|
||||
*/
|
||||
public function validate(array $stack = [], array $skip = [], string $ref = '', $context = null): bool
|
||||
{
|
||||
if (in_array($this, $skip, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$valid = true;
|
||||
|
||||
// Report orphaned annotations
|
||||
foreach ($this->_unmerged as $annotation) {
|
||||
if (!is_object($annotation)) {
|
||||
$this->_context->logger->warning('Unexpected type: "' . gettype($annotation) . '" in ' . $this->identity() . '->_unmerged, expecting a Annotation object');
|
||||
break;
|
||||
}
|
||||
|
||||
/** @var class-string<AbstractAnnotation> $class */
|
||||
$class = get_class($annotation);
|
||||
if ($details = $this->matchNested($annotation)) {
|
||||
$property = $details->value;
|
||||
if (is_array($property)) {
|
||||
$this->_context->logger->warning('Only one ' . Util::shorten(get_class($annotation)) . '() allowed for ' . $this->identity() . ' multiple found, skipped: ' . $annotation->_context);
|
||||
} else {
|
||||
$this->_context->logger->warning('Only one ' . Util::shorten(get_class($annotation)) . '() allowed for ' . $this->identity() . " multiple found in:\n Using: " . $this->{$property}->_context . "\n Skipped: " . $annotation->_context);
|
||||
}
|
||||
} elseif ($annotation instanceof AbstractAnnotation) {
|
||||
$message = 'Unexpected ' . $annotation->identity();
|
||||
if ($class::$_parents) {
|
||||
$message .= ', expected to be inside ' . implode(', ', Util::shorten($class::$_parents));
|
||||
}
|
||||
$this->_context->logger->warning($message . ' in ' . $annotation->_context);
|
||||
}
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
// Report conflicting key
|
||||
foreach (static::$_nested as $annotationClass => $nested) {
|
||||
if (is_string($nested) || count($nested) === 1) {
|
||||
continue;
|
||||
}
|
||||
$property = $nested[0];
|
||||
if (Generator::isDefault($this->{$property})) {
|
||||
continue;
|
||||
}
|
||||
$keys = [];
|
||||
$keyField = $nested[1];
|
||||
foreach ($this->{$property} as $key => $item) {
|
||||
if (is_array($item) && is_numeric($key) === false) {
|
||||
$this->_context->logger->warning($this->identity() . '->' . $property . ' is an object literal, use nested ' . Util::shorten($annotationClass) . '() annotation(s) in ' . $this->_context);
|
||||
$keys[$key] = $item;
|
||||
} elseif (Generator::isDefault($item->{$keyField})) {
|
||||
$this->_context->logger->error($item->identity() . ' is missing key-field: "' . $keyField . '" in ' . $item->_context);
|
||||
} elseif (isset($keys[$item->{$keyField}])) {
|
||||
$this->_context->logger->error('Multiple ' . $item->_identity([]) . ' with the same ' . $keyField . '="' . $item->{$keyField} . "\":\n " . $item->_context . "\n " . $keys[$item->{$keyField}]->_context);
|
||||
} else {
|
||||
$keys[$item->{$keyField}] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (property_exists($this, 'ref') && !Generator::isDefault($this->ref) && is_string($this->ref)) {
|
||||
if (substr($this->ref, 0, 2) === '#/' && count($stack) > 0 && $stack[0] instanceof OpenApi) {
|
||||
// Internal reference
|
||||
try {
|
||||
$stack[0]->ref($this->ref);
|
||||
} catch (\Exception $e) {
|
||||
$this->_context->logger->warning($e->getMessage() . ' for ' . $this->identity() . ' in ' . $this->_context, ['exception' => $e]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Report missing required fields (when not a $ref)
|
||||
foreach (static::$_required as $property) {
|
||||
if (Generator::isDefault($this->{$property})) {
|
||||
$message = 'Missing required field "' . $property . '" for ' . $this->identity() . ' in ' . $this->_context;
|
||||
foreach (static::$_nested as $class => $nested) {
|
||||
$nestedProperty = is_array($nested) ? $nested[0] : $nested;
|
||||
if ($property === $nestedProperty) {
|
||||
if ($this instanceof OpenApi) {
|
||||
$message = 'Required ' . Util::shorten($class) . '() not found';
|
||||
} elseif (is_array($nested)) {
|
||||
$message = $this->identity() . ' requires at least one ' . Util::shorten($class) . '() in ' . $this->_context;
|
||||
} else {
|
||||
$message = $this->identity() . ' requires a ' . Util::shorten($class) . '() in ' . $this->_context;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->_context->logger->warning($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Report invalid types
|
||||
foreach (static::$_types as $property => $type) {
|
||||
$value = $this->{$property};
|
||||
if (Generator::isDefault($value) || $value === null) {
|
||||
continue;
|
||||
}
|
||||
if (is_string($type)) {
|
||||
if ($this->validateType($type, $value) === false) {
|
||||
$valid = false;
|
||||
$this->_context->logger->warning($this->identity() . '->' . $property . ' is a "' . gettype($value) . '", expecting a "' . $type . '" in ' . $this->_context);
|
||||
}
|
||||
} elseif (is_array($type)) { // enum?
|
||||
if (in_array($value, $type) === false) {
|
||||
$this->_context->logger->warning($this->identity() . '->' . $property . ' "' . $value . '" is invalid, expecting "' . implode('", "', $type) . '" in ' . $this->_context);
|
||||
}
|
||||
} else {
|
||||
throw new \Exception('Invalid ' . get_class($this) . '::$_types[' . $property . ']');
|
||||
}
|
||||
}
|
||||
$stack[] = $this;
|
||||
|
||||
return self::_validate($this, $stack, $skip, $ref, $context) ? $valid : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively validate all annotation properties.
|
||||
*
|
||||
* @param array|object $fields
|
||||
*/
|
||||
private static function _validate($fields, array $stack, array $skip, string $baseRef, ?object $context): bool
|
||||
{
|
||||
$valid = true;
|
||||
$blacklist = [];
|
||||
if (is_object($fields)) {
|
||||
if (in_array($fields, $skip, true)) {
|
||||
return true;
|
||||
}
|
||||
$skip[] = $fields;
|
||||
$blacklist = property_exists($fields, '_blacklist') ? $fields::$_blacklist : [];
|
||||
}
|
||||
|
||||
foreach ($fields as $field => $value) {
|
||||
if ($value === null || is_scalar($value) || in_array($field, $blacklist)) {
|
||||
continue;
|
||||
}
|
||||
$ref = $baseRef !== '' ? $baseRef . '/' . urlencode((string) $field) : urlencode((string) $field);
|
||||
if (is_object($value)) {
|
||||
if (method_exists($value, 'validate')) {
|
||||
if (!$value->validate($stack, $skip, $ref, $context)) {
|
||||
$valid = false;
|
||||
}
|
||||
} elseif (!self::_validate($value, $stack, $skip, $ref, $context)) {
|
||||
$valid = false;
|
||||
}
|
||||
} elseif (is_array($value) && !self::_validate($value, $stack, $skip, $ref, $context)) {
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a identity for easy debugging.
|
||||
* Example: "@OA\Get(path="/pets")".
|
||||
*/
|
||||
public function identity(): string
|
||||
{
|
||||
$class = get_class($this);
|
||||
$properties = [];
|
||||
/** @var class-string<AbstractAnnotation> $parent */
|
||||
foreach (static::$_parents as $parent) {
|
||||
foreach ($parent::$_nested as $annotationClass => $entry) {
|
||||
if ($annotationClass === $class && is_array($entry) && !Generator::isDefault($this->{$entry[1]})) {
|
||||
$properties[] = $entry[1];
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_identity($properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if `$other` can be nested and if so return details about where/how.
|
||||
*
|
||||
* @param AbstractAnnotation $other the other annotation
|
||||
*
|
||||
* @return null|object key/value object or `null`
|
||||
*/
|
||||
public function matchNested($other)
|
||||
{
|
||||
if ($other instanceof AbstractAnnotation && array_key_exists($root = $other->getRoot(), static::$_nested)) {
|
||||
return (object) ['key' => $root, 'value' => static::$_nested[$root]];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the root annotation.
|
||||
*
|
||||
* This is used for resolving type equality and nesting rules to allow those rules to also work for custom,
|
||||
* derived annotation classes.
|
||||
*
|
||||
* @return class-string the root annotation class in the `OpenApi\\Annotations` namespace
|
||||
*/
|
||||
public function getRoot(): string
|
||||
{
|
||||
$class = get_class($this);
|
||||
|
||||
do {
|
||||
if (0 === strpos($class, 'OpenApi\\Annotations\\')) {
|
||||
break;
|
||||
}
|
||||
} while ($class = get_parent_class($class));
|
||||
|
||||
return $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Match the annotation root.
|
||||
*
|
||||
* @param class-string $rootClass the root class to match
|
||||
*/
|
||||
public function isRoot(string $rootClass): bool
|
||||
{
|
||||
return $this->getRoot() == $rootClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for generating the identity().
|
||||
*/
|
||||
protected function _identity(array $properties): string
|
||||
{
|
||||
$fields = [];
|
||||
foreach ($properties as $property) {
|
||||
$value = $this->{$property};
|
||||
if ($value !== null && !Generator::isDefault($value)) {
|
||||
$fields[] = $property . '=' . (is_string($value) ? '"' . $value . '"' : $value);
|
||||
}
|
||||
}
|
||||
|
||||
return Util::shorten(get_class($this)) . '(' . implode(',', $fields) . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the matching of the property value to a annotation type.
|
||||
*
|
||||
* @param string $type The annotations property type
|
||||
* @param mixed $value The property value
|
||||
*/
|
||||
private function validateType(string $type, $value): bool
|
||||
{
|
||||
if (substr($type, 0, 1) === '[' && substr($type, -1) === ']') { // Array of a specified type?
|
||||
if ($this->validateType('array', $value) === false) {
|
||||
return false;
|
||||
}
|
||||
$itemType = substr($type, 1, -1);
|
||||
foreach ($value as $i => $item) {
|
||||
if ($this->validateType($itemType, $item) === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_subclass_of($type, AbstractAnnotation::class)) {
|
||||
$type = 'object';
|
||||
}
|
||||
|
||||
return $this->validateDefaultTypes($type, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates default Open Api types.
|
||||
*
|
||||
* @param string $type The property type
|
||||
* @param mixed $value The value to validate
|
||||
*/
|
||||
private function validateDefaultTypes(string $type, $value): bool
|
||||
{
|
||||
if (str_contains($type, '|')) {
|
||||
$types = explode('|', $type);
|
||||
foreach ($types as $type) {
|
||||
if ($this->validateDefaultTypes($type, $value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'string':
|
||||
return is_string($value);
|
||||
case 'boolean':
|
||||
return is_bool($value);
|
||||
case 'integer':
|
||||
return is_int($value);
|
||||
case 'number':
|
||||
return is_numeric($value);
|
||||
case 'object':
|
||||
return is_object($value);
|
||||
case 'array':
|
||||
return $this->validateArrayType($value);
|
||||
case 'scheme':
|
||||
return in_array($value, ['http', 'https', 'ws', 'wss'], true);
|
||||
default:
|
||||
throw new \Exception('Invalid type "' . $type . '"');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate array type.
|
||||
*
|
||||
* @param mixed $value
|
||||
*/
|
||||
private function validateArrayType($value): bool
|
||||
{
|
||||
if (is_array($value) === false) {
|
||||
return false;
|
||||
}
|
||||
$count = 0;
|
||||
foreach ($value as $i => $item) {
|
||||
// not a array, but a hash/map
|
||||
if ($count !== $i) {
|
||||
return false;
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the context with a reference to the annotation it is nested in.
|
||||
*
|
||||
* @param AbstractAnnotation $annotation
|
||||
*
|
||||
* @return AbstractAnnotation
|
||||
*/
|
||||
protected function nested(AbstractAnnotation $annotation, Context $nestedContext)
|
||||
{
|
||||
if (property_exists($annotation, '_context') && $annotation->_context === $this->_context) {
|
||||
$annotation->_context = $nestedContext;
|
||||
}
|
||||
|
||||
return $annotation;
|
||||
}
|
||||
|
||||
protected function combine(...$args): array
|
||||
{
|
||||
$combined = [];
|
||||
foreach ($args as $arg) {
|
||||
if (is_array($arg)) {
|
||||
$combined = array_merge($combined, $arg);
|
||||
} else {
|
||||
$combined[] = $arg;
|
||||
}
|
||||
}
|
||||
|
||||
return array_filter($combined, function ($value) {
|
||||
return !Generator::isDefault($value) && $value !== null;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*/
|
||||
class AdditionalProperties extends Schema
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
Schema::class,
|
||||
Property::class,
|
||||
Items::class,
|
||||
JsonContent::class,
|
||||
XmlContent::class,
|
||||
AdditionalProperties::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Discriminator::class => 'discriminator',
|
||||
Items::class => 'items',
|
||||
Property::class => ['properties', 'property'],
|
||||
ExternalDocumentation::class => 'externalDocs',
|
||||
Xml::class => 'xml',
|
||||
AdditionalProperties::class => 'additionalProperties',
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
/**
|
||||
* A container for custom data to be attached to an annotation.
|
||||
*
|
||||
* These will be ignored by `swagger-php` but can be used for custom processing.
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class Attachable extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
AdditionalProperties::class,
|
||||
Components::class,
|
||||
Contact::class,
|
||||
Delete::class,
|
||||
Discriminator::class,
|
||||
Examples::class,
|
||||
ExternalDocumentation::class,
|
||||
Flow::class,
|
||||
Get::class,
|
||||
Head::class,
|
||||
Header::class,
|
||||
Info::class,
|
||||
Items::class,
|
||||
JsonContent::class,
|
||||
License::class,
|
||||
Link::class,
|
||||
MediaType::class,
|
||||
OpenApi::class,
|
||||
Operation::class,
|
||||
Options::class,
|
||||
Parameter::class,
|
||||
Patch::class,
|
||||
PathItem::class,
|
||||
PathParameter::class,
|
||||
Post::class,
|
||||
Property::class,
|
||||
Put::class,
|
||||
RequestBody::class,
|
||||
Response::class,
|
||||
Schema::class,
|
||||
SecurityScheme::class,
|
||||
Server::class,
|
||||
ServerVariable::class,
|
||||
Tag::class,
|
||||
Trace::class,
|
||||
Webhook::class,
|
||||
Xml::class,
|
||||
XmlContent::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Allows to type-hint a specific parent annotation class.
|
||||
*
|
||||
* Container to allow custom annotations that are limited to a subset of potential parent
|
||||
* annotation classes.
|
||||
*
|
||||
* @return array<class-string>|null List of valid parent annotation classes. If `null`, the default nesting rules apply.
|
||||
*/
|
||||
public function allowedParents(): ?array
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
use OpenApi\Util;
|
||||
|
||||
/**
|
||||
* Holds a set of reusable objects for different aspects of the OA.
|
||||
*
|
||||
* All objects defined within the components object will have no effect on the API unless they are explicitly
|
||||
* referenced from properties outside the components object.
|
||||
*
|
||||
* @see [OAI Components Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#components-object)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class Components extends AbstractAnnotation
|
||||
{
|
||||
public const COMPONENTS_PREFIX = '#/components/';
|
||||
|
||||
/**
|
||||
* Schema reference.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const SCHEMA_REF = '#/components/schemas/';
|
||||
|
||||
/**
|
||||
* Reusable Schemas.
|
||||
*
|
||||
* @var array<Schema|\OpenApi\Attributes\Schema>
|
||||
*/
|
||||
public $schemas = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Reusable Responses.
|
||||
*
|
||||
* @var Response[]
|
||||
*/
|
||||
public $responses = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Reusable Parameters.
|
||||
*
|
||||
* @var Parameter[]
|
||||
*/
|
||||
public $parameters = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Reusable Examples.
|
||||
*
|
||||
* @var Examples[]
|
||||
*/
|
||||
public $examples = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Reusable Request Bodies.
|
||||
*
|
||||
* @var RequestBody[]
|
||||
*/
|
||||
public $requestBodies = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Reusable Headers.
|
||||
*
|
||||
* @var Header[]
|
||||
*/
|
||||
public $headers = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Reusable Security Schemes.
|
||||
*
|
||||
* @var SecurityScheme[]
|
||||
*/
|
||||
public $securitySchemes = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Reusable Links.
|
||||
*
|
||||
* @var Link[]
|
||||
*/
|
||||
public $links = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Reusable Callbacks.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $callbacks = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
OpenApi::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Response::class => ['responses', 'response'],
|
||||
Parameter::class => ['parameters', 'parameter'],
|
||||
PathParameter::class => ['parameters', 'parameter'],
|
||||
RequestBody::class => ['requestBodies', 'request'],
|
||||
Examples::class => ['examples', 'example'],
|
||||
Header::class => ['headers', 'header'],
|
||||
SecurityScheme::class => ['securitySchemes', 'securityScheme'],
|
||||
Link::class => ['links', 'link'],
|
||||
Schema::class => ['schemas', 'schema'],
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
|
||||
/**
|
||||
* Generate a `#/components/...` reference for the given annotation.
|
||||
*
|
||||
* A `string` component value always assumes type `Schema`.
|
||||
*
|
||||
* @param AbstractAnnotation|string $component
|
||||
*/
|
||||
public static function ref($component, bool $encode = true): string
|
||||
{
|
||||
if ($component instanceof AbstractAnnotation) {
|
||||
foreach (Components::$_nested as $type => $nested) {
|
||||
// exclude attachables
|
||||
if (2 == count($nested)) {
|
||||
if ($component instanceof $type) {
|
||||
$type = $nested[0];
|
||||
$name = $component->{$nested[1]};
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$type = 'schemas';
|
||||
$name = $component;
|
||||
}
|
||||
|
||||
return self::COMPONENTS_PREFIX . $type . '/' . ($encode ? Util::refEncode((string) $name) : $name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* Contact information for the exposed API.
|
||||
*
|
||||
* @see [OAI Contact Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#contact-object)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class Contact extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* The identifying name of the contact person/organization.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The URL pointing to the contact information.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $url = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The email address of the contact person/organization.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $email = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'name' => 'string',
|
||||
'url' => 'string',
|
||||
'email' => 'string',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
Info::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
/**
|
||||
* A `@OA\Request` cookie parameter.
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class CookieParameter extends Parameter
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
* This takes 'cookie' as the default location.
|
||||
*/
|
||||
public $in = 'cookie';
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*/
|
||||
class Delete extends Operation
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $method = 'delete';
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
PathItem::class,
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* The discriminator is a specific object in a schema which is used to inform the consumer of
|
||||
* the specification of an alternative schema based on the value associated with it.
|
||||
*
|
||||
* This object is based on the [JSON Schema Specification](http://json-schema.org) and uses a predefined subset of it.
|
||||
* On top of this subset, there are extensions provided by this specification to allow for more complete documentation.
|
||||
*
|
||||
* @see [OAI Discriminator Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#discriminatorObject)
|
||||
* @see [JSON Schema](http://json-schema.org/)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class Discriminator extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* The name of the property in the payload that will hold the discriminator value.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $propertyName = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An object to hold mappings between payload values and schema names or references.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public $mapping = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_required = ['propertyName'];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'propertyName' => 'string',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
Schema::class,
|
||||
Property::class,
|
||||
AdditionalProperties::class,
|
||||
Items::class,
|
||||
JsonContent::class,
|
||||
XmlContent::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*/
|
||||
class Examples extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* The relative or absolute path to an example.
|
||||
*
|
||||
* @see [Using refs](https://swagger.io/docs/specification/using-ref/)
|
||||
*
|
||||
* @var string|class-string|object
|
||||
*/
|
||||
public $ref = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The key into `#/components/examples`.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $example = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Short description for the example.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $summary = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Embedded literal example.
|
||||
*
|
||||
* The value field and externalValue field are mutually exclusive.
|
||||
*
|
||||
* To represent examples of media types that cannot naturally be represented
|
||||
* in JSON or YAML, use a string value to contain the example, escaping where necessary.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Embedded literal example.
|
||||
*
|
||||
* The value field and externalValue field are mutually exclusive.
|
||||
*
|
||||
* To represent examples of media types that cannot naturally be represented
|
||||
* in JSON or YAML, use a string value to contain the example, escaping where necessary.
|
||||
*
|
||||
* @var int|string|array
|
||||
*/
|
||||
public $value = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An URL that points to the literal example.
|
||||
*
|
||||
* This provides the capability to reference examples that cannot easily be included
|
||||
* in JSON or YAML documents.
|
||||
*
|
||||
* The value field and externalValue field are mutually exclusive.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $externalValue = Generator::UNDEFINED;
|
||||
|
||||
public static $_types = [
|
||||
'summary' => 'string',
|
||||
'description' => 'string',
|
||||
'externalValue' => 'string',
|
||||
];
|
||||
|
||||
public static $_required = ['summary'];
|
||||
|
||||
public static $_parents = [
|
||||
Components::class,
|
||||
Parameter::class,
|
||||
PathParameter::class,
|
||||
MediaType::class,
|
||||
JsonContent::class,
|
||||
XmlContent::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* Allows referencing an external resource for extended documentation.
|
||||
*
|
||||
* @see [OAI External Documentation Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.md#external-documentation-object)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class ExternalDocumentation extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* A short description of the target documentation. GFM syntax can be used for rich text representation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The URL for the target documentation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $url = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'description' => 'string',
|
||||
'url' => 'string',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_required = ['url'];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
OpenApi::class,
|
||||
Tag::class,
|
||||
Schema::class,
|
||||
AdditionalProperties::class,
|
||||
Property::class,
|
||||
Operation::class,
|
||||
Get::class,
|
||||
Post::class,
|
||||
Put::class,
|
||||
Delete::class,
|
||||
Patch::class,
|
||||
Head::class,
|
||||
Options::class,
|
||||
Trace::class,
|
||||
Items::class,
|
||||
JsonContent::class,
|
||||
XmlContent::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* Configuration details for a supported OAuth Flow.
|
||||
*
|
||||
* @see [OAI OAuth Flow Object](https://swagger.io/specification/#oauthFlowObject)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class Flow extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* The authorization url to be used for this flow.
|
||||
*
|
||||
* This must be in the form of an url.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $authorizationUrl = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The token URL to be used for this flow.
|
||||
*
|
||||
* This must be in the form of an url.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $tokenUrl = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The URL to be used for obtaining refresh tokens.
|
||||
*
|
||||
* This must be in the form of an url.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $refreshUrl = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Flow name.
|
||||
*
|
||||
* One of ['implicit', 'password', 'authorizationCode', 'clientCredentials'].
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $flow = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The available scopes for the OAuth2 security scheme.
|
||||
*
|
||||
* A map between the scope name and a short description for it.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $scopes = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_required = ['scopes', 'flow'];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'flow' => ['implicit', 'password', 'authorizationCode', 'clientCredentials'],
|
||||
'refreshUrl' => 'string',
|
||||
'authorizationUrl' => 'string',
|
||||
'tokenUrl' => 'string',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
SecurityScheme::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
if (is_array($this->scopes) && empty($this->scopes)) {
|
||||
$this->scopes = new \stdClass();
|
||||
}
|
||||
|
||||
return parent::jsonSerialize();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*/
|
||||
class Get extends Operation
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $method = 'get';
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
PathItem::class,
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*/
|
||||
class Head extends Operation
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $method = 'head';
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
PathItem::class,
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* @see [OAI Header Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.md#headerObject).
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class Header extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* The relative or absolute path to the endpoint.
|
||||
*
|
||||
* @see [Using refs](https://swagger.io/docs/specification/using-ref/)
|
||||
*
|
||||
* @var string|class-string|object
|
||||
*/
|
||||
public $ref = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $header = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A brief description of the parameter.
|
||||
*
|
||||
* This could contain examples of use.
|
||||
* CommonMark syntax MAY be used for rich text representation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $required = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Schema object.
|
||||
*
|
||||
* @var Schema
|
||||
*/
|
||||
public $schema = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Specifies that a parameter is deprecated and SHOULD be transitioned out of usage.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $deprecated = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Sets the ability to pass empty-valued parameters.
|
||||
*
|
||||
* This is valid only for query parameters and allows sending a parameter with an empty value.
|
||||
*
|
||||
* Default value is false.
|
||||
*
|
||||
* If style is used, and if behavior is n/a (cannot be serialized), the value of allowEmptyValue SHALL be ignored.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $allowEmptyValue = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_required = ['header', 'schema'];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'header' => 'string',
|
||||
'description' => 'string',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Schema::class => 'schema',
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
Components::class,
|
||||
Response::class,
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
/**
|
||||
* A `@OA\Request` header parameter.
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class HeaderParameter extends Parameter
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
* This takes 'header' as the default location.
|
||||
*/
|
||||
public $in = 'header';
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* The object provides metadata about the API.
|
||||
*
|
||||
* The metadata may be used by the clients if needed and may be presented in editing or documentation generation tools for convenience.
|
||||
*
|
||||
* @see [OAI Info Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#info-object)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class Info extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* The title of the application.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $title = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A short description of the application.
|
||||
*
|
||||
* CommonMark syntax may be used for rich text representation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An URL to the Terms of Service for the API.
|
||||
*
|
||||
* Must be in the format of an url.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $termsOfService = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The contact information for the exposed API.
|
||||
*
|
||||
* @var Contact
|
||||
*/
|
||||
public $contact = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The license information for the exposed API.
|
||||
*
|
||||
* @var License
|
||||
*/
|
||||
public $license = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The version of the OpenAPI document (which is distinct from the OpenAPI Specification version or the API implementation version).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $version = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_required = ['title', 'version'];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'title' => 'string',
|
||||
'version' => 'string',
|
||||
'description' => 'string',
|
||||
'termsOfService' => 'string',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Contact::class => 'contact',
|
||||
License::class => 'license',
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
OpenApi::class,
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
/**
|
||||
* The description of an item in a Schema with type `array`.
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class Items extends Schema
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Discriminator::class => 'discriminator',
|
||||
Items::class => 'items',
|
||||
Property::class => ['properties', 'property'],
|
||||
ExternalDocumentation::class => 'externalDocs',
|
||||
Xml::class => 'xml',
|
||||
AdditionalProperties::class => 'additionalProperties',
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
Property::class,
|
||||
AdditionalProperties::class,
|
||||
Schema::class,
|
||||
JsonContent::class,
|
||||
XmlContent::class,
|
||||
Items::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function validate(array $stack = [], array $skip = [], string $ref = '', $context = null): bool
|
||||
{
|
||||
if (in_array($this, $skip, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$valid = parent::validate($stack, $skip, $ref, $context);
|
||||
|
||||
$parent = end($stack);
|
||||
if ($parent instanceof Schema && $parent->type !== 'array') {
|
||||
$this->_context->logger->warning('@OA\\Items() parent type must be "array" in ' . $this->_context);
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
// @todo Additional validation when used inside a Header or Parameter context.
|
||||
|
||||
return $valid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* Shorthand for a json response.
|
||||
*
|
||||
* Use as `@OA\Schema` inside a `Response` and `MediaType`->`'application/json'` will be generated.
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class JsonContent extends Schema
|
||||
{
|
||||
/**
|
||||
* An associative array of Examples attributes.
|
||||
*
|
||||
* The keys represent the name of the example and the values are instances of the Examples attribute.
|
||||
* Each example is used to show how the content of the request or response should look like.
|
||||
*
|
||||
* @var array<string,Examples>
|
||||
*/
|
||||
public $examples = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Discriminator::class => 'discriminator',
|
||||
Items::class => 'items',
|
||||
Property::class => ['properties', 'property'],
|
||||
ExternalDocumentation::class => 'externalDocs',
|
||||
AdditionalProperties::class => 'additionalProperties',
|
||||
Examples::class => ['examples', 'example'],
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* License information for the exposed API.
|
||||
*
|
||||
* @see [OAI License Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#license-object)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class License extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* The license name used for the API.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An SPDX license expression for the API. The `identifier` field is mutually exclusive of the `url` field.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $identifier = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An URL to the license used for the API. This MUST be in the form of a URL.
|
||||
*
|
||||
* The `url` field is mutually exclusive of the `identifier` field.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $url = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'name' => 'string',
|
||||
'identifier' => 'string',
|
||||
'url' => 'string',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_required = ['name'];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
Info::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
$data = parent::jsonSerialize();
|
||||
|
||||
if ($this->_context->isVersion(OpenApi::VERSION_3_0_0)) {
|
||||
unset($data->identifier);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function validate(array $stack = [], array $skip = [], string $ref = '', $context = null): bool
|
||||
{
|
||||
$valid = parent::validate($stack, $skip, $ref, $context);
|
||||
|
||||
if ($this->_context->isVersion(OpenApi::VERSION_3_1_0)) {
|
||||
if (!Generator::isDefault($this->url) && $this->identifier !== Generator::UNDEFINED) {
|
||||
$this->_context->logger->warning($this->identity() . ' url and identifier are mutually exclusive');
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* The Link object represents a possible design-time link for a response.
|
||||
*
|
||||
* The presence of a link does not guarantee the caller's ability to successfully invoke it, rather it provides a known
|
||||
* relationship and traversal mechanism between responses and other operations.
|
||||
*
|
||||
* Unlike dynamic links (i.e. links provided in the response payload), the OA linking mechanism does not require
|
||||
* link information in the runtime response.
|
||||
*
|
||||
* For computing links, and providing instructions to execute them, a runtime expression is used for
|
||||
* accessing values in an operation and using them as parameters while invoking the linked operation.
|
||||
*
|
||||
* @see [OAI Link Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#link-object)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class Link extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* @see [Using refs](https://swagger.io/docs/specification/using-ref/)
|
||||
*
|
||||
* @var string|class-string|object
|
||||
*/
|
||||
public $ref = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The key into MediaType->links array.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $link = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A relative or absolute reference to an OA operation.
|
||||
*
|
||||
* This field is mutually exclusive of the <code>operationId</code> field, and must point to an Operation object.
|
||||
*
|
||||
* Relative values may be used to locate an existing Operation object in the OpenAPI definition.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $operationRef = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The name of an existing, resolvable OA operation, as defined with a unique <code>operationId</code>.
|
||||
*
|
||||
* This field is mutually exclusive of the <code>operationRef</code> field.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $operationId = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A map representing parameters to pass to an operation as specified with operationId or identified via
|
||||
* operationRef.
|
||||
*
|
||||
* The key is the parameter name to be used, whereas the value can be a constant or an expression to
|
||||
* be evaluated and passed to the linked operation.
|
||||
* The parameter name can be qualified using the parameter location [{in}.]{name} for operations
|
||||
* that use the same parameter name in different locations (e.g. path.id).
|
||||
*
|
||||
* @var array<string,mixed>
|
||||
*/
|
||||
public $parameters = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A literal value or {expression} to use as a request body when calling the target operation.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $requestBody = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A description of the link.
|
||||
*
|
||||
* CommonMark syntax may be used for rich text representation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A server object to be used by the target operation.
|
||||
*
|
||||
* @var Server
|
||||
*/
|
||||
public $server = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Server::class => 'server',
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
Components::class,
|
||||
Response::class,
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* Each Media Type object provides schema and examples for the media type identified by its key.
|
||||
*
|
||||
* @see [OAI Media Type Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#media-type-object)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class MediaType extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* The key into Operation->content array.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $mediaType = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The schema defining the type used for the request body.
|
||||
*
|
||||
* @var Schema
|
||||
*/
|
||||
public $schema = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Example of the media type.
|
||||
*
|
||||
* The example object should be in the correct format as specified by the media type.
|
||||
* The example object is mutually exclusive of the examples object.
|
||||
*
|
||||
* Furthermore, if referencing a schema which contains an example,
|
||||
* the example value shall override the example provided by the schema.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $example = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Examples of the media type.
|
||||
*
|
||||
* Each example object should match the media type and specified schema if present.
|
||||
* The examples object is mutually exclusive of the example object.
|
||||
*
|
||||
* Furthermore, if referencing a schema which contains an example,
|
||||
* the examples value shall override the example provided by the schema.
|
||||
*
|
||||
* @var array<string,Examples>
|
||||
*/
|
||||
public $examples = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A map between a property name and its encoding information.
|
||||
*
|
||||
* The key, being the property name, must exist in the schema as a property.
|
||||
*
|
||||
* The encoding object shall only apply to requestBody objects when the media type is multipart or
|
||||
* application/x-www-form-urlencoded.
|
||||
*
|
||||
* @var array<string,mixed>
|
||||
*/
|
||||
public $encoding = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Schema::class => 'schema',
|
||||
Examples::class => ['examples', 'example'],
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
Response::class,
|
||||
RequestBody::class,
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Analysis;
|
||||
use OpenApi\Generator;
|
||||
use OpenApi\Util;
|
||||
|
||||
/**
|
||||
* This is the root document object for the API specification.
|
||||
*
|
||||
* @see [OAI OpenApi Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.md#openapi-object)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class OpenApi extends AbstractAnnotation
|
||||
{
|
||||
public const VERSION_3_0_0 = '3.0.0';
|
||||
public const VERSION_3_1_0 = '3.1.0';
|
||||
public const DEFAULT_VERSION = self::VERSION_3_0_0;
|
||||
public const SUPPORTED_VERSIONS = [self::VERSION_3_0_0, self::VERSION_3_1_0];
|
||||
|
||||
/**
|
||||
* The semantic version number of the OpenAPI Specification version that the OpenAPI document uses.
|
||||
*
|
||||
* The openapi field should be used by tooling specifications and clients to interpret the OpenAPI document.
|
||||
*
|
||||
* A version specified via `Generator::setVersion()` will overwrite this value.
|
||||
*
|
||||
* This is not related to the API info::version string.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $openapi = self::DEFAULT_VERSION;
|
||||
|
||||
/**
|
||||
* Provides metadata about the API. The metadata may be used by tooling as required.
|
||||
*
|
||||
* @var Info
|
||||
*/
|
||||
public $info = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An array of <code>@Server</code> objects, which provide connectivity information to a target server.
|
||||
*
|
||||
* If not provided, or is an empty array, the default value would be a Server Object with an url value of <code>/</code>.
|
||||
*
|
||||
* @var Server[]
|
||||
*/
|
||||
public $servers = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The available paths and operations for the API.
|
||||
*
|
||||
* @var PathItem[]
|
||||
*/
|
||||
public $paths = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An element to hold various components for the specification.
|
||||
*
|
||||
* @var Components
|
||||
*/
|
||||
public $components = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A declaration of which security mechanisms can be used across the API.
|
||||
*
|
||||
* The list of values includes alternative security requirement objects that can be used.
|
||||
* Only one of the security requirement objects need to be satisfied to authorize a request.
|
||||
* Individual operations can override this definition.
|
||||
* To make security optional, an empty security requirement `({})` can be included in the array.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $security = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A list of tags used by the specification with additional metadata.
|
||||
*
|
||||
* The order of the tags can be used to reflect on their order by the parsing tools.
|
||||
* Not all tags that are used by the Operation Object must be declared.
|
||||
* The tags that are not declared may be organized randomly or based on the tools' logic.
|
||||
* Each tag name in the list must be unique.
|
||||
*
|
||||
* @var Tag[]
|
||||
*/
|
||||
public $tags = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Additional external documentation.
|
||||
*
|
||||
* @var ExternalDocumentation
|
||||
*/
|
||||
public $externalDocs = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The available webhooks for the API.
|
||||
*
|
||||
* @var Webhook[]
|
||||
*/
|
||||
public $webhooks = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @var Analysis
|
||||
*/
|
||||
public $_analysis = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_required = ['openapi', 'info'];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Info::class => 'info',
|
||||
Server::class => ['servers'],
|
||||
PathItem::class => ['paths', 'path'],
|
||||
Components::class => 'components',
|
||||
Tag::class => ['tags'],
|
||||
ExternalDocumentation::class => 'externalDocs',
|
||||
Webhook::class => ['webhooks', 'webhook'],
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function validate(?array $stack = null, ?array $skip = null, string $ref = '', $context = null): bool
|
||||
{
|
||||
if ($stack !== null || $skip !== null || $ref !== '') {
|
||||
$this->_context->logger->warning('Nested validation for ' . $this->identity() . ' not allowed');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!in_array($this->openapi, self::SUPPORTED_VERSIONS)) {
|
||||
$this->_context->logger->warning('Unsupported OpenAPI version "' . $this->openapi . '". Allowed versions are: ' . implode(', ', self::SUPPORTED_VERSIONS));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* paths is optional in 3.1.0 */
|
||||
if ($this->openapi === self::VERSION_3_0_0 && Generator::isDefault($this->paths)) {
|
||||
$this->_context->logger->warning('Required @OA\PathItem() not found');
|
||||
}
|
||||
|
||||
if ($this->openapi === self::VERSION_3_1_0
|
||||
&& Generator::isDefault($this->paths)
|
||||
&& Generator::isDefault($this->webhooks)
|
||||
&& Generator::isDefault($this->components)
|
||||
) {
|
||||
$this->_context->logger->warning("At least one of 'Required @OA\PathItem(), @OA\Components() or @OA\Webhook() not found'");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::validate([], [], '#', new \stdClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the OpenAPI documentation to a file.
|
||||
*/
|
||||
public function saveAs(string $filename, string $format = 'auto'): void
|
||||
{
|
||||
if ($format === 'auto') {
|
||||
$format = strtolower(substr($filename, -5)) === '.json' ? 'json' : 'yaml';
|
||||
}
|
||||
|
||||
if (strtolower($format) === 'json') {
|
||||
$content = $this->toJson();
|
||||
} else {
|
||||
$content = $this->toYaml();
|
||||
}
|
||||
|
||||
if (file_put_contents($filename, $content) === false) {
|
||||
throw new \Exception('Failed to saveAs("' . $filename . '", "' . $format . '")');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up an annotation with a $ref url.
|
||||
*
|
||||
* @param string $ref The $ref value, for example: "#/components/schemas/Product"
|
||||
*/
|
||||
public function ref(string $ref)
|
||||
{
|
||||
if (substr($ref, 0, 2) !== '#/') {
|
||||
// @todo Add support for external (http) refs?
|
||||
throw new \Exception('Unsupported $ref "' . $ref . '", it should start with "#/"');
|
||||
}
|
||||
|
||||
return $this->resolveRef($ref, '#/', $this, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive helper for ref().
|
||||
*
|
||||
* @param array|AbstractAnnotation $container
|
||||
*/
|
||||
private static function resolveRef(string $ref, string $resolved, $container, array $mapping)
|
||||
{
|
||||
if ($ref === $resolved) {
|
||||
return $container;
|
||||
}
|
||||
$path = substr($ref, strlen($resolved));
|
||||
$slash = strpos($path, '/');
|
||||
|
||||
$subpath = $slash === false ? $path : substr($path, 0, $slash);
|
||||
$property = Util::refDecode($subpath);
|
||||
$unresolved = $slash === false ? $resolved . $subpath : $resolved . $subpath . '/';
|
||||
|
||||
if (is_object($container)) {
|
||||
if (property_exists($container, $property) === false) {
|
||||
throw new \Exception('$ref "' . $ref . '" not found');
|
||||
}
|
||||
if ($slash === false) {
|
||||
return $container->{$property};
|
||||
}
|
||||
$mapping = [];
|
||||
if ($container instanceof AbstractAnnotation) {
|
||||
foreach ($container::$_nested as $nestedClass => $nested) {
|
||||
if (is_string($nested) === false && count($nested) === 2 && $nested[0] === $property) {
|
||||
$mapping[$nestedClass] = $nested[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return self::resolveRef($ref, $unresolved, $container->{$property}, $mapping);
|
||||
} elseif (is_array($container)) {
|
||||
if (array_key_exists($property, $container)) {
|
||||
return self::resolveRef($ref, $unresolved, $container[$property], []);
|
||||
}
|
||||
foreach ($mapping as $nestedClass => $keyField) {
|
||||
foreach ($container as $key => $item) {
|
||||
if (is_numeric($key) && is_object($item) && $item instanceof $nestedClass && (string) $item->{$keyField} === $property) {
|
||||
return self::resolveRef($ref, $unresolved, $item, []);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new \Exception('$ref "' . $unresolved . '" not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
$data = parent::jsonSerialize();
|
||||
|
||||
if (false === $this->_context->isVersion(OpenApi::VERSION_3_1_0)) {
|
||||
unset($data->webhooks);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* Base class for `@OA\Get`, `@OA\Post`, `@OA\Put`, etc.
|
||||
*
|
||||
* Describes a single API operation on a path.
|
||||
*
|
||||
* @see [OAI Operation Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#operation-object)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
abstract class Operation extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* Key in the OpenApi "Paths Object" for this operation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $path = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A list of tags for API documentation control.
|
||||
*
|
||||
* Tags can be used for logical grouping of operations by resources or any other qualifier.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public $tags = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Key in the OpenApi "Path Item Object" for this operation.
|
||||
*
|
||||
* Allowed values: 'get', 'post', put', 'patch', 'delete', 'options', 'head' and 'trace'.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $method = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A short summary of what the operation does.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $summary = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A verbose explanation of the operation behavior.
|
||||
*
|
||||
* CommonMark syntax MAY be used for rich text representation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Additional external documentation for this operation.
|
||||
*
|
||||
* @var ExternalDocumentation
|
||||
*/
|
||||
public $externalDocs = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Unique string used to identify the operation.
|
||||
*
|
||||
* The id must be unique among all operations described in the API.
|
||||
* Tools and libraries may use the operationId to uniquely identify an operation, therefore, it is recommended to
|
||||
* follow common programming naming conventions.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $operationId = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A list of parameters that are applicable for this operation.
|
||||
*
|
||||
* If a parameter is already defined at the Path Item, the new definition will override it but can never remove it.
|
||||
* The list must not include duplicated parameters.
|
||||
*
|
||||
* A unique parameter is defined by a combination of a name and location.
|
||||
*
|
||||
* The list can use the Reference Object to link to parameters that are defined at the OpenAPI Object's
|
||||
* components/parameters.
|
||||
*
|
||||
* @var Parameter[]
|
||||
*/
|
||||
public $parameters = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The request body applicable for this operation.
|
||||
*
|
||||
* The requestBody is only supported in HTTP methods where the HTTP 1.1 specification RFC7231 has explicitly
|
||||
* defined semantics for request bodies. In other cases where the HTTP spec is vague, requestBody shall be ignored
|
||||
* by consumers.
|
||||
*
|
||||
* @var RequestBody
|
||||
*/
|
||||
public $requestBody = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The list of possible responses as they are returned from executing this operation.
|
||||
*
|
||||
* @var Response[]
|
||||
*/
|
||||
public $responses = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A map of possible out-of band callbacks related to the parent operation.
|
||||
*
|
||||
* The key is a unique identifier for the Callback Object.
|
||||
*
|
||||
* Each value in the map is a Callback Object that describes a request that may be initiated by the API provider
|
||||
* and the expected responses. The key value used to identify the callback object is an expression, evaluated at
|
||||
* runtime, that identifies a URL to use for the callback operation.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $callbacks = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Declares this operation to be deprecated.
|
||||
*
|
||||
* Consumers should refrain from usage of the declared operation.
|
||||
*
|
||||
* Default value is false.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $deprecated = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A declaration of which security mechanisms can be used for this operation.
|
||||
*
|
||||
* The list of values includes alternative security requirement objects that can be used.
|
||||
*
|
||||
* Only one of the security requirement objects need to be satisfied to authorize a request.
|
||||
*
|
||||
* This definition overrides any declared top-level security.
|
||||
* To remove a top-level security declaration, an empty array can be used.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $security = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An alternative server array to service this operation.
|
||||
*
|
||||
* If an alternative server object is specified at the Path Item Object or Root level, it will be overridden by
|
||||
* this value.
|
||||
*
|
||||
* @var Server[]
|
||||
*/
|
||||
public $servers = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_required = ['responses'];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'path' => 'string',
|
||||
'method' => 'string',
|
||||
'tags' => '[string]',
|
||||
'summary' => 'string',
|
||||
'description' => 'string',
|
||||
'deprecated' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Parameter::class => ['parameters'],
|
||||
PathParameter::class => ['parameters'],
|
||||
Response::class => ['responses', 'response'],
|
||||
ExternalDocumentation::class => 'externalDocs',
|
||||
Server::class => ['servers'],
|
||||
RequestBody::class => 'requestBody',
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
$data = parent::jsonSerialize();
|
||||
|
||||
unset($data->method);
|
||||
unset($data->path);
|
||||
|
||||
// ensure security elements are object
|
||||
if (isset($data->security) && is_array($data->security)) {
|
||||
foreach ($data->security as $key => $scheme) {
|
||||
$data->security[$key] = (object) $scheme;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function validate(array $stack = [], array $skip = [], string $ref = '', $context = null): bool
|
||||
{
|
||||
if (in_array($this, $skip, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$valid = parent::validate($stack, $skip, $ref, $context);
|
||||
|
||||
if (!Generator::isDefault($this->responses)) {
|
||||
foreach ($this->responses as $response) {
|
||||
if (!Generator::isDefault($response->response) && $response->response !== 'default' && preg_match('/^([12345]{1}[0-9]{2})|([12345]{1}XX)$/', (string) $response->response) === 0) {
|
||||
$this->_context->logger->warning('Invalid value "' . $response->response . '" for ' . $response->_identity([]) . '->response, expecting "default", a HTTP Status Code or HTTP Status Code range definition in ' . $response->_context);
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_object($context) && !Generator::isDefault($this->operationId)) {
|
||||
if (!property_exists($context, 'operationIds')) {
|
||||
$context->operationIds = [];
|
||||
}
|
||||
|
||||
if (in_array($this->operationId, $context->operationIds)) {
|
||||
$this->_context->logger->warning('operationId must be unique. Duplicate value found: "' . $this->operationId . '"');
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
$context->operationIds[] = $this->operationId;
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*/
|
||||
class Options extends Operation
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $method = 'options';
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
PathItem::class,
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* Describes a single operation parameter.
|
||||
*
|
||||
* A unique parameter is defined by a combination of a name and location.
|
||||
*
|
||||
* @see [OAA Parameter Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class Parameter extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* The relative or absolute path to the endpoint.
|
||||
*
|
||||
* @see [Using refs](https://swagger.io/docs/specification/using-ref/)
|
||||
*
|
||||
* @var string|class-string|object
|
||||
*/
|
||||
public $ref = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The key into <code>Components::parameters</code> or <code>PathItem::parameters</code> array.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $parameter = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The (case-sensitive) name of the parameter.
|
||||
*
|
||||
* If in is "path", the name field must correspond to the associated path segment from the path field in the Paths Object.
|
||||
*
|
||||
* If in is "header" and the name field is "Accept", "Content-Type" or "Authorization", the parameter definition shall be ignored.
|
||||
* For all other cases, the name corresponds to the parameter name used by the in property.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The location of the parameter.
|
||||
*
|
||||
* Possible values are "query", "header", "path" or "cookie".
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $in = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A brief description of the parameter.
|
||||
*
|
||||
* This could contain examples of use.
|
||||
*
|
||||
* CommonMark syntax may be used for rich text representation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Determines whether this parameter is mandatory.
|
||||
*
|
||||
* If the parameter location is "path", this property is required and its value must be true.
|
||||
* Otherwise, the property may be included and its default value is false.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $required = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Specifies that a parameter is deprecated and should be transitioned out of usage.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $deprecated = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Sets the ability to pass empty-valued parameters.
|
||||
*
|
||||
* This is valid only for query parameters and allows sending a parameter with an empty value.
|
||||
*
|
||||
* Default value is false.
|
||||
*
|
||||
* If style is used, and if behavior is n/a (cannot be serialized), the value of allowEmptyValue shall be ignored.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $allowEmptyValue = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Describes how the parameter value will be serialized depending on the type of the parameter value.
|
||||
*
|
||||
* Default values (based on value of in): for query - form; for path - simple; for header - simple; for cookie - form.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $style = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* When this is true, parameter values of type array or object generate separate parameters for each value of the array or key-value pair of the map.
|
||||
*
|
||||
* For other types of parameters this property has no effect.
|
||||
*
|
||||
* When style is form, the default value is true.
|
||||
* For all other styles, the default value is false.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $explode = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Determines whether the parameter value should allow reserved characters, as defined by RFC3986 :/?#[]@!$&'()*+,;= to be included without percent-encoding.
|
||||
*
|
||||
* This property only applies to parameters with an in value of query.
|
||||
*
|
||||
* The default value is false.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $allowReserved = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The schema defining the type used for the parameter.
|
||||
*
|
||||
* @var Schema
|
||||
*/
|
||||
public $schema = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Example of the media type.
|
||||
*
|
||||
* The example should match the specified schema and encoding properties if present.
|
||||
* The example object is mutually exclusive of the examples object.
|
||||
* Furthermore, if referencing a schema which contains an example, the example value shall override the example provided by the schema.
|
||||
* To represent examples of media types that cannot naturally be represented in JSON or YAML, a string value can contain the example with escaping where necessary.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $example = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Examples of the media type.
|
||||
*
|
||||
* Each example should contain a value in the correct format as specified in the parameter encoding.
|
||||
* The examples object is mutually exclusive of the example object.
|
||||
* Furthermore, if referencing a schema which contains an example, the examples value shall override the example provided by the schema.
|
||||
*
|
||||
* @var array<string,Examples>
|
||||
*/
|
||||
public $examples = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A map containing the representations for the parameter.
|
||||
*
|
||||
* The key is the media type and the value describes it.
|
||||
* The map must only contain one entry.
|
||||
*
|
||||
* @var array<MediaType>|JsonContent|XmlContent|Attachable
|
||||
*/
|
||||
public $content = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Path-style parameters defined by RFC6570.
|
||||
*
|
||||
* @see [RFC6570](https://tools.ietf.org/html/rfc6570#section-3.2.7)
|
||||
*/
|
||||
public $matrix = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Label style parameters defined by RFC6570.
|
||||
*
|
||||
* @see [RFC6570](https://tools.ietf.org/html/rfc6570#section-3.2.5)
|
||||
*/
|
||||
public $label = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Form style parameters defined by RFC6570.
|
||||
*
|
||||
* This option replaces collectionFormat with a csv (when explode is false) or multi (when explode is true) value from OpenAPI 2.0.
|
||||
*
|
||||
* @see [RFC6570](https://tools.ietf.org/html/rfc6570#section-3.2.8)
|
||||
*/
|
||||
public $form = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Simple style parameters defined by RFC6570.
|
||||
*
|
||||
* This option replaces collectionFormat with a csv value from OpenAPI 2.0.
|
||||
*
|
||||
* @see [RFC6570](https://tools.ietf.org/html/rfc6570#section-3.2.2)
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $simple = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Space separated array values.
|
||||
*
|
||||
* This option replaces collectionFormat equal to ssv from OpenAPI 2.0.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $spaceDelimited = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Pipe separated array values.
|
||||
*
|
||||
* This option replaces collectionFormat equal to pipes from OpenAPI 2.0.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $pipeDelimited = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Provides a simple way of rendering nested objects using form parameters.
|
||||
*/
|
||||
public $deepObject = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_required = ['name', 'in'];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'name' => 'string',
|
||||
'in' => ['query', 'header', 'path', 'cookie'],
|
||||
'description' => 'string',
|
||||
'style' => ['matrix', 'label', 'form', 'simple', 'spaceDelimited', 'pipeDelimited', 'deepObject'],
|
||||
'required' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Schema::class => 'schema',
|
||||
Examples::class => ['examples', 'example'],
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
Components::class,
|
||||
PathItem::class,
|
||||
Operation::class,
|
||||
Get::class,
|
||||
Post::class,
|
||||
Put::class,
|
||||
Delete::class,
|
||||
Patch::class,
|
||||
Head::class,
|
||||
Options::class,
|
||||
Trace::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function validate(array $stack = [], array $skip = [], string $ref = '', $context = null): bool
|
||||
{
|
||||
if (in_array($this, $skip, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$valid = parent::validate($stack, $skip, $ref, $context);
|
||||
|
||||
if (Generator::isDefault($this->ref)) {
|
||||
if ($this->in === 'body') {
|
||||
if (Generator::isDefault($this->schema)) {
|
||||
$this->_context->logger->warning('Field "schema" is required when ' . $this->identity() . ' is in "' . $this->in . '" in ' . $this->_context);
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function identity(): string
|
||||
{
|
||||
return parent::_identity(['name', 'in']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*/
|
||||
class Patch extends Operation
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $method = 'patch';
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
PathItem::class,
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* Describes the operations available on a single path.
|
||||
*
|
||||
* A Path Item may be empty, due to ACL constraints.
|
||||
* The path itself is still exposed to the documentation viewer, but they will not know which operations and parameters are available.
|
||||
*
|
||||
* @see [OAI Path Item Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#path-item-object)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class PathItem extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* @see [Using refs](https://swagger.io/docs/specification/using-ref/)
|
||||
*
|
||||
* @var string|class-string|object
|
||||
*/
|
||||
public $ref = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An optional, string summary, intended to apply to all operations in this path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $summary = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An optional, string description, intended to apply to all operations in this path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Key for the Path Object (OpenApi->paths array).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $path = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A definition of a GET operation on this path.
|
||||
*
|
||||
* @var Get
|
||||
*/
|
||||
public $get = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A definition of a PUT operation on this path.
|
||||
*
|
||||
* @var Put
|
||||
*/
|
||||
public $put = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A definition of a POST operation on this path.
|
||||
*
|
||||
* @var Post
|
||||
*/
|
||||
public $post = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A definition of a DELETE operation on this path.
|
||||
*
|
||||
* @var Delete
|
||||
*/
|
||||
public $delete = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A definition of a OPTIONS operation on this path.
|
||||
*
|
||||
* @var Options
|
||||
*/
|
||||
public $options = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A definition of a HEAD operation on this path.
|
||||
*
|
||||
* @var Head
|
||||
*/
|
||||
public $head = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A definition of a PATCH operation on this path.
|
||||
*
|
||||
* @var Patch
|
||||
*/
|
||||
public $patch = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A definition of a TRACE operation on this path.
|
||||
*
|
||||
* @var Trace
|
||||
*/
|
||||
public $trace = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An alternative server array to service all operations in this path.
|
||||
*
|
||||
* @var Server[]
|
||||
*/
|
||||
public $servers = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A list of parameters that are applicable for all the operations described under this path.
|
||||
*
|
||||
* These parameters can be overridden at the operation level, but cannot be removed there.
|
||||
* The list must not include duplicated parameters.
|
||||
* A unique parameter is defined by a combination of a name and location.
|
||||
* The list can use the Reference Object to link to parameters that are defined at the OpenAPI Object's components/parameters.
|
||||
*
|
||||
* @var Parameter[]
|
||||
*/
|
||||
public $parameters = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'path' => 'string',
|
||||
'summary' => 'string',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Get::class => 'get',
|
||||
Post::class => 'post',
|
||||
Put::class => 'put',
|
||||
Delete::class => 'delete',
|
||||
Patch::class => 'patch',
|
||||
Trace::class => 'trace',
|
||||
Head::class => 'head',
|
||||
Options::class => 'options',
|
||||
Parameter::class => ['parameters'],
|
||||
PathParameter::class => ['parameters'],
|
||||
Server::class => ['servers'],
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
OpenApi::class,
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
/**
|
||||
* A `@OA\Request` path parameter.
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class PathParameter extends Parameter
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
* This takes 'path' as the default location.
|
||||
*/
|
||||
public $in = 'path';
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $required = true;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*/
|
||||
class Post extends Operation
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $method = 'post';
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
PathItem::class,
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*/
|
||||
class Property extends Schema
|
||||
{
|
||||
/**
|
||||
* The key into Schema->properties array.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $property = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
AdditionalProperties::class,
|
||||
Schema::class,
|
||||
JsonContent::class,
|
||||
XmlContent::class,
|
||||
Property::class,
|
||||
Items::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Discriminator::class => 'discriminator',
|
||||
Items::class => 'items',
|
||||
Property::class => ['properties', 'property'],
|
||||
ExternalDocumentation::class => 'externalDocs',
|
||||
Xml::class => 'xml',
|
||||
AdditionalProperties::class => 'additionalProperties',
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*/
|
||||
class Put extends Operation
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $method = 'put';
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
PathItem::class,
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
/**
|
||||
* A `@OA\Request` query parameter.
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class QueryParameter extends Parameter
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
* This takes 'query' as the default location.
|
||||
*/
|
||||
public $in = 'query';
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Attributes\JsonContent;
|
||||
use OpenApi\Attributes\XmlContent;
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* Describes a single request body.
|
||||
*
|
||||
* @see [OAI Request Body Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#requestBodyObject)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class RequestBody extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* The relative or absolute path to a request body.
|
||||
*
|
||||
* @see [Using refs](https://swagger.io/docs/specification/using-ref/)
|
||||
*
|
||||
* @var string|class-string|object
|
||||
*/
|
||||
public $ref = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Request body model name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $request = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A brief description of the parameter.
|
||||
*
|
||||
* This could contain examples of use.
|
||||
*
|
||||
* CommonMark syntax may be used for rich text representation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Determines whether this parameter is mandatory.
|
||||
*
|
||||
* If the parameter location is "path", this property is required and its value must be true.
|
||||
* Otherwise, the property may be included and its default value is false.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $required = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The content of the request body.
|
||||
*
|
||||
* The key is a media type or media type range and the value describes it. For requests that match multiple keys,
|
||||
* only the most specific key is applicable. e.g. text/plain overrides text/*.
|
||||
*
|
||||
* @var array<MediaType|JsonContent|XmlContent>|MediaType|JsonContent|XmlContent|Attachable
|
||||
*/
|
||||
public $content = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'description' => 'string',
|
||||
'required' => 'boolean',
|
||||
'request' => 'string',
|
||||
];
|
||||
|
||||
public static $_parents = [
|
||||
Components::class,
|
||||
Delete::class,
|
||||
Get::class,
|
||||
Head::class,
|
||||
Operation::class,
|
||||
Options::class,
|
||||
Patch::class,
|
||||
Post::class,
|
||||
Trace::class,
|
||||
Put::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
MediaType::class => ['content', 'mediaType'],
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* Describes a single response from an API Operation, including design-time,
|
||||
* static links to operations based on the response.
|
||||
*
|
||||
* @see [OAI Response Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#response-object)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class Response extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* The relative or absolute path to a response.
|
||||
*
|
||||
* @see [Using refs](https://swagger.io/docs/specification/using-ref/)
|
||||
*
|
||||
* @var string|class-string|object
|
||||
*/
|
||||
public $ref = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The key into Operations->responses array.
|
||||
*
|
||||
* A HTTP status code or <code>default</code>.
|
||||
*
|
||||
* @var string|int
|
||||
*/
|
||||
public $response = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A short description of the response.
|
||||
*
|
||||
* CommonMark syntax may be used for rich text representation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Maps a header name to its definition.
|
||||
*
|
||||
* RFC7230 states header names are case insensitive.
|
||||
*
|
||||
* If a response header is defined with the name "Content-Type", it shall be ignored.
|
||||
*
|
||||
* @see [RFC7230](https://tools.ietf.org/html/rfc7230#page-22)
|
||||
*
|
||||
* @var Header[]
|
||||
*/
|
||||
public $headers = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A map containing descriptions of potential response payloads.
|
||||
*
|
||||
* The key is a media type or media type range and the value describes it.
|
||||
*
|
||||
* For responses that match multiple keys, only the most specific key is applicable;
|
||||
* e.g. <code>text/plain</code> overrides <code>text/*</code>.
|
||||
*
|
||||
* @var MediaType|JsonContent|XmlContent|Attachable|array<MediaType|JsonContent|XmlContent|Attachable>
|
||||
*/
|
||||
public $content = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A map of operations links that can be followed from the response.
|
||||
*
|
||||
* The key of the map is a short name for the link, following the naming constraints of the names for Component
|
||||
* Objects.
|
||||
*
|
||||
* @var Link[]
|
||||
*/
|
||||
public $links = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'description' => 'string',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
MediaType::class => ['content', 'mediaType'],
|
||||
Header::class => ['headers', 'header'],
|
||||
Link::class => ['links', 'link'],
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
Components::class,
|
||||
Operation::class,
|
||||
Get::class,
|
||||
Post::class,
|
||||
Put::class,
|
||||
Patch::class,
|
||||
Delete::class,
|
||||
Head::class,
|
||||
Options::class,
|
||||
Trace::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function validate(array $stack = [], array $skip = [], string $ref = '', $context = null): bool
|
||||
{
|
||||
$valid = parent::validate($stack, $skip, $ref, $context);
|
||||
|
||||
if (Generator::isDefault($this->description) && Generator::isDefault($this->ref)) {
|
||||
$this->_context->logger->warning($this->identity() . ' One of description or ref is required');
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,495 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* The definition of input and output data types.
|
||||
*
|
||||
* These types can be objects, but also primitives and arrays.
|
||||
*
|
||||
* This object is based on the [JSON Schema Specification](http://json-schema.org) and uses a predefined subset of it.
|
||||
* On top of this subset, there are extensions provided by this specification to allow for more complete documentation.
|
||||
*
|
||||
* @see [OAI Schema Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#schemaObject)
|
||||
* @see [JSON Schema](http://json-schema.org/)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class Schema extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* The relative or absolute path to the endpoint.
|
||||
*
|
||||
* @see [Using refs](https://swagger.io/docs/specification/using-ref/)
|
||||
*
|
||||
* @var string|class-string|object
|
||||
*/
|
||||
public $ref = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The key into Components->schemas array.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $schema = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Can be used to decorate a user interface with information about the data produced by this user interface.
|
||||
*
|
||||
* Preferably short; use <code>description</code> for more details.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $title = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A description will provide explanation about the purpose of the instance described by this schema.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The maximum number of properties allowed in an object instance.
|
||||
* An object instance is valid against this property if its number of properties is less than, or equal to, the value of this attribute.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $maxProperties = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The minimum number of properties allowed in an object instance.
|
||||
* An object instance is valid against this property if its number of properties is greater than, or equal to, the value of this attribute.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $minProperties = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An object instance is valid against this property if its property set contains all elements in this property's
|
||||
* array value.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public $required = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A collection of properties to define for an object.
|
||||
*
|
||||
* Each property is represented as an instance of the <a href="#property">Property</a> class.
|
||||
*
|
||||
* @var Property[]
|
||||
*/
|
||||
public $properties = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The type of the schema/property.
|
||||
*
|
||||
* OpenApi v3.0: The value MUST be one of "string", "number", "integer", "boolean", "array" or "object".
|
||||
*
|
||||
* Since OpenApi v3.1 an array of types may be used.
|
||||
*
|
||||
* @var string|non-empty-array<string>
|
||||
*/
|
||||
public $type = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The extending format for the previously mentioned type. See Data Type Formats for further details.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $format = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Required if type is "array". Describes the type of items in the array.
|
||||
*
|
||||
* @var Items
|
||||
*/
|
||||
public $items = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Determines the format of the array if type array is used.
|
||||
*
|
||||
* Possible values are:
|
||||
* - csv: comma separated values foo,bar.
|
||||
* - ssv: space separated values foo bar.
|
||||
* - tsv: tab separated values foo\tbar.
|
||||
* - pipes: pipe separated values foo|bar.
|
||||
* - multi: corresponds to multiple parameter instances instead of multiple values for a single instance foo=bar&foo=baz.
|
||||
* This is valid only for parameters of type <code>query</code> or <code>formData</code>.
|
||||
* Default value is csv.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $collectionFormat = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Sets a default value to the parameter. The type of the value depends on the defined type.
|
||||
*
|
||||
* @see [JSON schema validation](http://json-schema.org/latest/json-schema-validation.html#anchor101)
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $default = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The maximum value allowed for a numeric property. This value must be a number.
|
||||
*
|
||||
* @see [JSON schema validation](http://json-schema.org/latest/json-schema-validation.html#anchor17)
|
||||
*
|
||||
* @var int|float
|
||||
*/
|
||||
public $maximum = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A boolean indicating whether the maximum value is excluded from the set of valid values.
|
||||
*
|
||||
* When set to true, the maximum value is excluded, and when false or not specified, it is included.
|
||||
*
|
||||
* @see [JSON schema validation](http://json-schema.org/latest/json-schema-validation.html#anchor17)
|
||||
*
|
||||
* @var bool|int|float
|
||||
*/
|
||||
public $exclusiveMaximum = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The minimum value allowed for a numeric property. This value must be a number.
|
||||
*
|
||||
* @see [JSON schema validation](http://json-schema.org/latest/json-schema-validation.html#anchor21)
|
||||
*
|
||||
* @var int|float
|
||||
*/
|
||||
public $minimum = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A boolean indicating whether the minimum value is excluded from the set of valid values.
|
||||
*
|
||||
* When set to true, the minimum value is excluded, and when false or not specified, it is included.
|
||||
*
|
||||
* @see [JSON schema validation](http://json-schema.org/latest/json-schema-validation.html#anchor21)
|
||||
*
|
||||
* @var bool|int|float
|
||||
*/
|
||||
public $exclusiveMinimum = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The maximum length of a string property.
|
||||
*
|
||||
* A string instance is valid against this property if its length is less than, or equal to, the value of this attribute.
|
||||
*
|
||||
* @see [JSON schema validation](http://json-schema.org/latest/json-schema-validation.html#anchor26)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $maxLength = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The minimum length of a string property.
|
||||
*
|
||||
* A string instance is valid against this property if its length is greater than, or equal to, the value of this attribute.
|
||||
*
|
||||
* @see [JSON schema validation](http://json-schema.org/latest/json-schema-validation.html#anchor29)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $minLength = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A string instance is considered valid if the regular expression matches the instance successfully.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $pattern = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The maximum number of items allowed in an array property.
|
||||
*
|
||||
* An array instance is valid against this property if its number of items is less than, or equal to, the value of this attribute.
|
||||
*
|
||||
* @see [JSON schema validation](http://json-schema.org/latest/json-schema-validation.html#anchor42)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $maxItems = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The minimum number of items allowed in an array property.
|
||||
*
|
||||
* An array instance is valid against this property if its number of items is greater than, or equal to, the value of this attribute.
|
||||
*
|
||||
* @see [JSON schema validation](http://json-schema.org/latest/json-schema-validation.html#anchor45)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $minItems = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A boolean value indicating whether all items in an array property must be unique.
|
||||
*
|
||||
* If this attribute is set to true, then all items in the array must be unique.
|
||||
*
|
||||
* @see [JSON schema validation](http://json-schema.org/latest/json-schema-validation.html#anchor49)
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $uniqueItems = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A collection of allowable values for a property.
|
||||
*
|
||||
* A property instance is valid against this attribute if its value is one of the values specified in this collection.
|
||||
*
|
||||
* @see [JSON schema validation](http://json-schema.org/latest/json-schema-validation.html#anchor76)
|
||||
*
|
||||
* @var string[]|int[]|float[]|bool[]|\UnitEnum[]|class-string
|
||||
*/
|
||||
public $enum = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A numeric instance is valid against "multipleOf" if the result of the division of the instance by this
|
||||
* property's value is an integer.
|
||||
*
|
||||
* @var int|float
|
||||
*/
|
||||
public $multipleOf = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Adds support for polymorphism.
|
||||
*
|
||||
* The discriminator is an object name that is used to differentiate between other schemas which may satisfy the
|
||||
* payload description. See Composition and Inheritance for more details.
|
||||
*
|
||||
* @var Discriminator
|
||||
*/
|
||||
public $discriminator = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Declares the property as "read only".
|
||||
*
|
||||
* Relevant only for Schema "properties" definitions.
|
||||
*
|
||||
* This means that it may be sent as part of a response but should not be sent as part of the request.
|
||||
* If the property is marked as readOnly being true and is in the required list, the required will take effect on
|
||||
* the response only. A property must not be marked as both readOnly and writeOnly being true. Default value is
|
||||
* false.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $readOnly = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Declares the property as "write only".
|
||||
*
|
||||
* Relevant only for Schema "properties" definitions.
|
||||
* Therefore, it may be sent as part of a request but should not be sent as part of the response.
|
||||
* If the property is marked as writeOnly being true and is in the required list, the required will take effect on
|
||||
* the request only. A property must not be marked as both readOnly and writeOnly being true. Default value is
|
||||
* false.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $writeOnly = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* This may be used only on properties schemas.
|
||||
*
|
||||
* It has no effect on root schemas.
|
||||
* Adds additional metadata to describe the XML representation of this property.
|
||||
*
|
||||
* @var Xml
|
||||
*/
|
||||
public $xml = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Additional external documentation for this schema.
|
||||
*
|
||||
* @var ExternalDocumentation
|
||||
*/
|
||||
public $externalDocs = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A free-form property to include an example of an instance for this schema.
|
||||
*
|
||||
* To represent examples that cannot naturally be represented in JSON or YAML, a string value can be used to
|
||||
* contain the example with escaping where necessary.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $example = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Allows sending a null value for the defined schema.
|
||||
* Default value is false.
|
||||
*
|
||||
* This must not be used when using OpenApi version 3.1,
|
||||
* instead make the "type" property an array and add "null" as a possible type.
|
||||
*
|
||||
* @var bool
|
||||
*
|
||||
* @see https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0
|
||||
*/
|
||||
public $nullable = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Specifies that a schema is deprecated and should be transitioned out of usage.
|
||||
* Default value is false.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $deprecated = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An instance validates successfully against this property if it validates successfully against all schemas
|
||||
* defined by this property's value.
|
||||
*
|
||||
* @var array<Schema|\OpenApi\Attributes\Schema>
|
||||
*/
|
||||
public $allOf = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An instance validates successfully against this property if it validates successfully against at least one
|
||||
* schema defined by this property's value.
|
||||
*
|
||||
* @var array<Schema|\OpenApi\Attributes\Schema>
|
||||
*/
|
||||
public $anyOf = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An instance validates successfully against this property if it validates successfully against exactly one schema
|
||||
* defined by this property's value.
|
||||
*
|
||||
* @var array<Schema|\OpenApi\Attributes\Schema>
|
||||
*/
|
||||
public $oneOf = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.29.
|
||||
*/
|
||||
public $not = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* http://json-schema.org/latest/json-schema-validation.html#anchor64.
|
||||
*
|
||||
* @var bool|AdditionalProperties
|
||||
*/
|
||||
public $additionalProperties = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.10.
|
||||
*/
|
||||
public $additionalItems = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.14.
|
||||
*/
|
||||
public $contains = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.19.
|
||||
*/
|
||||
public $patternProperties = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.21.
|
||||
*/
|
||||
public $dependencies = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.22.
|
||||
*/
|
||||
public $propertyNames = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* http://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.6.1.3.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $const = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'title' => 'string',
|
||||
'description' => 'string',
|
||||
'required' => '[string]',
|
||||
'format' => 'string',
|
||||
'collectionFormat' => ['csv', 'ssv', 'tsv', 'pipes', 'multi'],
|
||||
'maximum' => 'number',
|
||||
'exclusiveMaximum' => 'boolean|integer|number',
|
||||
'minimum' => 'number',
|
||||
'exclusiveMinimum' => 'boolean|integer|number',
|
||||
'maxLength' => 'integer',
|
||||
'minLength' => 'integer',
|
||||
'pattern' => 'string',
|
||||
'maxItems' => 'integer',
|
||||
'minItems' => 'integer',
|
||||
'uniqueItems' => 'boolean',
|
||||
'multipleOf' => 'integer',
|
||||
'allOf' => '[' . Schema::class . ']',
|
||||
'oneOf' => '[' . Schema::class . ']',
|
||||
'anyOf' => '[' . Schema::class . ']',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Discriminator::class => 'discriminator',
|
||||
Items::class => 'items',
|
||||
Property::class => ['properties', 'property'],
|
||||
ExternalDocumentation::class => 'externalDocs',
|
||||
Xml::class => 'xml',
|
||||
AdditionalProperties::class => 'additionalProperties',
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
Components::class,
|
||||
Parameter::class,
|
||||
PathParameter::class,
|
||||
MediaType::class,
|
||||
Header::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
$data = parent::jsonSerialize();
|
||||
|
||||
if (isset($data->const)) {
|
||||
if ($this->_context->isVersion(OpenApi::VERSION_3_0_0)) {
|
||||
$data->enum = [$data->const];
|
||||
unset($data->const);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function validate(array $stack = [], array $skip = [], string $ref = '', $context = null): bool
|
||||
{
|
||||
if ($this->type === 'array' && Generator::isDefault($this->items)) {
|
||||
$this->_context->logger->warning('@OA\\Items() is required when ' . $this->identity() . ' has type "array" in ' . $this->_context);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::validate($stack, $skip, $ref, $context);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* @see [OAI Security Scheme Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#securitySchemeObject).
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class SecurityScheme extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* The relative or absolute path to a security scheme.
|
||||
*
|
||||
* @see [Using refs](https://swagger.io/docs/specification/using-ref/)
|
||||
*
|
||||
* @var string|class-string|object
|
||||
*/
|
||||
public $ref = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The key into OpenApi->security array.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $securityScheme = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The type of the security scheme.
|
||||
*
|
||||
* @var string|non-empty-array<string>
|
||||
*/
|
||||
public $type = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A short description for security scheme.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The name of the header or query parameter to be used.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Required The location of the API key.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $in = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The flow used by the OAuth2 security scheme.
|
||||
*
|
||||
* @var Flow[]
|
||||
*/
|
||||
public $flows = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A hint to the client to identify how the bearer token is formatted.
|
||||
*
|
||||
* Bearer tokens are usually generated by an authorization server, so this information is primarily for documentation purposes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $bearerFormat = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The name of the HTTP Authorization scheme.
|
||||
*
|
||||
* @see [RFC7235](https://tools.ietf.org/html/rfc7235#section-5.1)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $scheme = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* OpenId Connect URL to discover OAuth2 configuration values. This MUST be in the form of a URL.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $openIdConnectUrl = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_required = ['securityScheme', 'type'];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'type' => ['http', 'apiKey', 'oauth2', 'openIdConnect'],
|
||||
'description' => 'string',
|
||||
'name' => 'string',
|
||||
'bearerFormat' => 'string',
|
||||
'in' => ['query', 'header', 'cookie'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Flow::class => ['flows', 'flow'],
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
Components::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function merge(array $annotations, bool $ignore = false): array
|
||||
{
|
||||
$unmerged = parent::merge($annotations, $ignore);
|
||||
|
||||
if ($this->type === 'oauth2') {
|
||||
$this->name = Generator::UNDEFINED;
|
||||
}
|
||||
|
||||
return $unmerged;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* An object representing a server.
|
||||
*
|
||||
* @see [OAI Server Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#server-object)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class Server extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* An URL to the target host.
|
||||
*
|
||||
* This URL supports Server Variables and may be relative,
|
||||
* to indicate that the host location is relative to the location where the OpenAPI document is being served.
|
||||
* Variable substitutions will be made when a variable is named in {brackets}.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $url = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An optional string describing the host designated by the URL.
|
||||
*
|
||||
* CommonMark syntax may be used for rich text representation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A map between a variable name and its value.
|
||||
*
|
||||
* The value is used for substitution in the server's URL template.
|
||||
*
|
||||
* @var ServerVariable[]
|
||||
*/
|
||||
public $variables = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
OpenApi::class,
|
||||
PathItem::class,
|
||||
Operation::class,
|
||||
Get::class,
|
||||
Post::class,
|
||||
Put::class,
|
||||
Delete::class,
|
||||
Patch::class,
|
||||
Head::class,
|
||||
Options::class,
|
||||
Trace::class,
|
||||
Link::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
ServerVariable::class => ['variables', 'serverVariable'],
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_required = ['url'];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'url' => 'string',
|
||||
'description' => 'string',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* An object representing a server variable for server URL template substitution.
|
||||
*
|
||||
* @see [OAI Server Variable Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#server-variable-object)
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class ServerVariable extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* The key into Server->variables array.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $serverVariable = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An enumeration of values to be used if the substitution options are from a limited set.
|
||||
*
|
||||
* @var string[]|int[]|float[]|bool[]|\UnitEnum[]|class-string
|
||||
*/
|
||||
public $enum = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The default value to use for substitution, and to send, if an alternate value is not supplied.
|
||||
*
|
||||
* Unlike the Schema Object's default, this value must be provided by the consumer.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $default = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A map between a variable name and its value.
|
||||
*
|
||||
* The value is used for substitution in the server's URL template.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $variables = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* An optional description for the server variable.
|
||||
*
|
||||
* CommonMark syntax MAY be used for rich text representation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
Server::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_required = ['default'];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'default' => 'string',
|
||||
'description' => 'string',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* @see [OAI Tag Object]( https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.md#tagObject).
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class Tag extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* The name of the tag.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* A short description for the tag. GFM syntax can be used for rich text representation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Additional external documentation for this tag.
|
||||
*
|
||||
* @var ExternalDocumentation
|
||||
*/
|
||||
public $externalDocs = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_required = ['name'];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'name' => 'string',
|
||||
'description' => 'string',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
OpenApi::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
ExternalDocumentation::class => 'externalDocs',
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*/
|
||||
class Trace extends Operation
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $method = 'trace';
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
PathItem::class,
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* Acts like a `PathItem` with the main difference being that it requires `webhook` instead of `path`.
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class Webhook extends PathItem
|
||||
{
|
||||
/**
|
||||
* Key for the webhooks map.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $webhook = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_required = ['webhook'];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
OpenApi::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'webhook' => 'string',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* @see [OAI XML Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.md#xmlObject).
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class Xml extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* Replaces the name of the element/attribute used for the described schema property.
|
||||
*
|
||||
* When defined within the Items Object (items), it will affect the name of the individual XML elements within the list.
|
||||
* When defined alongside type being array (outside the items), it will affect the wrapping element
|
||||
* and only if wrapped is <code>true</code>.
|
||||
*
|
||||
* If wrapped is <code>false</code>, it will be ignored.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The URL of the namespace definition. Value SHOULD be in the form of a URL.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $namespace = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* The prefix to be used for the name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $prefix = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* Declares whether the property definition translates to an attribute instead of an element.
|
||||
*
|
||||
* Default value is <code>false</code>.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $attribute = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* MAY be used only for an array definition.
|
||||
*
|
||||
* Signifies whether the array is wrapped (for example <code><books><book/><book/></books></code>)
|
||||
* or unwrapped (<code><book/><book/></code>).
|
||||
*
|
||||
* Default value is false. The definition takes effect only when defined alongside type being array (outside the items).
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $wrapped = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_types = [
|
||||
'name' => 'string',
|
||||
'namespace' => 'string',
|
||||
'prefix' => 'string',
|
||||
'attribute' => 'boolean',
|
||||
'wrapped' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [
|
||||
AdditionalProperties::class,
|
||||
Schema::class,
|
||||
Property::class,
|
||||
Schema::class,
|
||||
Items::class,
|
||||
XmlContent::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Annotations;
|
||||
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* Shorthand for a xml response.
|
||||
*
|
||||
* Use as `@OA\Schema` inside a `Response` and `MediaType`->`'application/xml'` will be generated.
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class XmlContent extends Schema
|
||||
{
|
||||
/**
|
||||
* @var array<string,Examples>
|
||||
*/
|
||||
public $examples = Generator::UNDEFINED;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_parents = [];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static $_nested = [
|
||||
Discriminator::class => 'discriminator',
|
||||
Items::class => 'items',
|
||||
Property::class => ['properties', 'property'],
|
||||
ExternalDocumentation::class => 'externalDocs',
|
||||
Xml::class => 'xml',
|
||||
AdditionalProperties::class => 'additionalProperties',
|
||||
Examples::class => ['examples', 'example'],
|
||||
Attachable::class => ['attachables'],
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user