diff --git a/docs/reference/annotations.md b/docs/reference/annotations.md
index 2208ec7af..7f5620c58 100644
--- a/docs/reference/annotations.md
+++ b/docs/reference/annotations.md
@@ -956,10 +956,12 @@ An object instance is valid against this property if its number of properties is
- serverVariable : string
The key into Server->variables array.
- - enum : string[]|int[]|float[]|\UnitEnum[]|class-string
+ - enum : string[]|int[]|float[]|bool[]|\UnitEnum[]|class-string
An enumeration of values to be used if the substitution options are from a limited set.
- default : string
The default value to use for substitution, and to send, if an alternate value is not supplied.
diff --git a/docs/reference/attributes.md b/docs/reference/attributes.md
index 292679b09..61c219f96 100644
--- a/docs/reference/attributes.md
+++ b/docs/reference/attributes.md
@@ -44,10 +44,12 @@ array value.
A collection of properties to define for an object.
Each property is represented as an instance of the Property class.
- - type : string|null
+ - type : string|non-empty-array<string>|null
The type of the schema/property.
-The value MUST be one of "string", "number", "integer", "boolean", "array" or "object".
+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.
- format : string|null
The extending format for the previously mentioned type. See Data Type Formats for further details.
- items : OpenApi\Attributes\Items|null
@@ -99,7 +101,7 @@ An array instance is valid against this property if its number of items is great
If this attribute is set to true, then all items in the array must be unique.See: JSON schema validation
- pattern : string|null
A string instance is considered valid if the regular expression matches the instance successfully.
- - enum : string[]|int[]|float[]|\UnitEnum[]|class-string
+ - enum : string[]|int[]|float[]|bool[]|\UnitEnum[]|class-string
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
@@ -139,7 +141,10 @@ To represent examples that cannot naturally be represented in JSON or YAML, a st
contain the example with escaping where necessary.
- nullable : bool|null
Allows sending a null value for the defined schema.
-Default value is false.
+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.
- deprecated : bool|null
Specifies that a schema is deprecated and should be transitioned out of usage.
Default value is false.
@@ -1002,10 +1007,12 @@ array value.
A collection of properties to define for an object.
Each property is represented as an instance of the Property class.
- - type : string|null
+ - type : string|non-empty-array<string>|null
The type of the schema/property.
-The value MUST be one of "string", "number", "integer", "boolean", "array" or "object".
+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.
- format : string|null
The extending format for the previously mentioned type. See Data Type Formats for further details.
- items : OpenApi\Attributes\Items|null
@@ -1057,7 +1064,7 @@ An array instance is valid against this property if its number of items is great
If this attribute is set to true, then all items in the array must be unique.See: JSON schema validation
- pattern : string|null
A string instance is considered valid if the regular expression matches the instance successfully.
- - enum : string[]|int[]|float[]|\UnitEnum[]|class-string
+ - enum : string[]|int[]|float[]|bool[]|\UnitEnum[]|class-string
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
@@ -1097,7 +1104,10 @@ To represent examples that cannot naturally be represented in JSON or YAML, a st
contain the example with escaping where necessary.
- nullable : bool|null
Allows sending a null value for the defined schema.
-Default value is false.
+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.
- deprecated : bool|null
Specifies that a schema is deprecated and should be transitioned out of usage.
Default value is false.
@@ -1160,10 +1170,12 @@ array value.
A collection of properties to define for an object.
Each property is represented as an instance of the Property class.
- - type : string|null
+ - type : string|non-empty-array<string>|null
The type of the schema/property.
-The value MUST be one of "string", "number", "integer", "boolean", "array" or "object".
+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.
- format : string|null
The extending format for the previously mentioned type. See Data Type Formats for further details.
- items : OpenApi\Attributes\Items|null
@@ -1215,7 +1227,7 @@ An array instance is valid against this property if its number of items is great
If this attribute is set to true, then all items in the array must be unique.See: JSON schema validation
- pattern : string|null
A string instance is considered valid if the regular expression matches the instance successfully.
- - enum : string[]|int[]|float[]|\UnitEnum[]|class-string
+ - enum : string[]|int[]|float[]|bool[]|\UnitEnum[]|class-string
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
@@ -1255,7 +1267,10 @@ To represent examples that cannot naturally be represented in JSON or YAML, a st
contain the example with escaping where necessary.
- nullable : bool|null
Allows sending a null value for the defined schema.
-Default value is false.
+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.
- deprecated : bool|null
Specifies that a schema is deprecated and should be transitioned out of usage.
Default value is false.
@@ -2024,10 +2039,12 @@ array value.
A collection of properties to define for an object.
Each property is represented as an instance of the Property class.
- - type : string|null
+ - type : string|non-empty-array<string>|null
The type of the schema/property.
-The value MUST be one of "string", "number", "integer", "boolean", "array" or "object".
+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.
- format : string|null
The extending format for the previously mentioned type. See Data Type Formats for further details.
- items : OpenApi\Attributes\Items|null
@@ -2079,7 +2096,7 @@ An array instance is valid against this property if its number of items is great
If this attribute is set to true, then all items in the array must be unique.See: JSON schema validation
- pattern : string|null
A string instance is considered valid if the regular expression matches the instance successfully.
- - enum : string[]|int[]|float[]|\UnitEnum[]|class-string
+ - enum : string[]|int[]|float[]|bool[]|\UnitEnum[]|class-string
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
@@ -2119,7 +2136,10 @@ To represent examples that cannot naturally be represented in JSON or YAML, a st
contain the example with escaping where necessary.
- nullable : bool|null
Allows sending a null value for the defined schema.
-Default value is false.
+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.
- deprecated : bool|null
Specifies that a schema is deprecated and should be transitioned out of usage.
Default value is false.
@@ -2470,10 +2490,12 @@ array value.
A collection of properties to define for an object.
Each property is represented as an instance of the Property class.
- - type : string|null
+ - type : string|non-empty-array<string>|null
The type of the schema/property.
-The value MUST be one of "string", "number", "integer", "boolean", "array" or "object".
+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.
- format : string|null
The extending format for the previously mentioned type. See Data Type Formats for further details.
- items : OpenApi\Attributes\Items|null
@@ -2525,7 +2547,7 @@ An array instance is valid against this property if its number of items is great
If this attribute is set to true, then all items in the array must be unique.See: JSON schema validation
- pattern : string|null
A string instance is considered valid if the regular expression matches the instance successfully.
- - enum : string[]|int[]|float[]|\UnitEnum[]|class-string
+ - enum : string[]|int[]|float[]|bool[]|\UnitEnum[]|class-string
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
@@ -2565,7 +2587,10 @@ To represent examples that cannot naturally be represented in JSON or YAML, a st
contain the example with escaping where necessary.
- nullable : bool|null
Allows sending a null value for the defined schema.
-Default value is false.
+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.
- deprecated : bool|null
Specifies that a schema is deprecated and should be transitioned out of usage.
Default value is false.
@@ -2610,7 +2635,7 @@ These will be ignored but can be used for custom processing.
The relative or absolute path to a security scheme.
See: Using refs
- securityScheme : string|null
The key into OpenApi->security array.
- - type : string|null
+ - type : string|non-empty-array<string>|null
The type of the security scheme.
- description : string|null
A short description for security scheme.
@@ -2700,7 +2725,7 @@ CommonMark syntax MAY be used for rich text representation.
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.
- - enum : string[]|int[]|float[]|\UnitEnum[]|class-string|null
+ - enum : string[]|int[]|float[]|bool[]|\UnitEnum[]|class-string|null
An enumeration of values to be used if the substitution options are from a limited set.
- variables : array|null
A map between a variable name and its value.
@@ -2918,10 +2943,12 @@ array value.
A collection of properties to define for an object.
Each property is represented as an instance of the Property class.
- - type : string|null
+ - type : string|non-empty-array<string>|null
The type of the schema/property.
-The value MUST be one of "string", "number", "integer", "boolean", "array" or "object".
+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.
- format : string|null
The extending format for the previously mentioned type. See Data Type Formats for further details.
- items : OpenApi\Attributes\Items|null
@@ -2973,7 +3000,7 @@ An array instance is valid against this property if its number of items is great
If this attribute is set to true, then all items in the array must be unique.See: JSON schema validation
- pattern : string|null
A string instance is considered valid if the regular expression matches the instance successfully.
- - enum : string[]|int[]|float[]|\UnitEnum[]|class-string
+ - enum : string[]|int[]|float[]|bool[]|\UnitEnum[]|class-string
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
@@ -3013,7 +3040,10 @@ To represent examples that cannot naturally be represented in JSON or YAML, a st
contain the example with escaping where necessary.
- nullable : bool|null
Allows sending a null value for the defined schema.
-Default value is false.
+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.
- deprecated : bool|null
Specifies that a schema is deprecated and should be transitioned out of usage.
Default value is false.
diff --git a/src/Annotations/Schema.php b/src/Annotations/Schema.php
index 77c818539..fef021819 100644
--- a/src/Annotations/Schema.php
+++ b/src/Annotations/Schema.php
@@ -91,9 +91,11 @@ class Schema extends AbstractAnnotation
/**
* The type of the schema/property.
*
- * The value MUST be one of "string", "number", "integer", "boolean", "array" or "object".
+ * OpenApi v3.0: The value MUST be one of "string", "number", "integer", "boolean", "array" or "object".
*
- * @var string
+ * Since OpenApi v3.1 an array of types may be used.
+ *
+ * @var string|non-empty-array
*/
public $type = Generator::UNDEFINED;
@@ -325,7 +327,12 @@ class Schema extends AbstractAnnotation
* 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;
diff --git a/src/Annotations/SecurityScheme.php b/src/Annotations/SecurityScheme.php
index 2d30e5bc6..631fcec8b 100644
--- a/src/Annotations/SecurityScheme.php
+++ b/src/Annotations/SecurityScheme.php
@@ -34,7 +34,7 @@ class SecurityScheme extends AbstractAnnotation
/**
* The type of the security scheme.
*
- * @var string
+ * @var string|non-empty-array
*/
public $type = Generator::UNDEFINED;
diff --git a/src/Attributes/AdditionalProperties.php b/src/Attributes/AdditionalProperties.php
index ca0ab3f8d..b79e996bd 100644
--- a/src/Attributes/AdditionalProperties.php
+++ b/src/Attributes/AdditionalProperties.php
@@ -12,6 +12,7 @@
class AdditionalProperties extends \OpenApi\Annotations\AdditionalProperties
{
/**
+ * @param string|non-empty-array|null $type
* @param string|class-string|object|null $ref
* @param string[] $required
* @param Property[] $properties
@@ -34,7 +35,7 @@ public function __construct(
?int $minProperties = null,
?array $required = null,
?array $properties = null,
- ?string $type = null,
+ string|array|null $type = null,
?string $format = null,
?Items $items = null,
?string $collectionFormat = null,
diff --git a/src/Attributes/Items.php b/src/Attributes/Items.php
index ad8f3606c..ca1190f67 100644
--- a/src/Attributes/Items.php
+++ b/src/Attributes/Items.php
@@ -12,6 +12,7 @@
class Items extends \OpenApi\Annotations\Items
{
/**
+ * @param string|non-empty-array|null $type
* @param string|class-string|object|null $ref
* @param string[] $required
* @param Property[] $properties
@@ -34,7 +35,7 @@ public function __construct(
?int $minProperties = null,
?array $required = null,
?array $properties = null,
- ?string $type = null,
+ string|array|null $type = null,
?string $format = null,
?Items $items = null,
?string $collectionFormat = null,
diff --git a/src/Attributes/JsonContent.php b/src/Attributes/JsonContent.php
index e10c605d7..e65a50dab 100644
--- a/src/Attributes/JsonContent.php
+++ b/src/Attributes/JsonContent.php
@@ -12,6 +12,7 @@
class JsonContent extends \OpenApi\Annotations\JsonContent
{
/**
+ * @param string|non-empty-array|null $type
* @param string|class-string|object|null $ref
* @param array $examples
* @param string[] $required
@@ -36,7 +37,7 @@ public function __construct(
?int $minProperties = null,
?array $required = null,
?array $properties = null,
- ?string $type = null,
+ string|array|null $type = null,
?string $format = null,
?Items $items = null,
?string $collectionFormat = null,
diff --git a/src/Attributes/Property.php b/src/Attributes/Property.php
index a3e2916c2..25c5c87d8 100644
--- a/src/Attributes/Property.php
+++ b/src/Attributes/Property.php
@@ -12,6 +12,7 @@
class Property extends \OpenApi\Annotations\Property
{
/**
+ * @param string|non-empty-array|null $type
* @param string|class-string|object|null $ref
* @param string[] $required
* @param Property[] $properties
@@ -35,7 +36,7 @@ public function __construct(
?int $minProperties = null,
?array $required = null,
?array $properties = null,
- ?string $type = null,
+ string|array|null $type = null,
?string $format = null,
?Items $items = null,
?string $collectionFormat = null,
diff --git a/src/Attributes/Schema.php b/src/Attributes/Schema.php
index 3437bbc5a..84b1a1476 100644
--- a/src/Attributes/Schema.php
+++ b/src/Attributes/Schema.php
@@ -12,6 +12,7 @@
class Schema extends \OpenApi\Annotations\Schema
{
/**
+ * @param string|non-empty-array|null $type
* @param string|class-string|object|null $ref
* @param string[] $required
* @param Property[] $properties
@@ -35,7 +36,7 @@ public function __construct(
?int $minProperties = null,
?array $required = null,
?array $properties = null,
- ?string $type = null,
+ string|array|null $type = null,
?string $format = null,
?Items $items = null,
?string $collectionFormat = null,
diff --git a/src/Attributes/SecurityScheme.php b/src/Attributes/SecurityScheme.php
index ea98cab90..e43c274bd 100644
--- a/src/Attributes/SecurityScheme.php
+++ b/src/Attributes/SecurityScheme.php
@@ -12,15 +12,16 @@
class SecurityScheme extends \OpenApi\Annotations\SecurityScheme
{
/**
- * @param string|class-string|object|null $ref
- * @param Flow[] $flows
- * @param array|null $x
- * @param Attachable[]|null $attachables
+ * @param string|non-empty-array|null $type
+ * @param string|class-string|object|null $ref
+ * @param Flow[] $flows
+ * @param array|null $x
+ * @param Attachable[]|null $attachables
*/
public function __construct(
string|object|null $ref = null,
?string $securityScheme = null,
- ?string $type = null,
+ string|array|null $type = null,
?string $description = null,
?string $name = null,
?string $in = null,
diff --git a/src/Attributes/XmlContent.php b/src/Attributes/XmlContent.php
index b4035994d..45f03590a 100644
--- a/src/Attributes/XmlContent.php
+++ b/src/Attributes/XmlContent.php
@@ -12,6 +12,7 @@
class XmlContent extends \OpenApi\Annotations\XmlContent
{
/**
+ * @param string|non-empty-array|null $type
* @param string|class-string|object|null $ref
* @param array $examples
* @param string[] $required
@@ -36,7 +37,7 @@ public function __construct(
?int $minProperties = null,
?array $required = null,
?array $properties = null,
- ?string $type = null,
+ string|array|null $type = null,
?string $format = null,
?Items $items = null,
?string $collectionFormat = null,
diff --git a/src/Processors/AugmentProperties.php b/src/Processors/AugmentProperties.php
index 395ac8c28..68e575c0f 100644
--- a/src/Processors/AugmentProperties.php
+++ b/src/Processors/AugmentProperties.php
@@ -51,7 +51,9 @@ public function __invoke(Analysis $analysis)
if (Generator::isDefault($property->type)) {
$this->augmentType($analysis, $property, $context, $refs, $typeAndDescription['type']);
} else {
- $this->mapNativeType($property, $property->type);
+ if (!is_array($property->type)) {
+ $this->mapNativeType($property, $property->type);
+ }
}
if (Generator::isDefault($property->description) && $typeAndDescription['description']) {
@@ -129,7 +131,7 @@ protected function augmentType(Analysis $analysis, OA\Property $property, Contex
if (Generator::isDefault($property->ref) && array_key_exists($refKey, $refs)) {
$this->applyRef($analysis, $property, $refs[$refKey]);
} else {
- if ($typeSchema = $analysis->getSchemaForSource($context->type)) {
+ if (is_string($context->type) && $typeSchema = $analysis->getSchemaForSource($context->type)) {
if (Generator::isDefault($property->format)) {
$property->ref = OA\Components::ref($typeSchema);
$property->type = Generator::UNDEFINED;
diff --git a/src/Processors/AugmentSchemas.php b/src/Processors/AugmentSchemas.php
index 47952b0c6..a07b2aa30 100644
--- a/src/Processors/AugmentSchemas.php
+++ b/src/Processors/AugmentSchemas.php
@@ -103,7 +103,7 @@ protected function augmentType(Analysis $analysis, array $schemas): void
$schema->type = 'object';
}
} else {
- if ($typeSchema = $analysis->getSchemaForSource($schema->type)) {
+ if (is_string($schema->type) && $typeSchema = $analysis->getSchemaForSource($schema->type)) {
if (Generator::isDefault($schema->format)) {
$schema->ref = OA\Components::ref($typeSchema);
$schema->type = Generator::UNDEFINED;
diff --git a/tests/Fixtures/Scratch/Nullable.php b/tests/Fixtures/Scratch/Nullable.php
index f86289285..f840e646f 100644
--- a/tests/Fixtures/Scratch/Nullable.php
+++ b/tests/Fixtures/Scratch/Nullable.php
@@ -44,6 +44,9 @@ class Nullable
#[OAT\Property]
public MyDateTime|null $anotherdate;
+
+ #[OAT\Property(type: ['string', 'null'])]
+ public ?string $description;
}
#[OAT\Get(
diff --git a/tests/Fixtures/Scratch/Nullable.yaml b/tests/Fixtures/Scratch/Nullable.yaml
index 0971e208a..b6c546ce1 100644
--- a/tests/Fixtures/Scratch/Nullable.yaml
+++ b/tests/Fixtures/Scratch/Nullable.yaml
@@ -47,4 +47,8 @@ components:
$ref: '#/components/schemas/MyDateTime'
-
type: 'null'
+ description:
+ type:
+ - string
+ - 'null'
type: object
diff --git a/tests/Fixtures/Scratch/Types31.php b/tests/Fixtures/Scratch/Types31.php
new file mode 100644
index 000000000..04a473f0b
--- /dev/null
+++ b/tests/Fixtures/Scratch/Types31.php
@@ -0,0 +1,33 @@
+