Skip to content
6 changes: 3 additions & 3 deletions src/Support/Generator/TypeTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,11 @@ public function transform(Type $type): OpenApiType
$openApiType = count($uniqueItems) === 1 ? $uniqueItems[0] : (new AnyOf)->setItems($uniqueItems);
}
} elseif ($type instanceof LiteralStringType) {
$openApiType = (new StringType)->enum([$type->value]);
$openApiType = (new StringType)->constant($type->value);
} elseif ($type instanceof LiteralIntegerType) {
$openApiType = (new IntegerType)->enum([$type->value]);
$openApiType = (new IntegerType)->constant($type->value);
} elseif ($type instanceof LiteralFloatType) {
$openApiType = (new NumberType)->enum([$type->value]);
$openApiType = (new NumberType)->constant($type->value);
} elseif ($type instanceof \Dedoc\Scramble\Support\Type\StringType) {
$openApiType = new StringType;
} elseif ($type instanceof \Dedoc\Scramble\Support\Type\FloatType) {
Expand Down
15 changes: 15 additions & 0 deletions src/Support/Generator/Types/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ abstract class Type

public array $enum = [];

/** @var scalar|null */
public $constant = null;

public bool $nullable = false;

public bool $deprecated = false;
Expand Down Expand Up @@ -113,6 +116,7 @@ public function toArray()
'deprecated' => $this->deprecated,
'pattern' => $this->pattern,
'enum' => count($this->enum) ? $this->enum : null,
'const' => ! is_null($this->constant) ? $this->constant : null,
]),
$this->example instanceof MissingValue ? [] : ['example' => $this->example],
$this->default instanceof MissingValue ? [] : ['default' => $this->default],
Expand Down Expand Up @@ -146,6 +150,17 @@ public function enum(array $enum): self
return $this;
}

/**
* @param scalar $constant
* @return $this
*/
public function constant($constant): self
{
$this->constant = $constant;

return $this;
}

/**
* @param array|scalar|null|MissingValue $example
* @return $this
Expand Down
2 changes: 1 addition & 1 deletion tests/InferExtensions/JsonResourceExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function JsonResourceExtensionTest_analyze(Infer $infer, OpenApiContext $context
],
'value' => [
'type' => 'integer',
'enum' => [42],
'const' => 42,
],
'default' => [
'anyOf' => [
Expand Down
2 changes: 1 addition & 1 deletion tests/ResourceCollectionResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public function index(Request $request)
expect($props = $openApiDocument['paths']['/test']['get']['responses'][200]['content']['application/json']['schema']['properties'])
->toHaveKeys(['data', 'something'])
->and($props['something']['properties'])
->toBe(['foo' => ['type' => 'string', 'enum' => ['bar']]]);
->toBe(['foo' => ['type' => 'string', 'const' => 'bar']]);
});
class AnnotationResourceCollectionResponseTest_Controller
{
Expand Down
4 changes: 2 additions & 2 deletions tests/Support/OperationExtensions/ResponseExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
expect($openApiDocument['paths']['/test']['get']['responses'][200]['content']['application/json']['schema'])
->toHaveKey('type', 'object')
->toHaveKey('properties.foo.type', 'string')
->toHaveKey('properties.foo.enum', ['bar']);
->toHaveKey('properties.foo.const', 'bar');
});
class Foo_ResponseExtensionTest_Controller
{
Expand Down Expand Up @@ -55,7 +55,7 @@ public function foo(): int
'schema' => [
'type' => 'object',
'properties' => [
'foo' => ['type' => 'string', 'enum' => ['bar']],
'foo' => ['type' => 'string', 'const' => 'bar'],
],
'required' => ['foo'],
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
expect($schema->toArray())
->toBe([
'type' => 'string',
'enum' => ['foo'],
'const' => 'foo',
]);
})->skip(! method_exists(Enum::class, 'only'));

Expand All @@ -65,7 +65,7 @@
expect($schema->toArray())
->toBe([
'type' => 'string',
'enum' => ['bar'],
'const' => 'bar',
]);
})->skip(! method_exists(Enum::class, 'except'));
});
Expand Down
4 changes: 2 additions & 2 deletions tests/Support/Type/OffsetSetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public function setC($data)
'bar' => [
'type' => 'integer',
'description' => 'Foo description.',
'enum' => [42],
'const' => 42,
],
],
'required' => ['bar'],
Expand Down Expand Up @@ -186,7 +186,7 @@ public function setC($data)
'bar' => [
'type' => 'integer',
'description' => 'Foo description.',
'enum' => [42],
'const' => 42,
],
],
'required' => ['bar'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
'properties' => [
'id' => [
'type' => 'integer',
'enum' => [42],
'const' => 42,
],
],
'required' => ['id'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@
'properties' => [
'id' => ['type' => 'integer'],
'name' => ['type' => 'string'],
'foo' => ['type' => 'string', 'enum' => ['bar']],
'nested' => ['type' => 'string', 'enum' => ['true']],
'foo' => ['type' => 'string', 'const' => 'bar'],
'nested' => ['type' => 'string', 'const' => 'true'],
],
'required' => ['id', 'name', 'foo', 'nested'],
]],
Expand All @@ -74,7 +74,7 @@
'properties' => [
'id' => ['type' => 'integer'],
'name' => ['type' => 'string'],
'foo' => ['type' => 'string', 'enum' => ['bar']],
'foo' => ['type' => 'string', 'const' => 'bar'],
],
'required' => ['id', 'name', 'foo'],
]],
Expand Down Expand Up @@ -263,7 +263,7 @@ public function toArray(Request $request)
->and($responses['202']['content']['application/json']['schema']['properties']['meta'])
->toBe([
'type' => 'object',
'properties' => ['foo' => ['type' => 'string', 'enum' => ['bar']]],
'properties' => ['foo' => ['type' => 'string', 'const' => 'bar']],
'required' => ['foo'],
]);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
'application/json' => [
'schema' => [
'type' => 'object',
'properties' => ['foo' => ['type' => 'string', 'enum' => ['bar']]],
'properties' => ['foo' => ['type' => 'string', 'const' => 'bar']],
'required' => ['foo'],
],
],
Expand Down
4 changes: 2 additions & 2 deletions tests/TypeToSchemaTransformerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
})->with([
[new IntegerType, ['type' => 'integer']],
[new StringType, ['type' => 'string']],
[new LiteralStringType('wow'), ['type' => 'string', 'enum' => ['wow']]],
[new LiteralFloatType(157.50), ['type' => 'number', 'enum' => [157.5]]],
[new LiteralStringType('wow'), ['type' => 'string', 'const' => 'wow']],
[new LiteralFloatType(157.50), ['type' => 'number', 'const' => 157.5]],
[new BooleanType, ['type' => 'boolean']],
[new MixedType, (object) []],
[new ArrayType(value: new StringType), ['type' => 'array', 'items' => ['type' => 'string']]],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ info:
servers:
- { url: 'http://localhost/api' }
paths:
/test: { get: { operationId: resourceCollectionResponseTest.index, tags: [ResourceCollectionResponseTest_], responses: { 200: { description: '`UserCollection_One`', content: { application/json: { schema: { type: object, properties: { data: { $ref: '#/components/schemas/UserCollection_One' }, something: { type: object, properties: { foo: { type: string, enum: [bar] } }, required: [foo] } }, required: [data, something] } } } } } } }
/test: { get: { operationId: resourceCollectionResponseTest.index, tags: [ResourceCollectionResponseTest_], responses: { 200: { description: '`UserCollection_One`', content: { application/json: { schema: { type: object, properties: { data: { $ref: '#/components/schemas/UserCollection_One' }, something: { type: object, properties: { foo: { type: string, const: bar } }, required: [foo] } }, required: [data, something] } } } } } } }
components:
schemas: { UserCollection_One: { type: object, properties: { foo: { type: string, enum: [bar] }, users: { type: array, items: { $ref: '#/components/schemas/UserResource' } }, meta: { type: object, properties: { foo: { type: string, enum: [bar] } }, required: [foo] } }, required: [foo, users, meta], title: UserCollection_One }, UserResource: { type: object, properties: { id: { type: integer, enum: [1] } }, required: [id], title: UserResource } }
schemas: { UserCollection_One: { type: object, properties: { foo: { type: string, const: bar }, users: { type: array, items: { $ref: '#/components/schemas/UserResource' } }, meta: { type: object, properties: { foo: { type: string, const: bar } }, required: [foo] } }, required: [foo, users, meta], title: UserCollection_One }, UserResource: { type: object, properties: { id: { type: integer, const: 1 } }, required: [id], title: UserResource } }
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ info:
servers:
- { url: 'http://localhost/api' }
paths:
/test: { get: { operationId: resourceCollectionResponseTest.index, tags: [ResourceCollectionResponseTest_], responses: { 200: { description: '`UserCollection_One`', content: { application/json: { schema: { type: object, properties: { data: { $ref: '#/components/schemas/UserCollection_One' }, something: { type: object, properties: { foo: { type: string, enum: [bar] } }, required: [foo] } }, required: [data, something] } } } } } } }
/test: { get: { operationId: resourceCollectionResponseTest.index, tags: [ResourceCollectionResponseTest_], responses: { 200: { description: '`UserCollection_One`', content: { application/json: { schema: { type: object, properties: { data: { $ref: '#/components/schemas/UserCollection_One' }, something: { type: object, properties: { foo: { type: string, const: bar } }, required: [foo] } }, required: [data, something] } } } } } } }
components:
schemas: { UserCollection_One: { type: object, properties: { foo: { type: string, enum: [bar] }, users: { type: array, items: { $ref: '#/components/schemas/UserResource' } }, meta: { type: object, properties: { foo: { type: string, enum: [bar] } }, required: [foo] } }, required: [foo, users, meta], title: UserCollection_One }, UserResource: { type: object, properties: { id: { type: integer, enum: [1] } }, required: [id], title: UserResource } }
schemas: { UserCollection_One: { type: object, properties: { foo: { type: string, const: bar }, users: { type: array, items: { $ref: '#/components/schemas/UserResource' } }, meta: { type: object, properties: { foo: { type: string, const: bar } }, required: [foo] } }, required: [foo, users, meta], title: UserCollection_One }, UserResource: { type: object, properties: { id: { type: integer, const: 1 } }, required: [id], title: UserResource } }
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
description: 'Paginated set of `UserResource`'
content:
application/json: { schema: { type: object, properties: { data: { $ref: '#/components/schemas/UserCollection_Five' }, links: { type: object, properties: { first: { type: [string, 'null'] }, last: { type: [string, 'null'] }, prev: { type: [string, 'null'] }, next: { type: [string, 'null'] }, custom: { type: string, enum: ['https://example.com'] } }, required: [first, last, prev, next, custom] }, meta: { type: object, properties: { current_page: { type: integer, minimum: 1 }, from: { type: [integer, 'null'], minimum: 1 }, last_page: { type: integer, minimum: 1 }, links: { type: array, description: 'Generated paginator links.', items: { type: object, properties: { url: { type: [string, 'null'] }, label: { type: string }, active: { type: boolean } }, required: [url, label, active] } }, path: { type: [string, 'null'], description: 'Base path for paginator generated URLs.' }, per_page: { type: integer, description: 'Number of items shown per page.', minimum: 0 }, to: { type: [integer, 'null'], description: 'Number of the last item in the slice.', minimum: 1 }, total: { type: integer, description: 'Total number of items being paginated.', minimum: 0 } }, required: [current_page, from, last_page, links, path, per_page, to, total] } }, required: [data, links, meta] } }
application/json: { schema: { type: object, properties: { data: { $ref: '#/components/schemas/UserCollection_Five' }, links: { type: object, properties: { first: { type: [string, 'null'] }, last: { type: [string, 'null'] }, prev: { type: [string, 'null'] }, next: { type: [string, 'null'] }, custom: { type: string, const: 'https://example.com' } }, required: [first, last, prev, next, custom] }, meta: { type: object, properties: { current_page: { type: integer, minimum: 1 }, from: { type: [integer, 'null'], minimum: 1 }, last_page: { type: integer, minimum: 1 }, links: { type: array, description: 'Generated paginator links.', items: { type: object, properties: { url: { type: [string, 'null'] }, label: { type: string }, active: { type: boolean } }, required: [url, label, active] } }, path: { type: [string, 'null'], description: 'Base path for paginator generated URLs.' }, per_page: { type: integer, description: 'Number of items shown per page.', minimum: 0 }, to: { type: [integer, 'null'], description: 'Number of the last item in the slice.', minimum: 1 }, total: { type: integer, description: 'Total number of items being paginated.', minimum: 0 } }, required: [current_page, from, last_page, links, path, per_page, to, total] } }, required: [data, links, meta] } }
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
description: 'Paginated set of `UserResource`'
content:
application/json: { schema: { type: object, properties: { data: { $ref: '#/components/schemas/UserCollection_Five' }, links: { type: object, properties: { first: { type: [string, 'null'] }, last: { type: [string, 'null'] }, prev: { type: [string, 'null'] }, next: { type: [string, 'null'] }, custom: { type: string, enum: ['https://example.com'] } }, required: [first, last, prev, next, custom] }, meta: { type: object, properties: { current_page: { type: integer, minimum: 1 }, from: { type: [integer, 'null'], minimum: 1 }, last_page: { type: integer, minimum: 1 }, links: { type: array, description: 'Generated paginator links.', items: { type: object, properties: { url: { type: [string, 'null'] }, label: { type: string }, active: { type: boolean } }, required: [url, label, active] } }, path: { type: [string, 'null'], description: 'Base path for paginator generated URLs.' }, per_page: { type: integer, description: 'Number of items shown per page.', minimum: 0 }, to: { type: [integer, 'null'], description: 'Number of the last item in the slice.', minimum: 1 }, total: { type: integer, description: 'Total number of items being paginated.', minimum: 0 } }, required: [current_page, from, last_page, links, path, per_page, to, total] } }, required: [data, links, meta] } }
application/json: { schema: { type: object, properties: { data: { $ref: '#/components/schemas/UserCollection_Five' }, links: { type: object, properties: { first: { type: [string, 'null'] }, last: { type: [string, 'null'] }, prev: { type: [string, 'null'] }, next: { type: [string, 'null'] }, custom: { type: string, const: 'https://example.com' } }, required: [first, last, prev, next, custom] }, meta: { type: object, properties: { current_page: { type: integer, minimum: 1 }, from: { type: [integer, 'null'], minimum: 1 }, last_page: { type: integer, minimum: 1 }, links: { type: array, description: 'Generated paginator links.', items: { type: object, properties: { url: { type: [string, 'null'] }, label: { type: string }, active: { type: boolean } }, required: [url, label, active] } }, path: { type: [string, 'null'], description: 'Base path for paginator generated URLs.' }, per_page: { type: integer, description: 'Number of items shown per page.', minimum: 0 }, to: { type: [integer, 'null'], description: 'Number of the last item in the slice.', minimum: 1 }, total: { type: integer, description: 'Total number of items being paginated.', minimum: 0 } }, required: [current_page, from, last_page, links, path, per_page, to, total] } }, required: [data, links, meta] } }
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
type: object
properties:
foo: { type: string, enum: [bar] }
foo: { type: string, const: bar }
users: { type: array, items: { $ref: '#/components/schemas/UserResource' } }
meta: { type: object, properties: { foo: { type: string, enum: [bar] } }, required: [foo] }
meta: { type: object, properties: { foo: { type: string, const: bar } }, required: [foo] }
required:
- foo
- users
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
type: object
properties:
foo: { type: string, enum: [bar] }
foo: { type: string, const: bar }
users: { type: array, items: { $ref: '#/components/schemas/UserResource' } }
meta: { type: object, properties: { foo: { type: string, enum: [bar] } }, required: [foo] }
meta: { type: object, properties: { foo: { type: string, const: bar } }, required: [foo] }
required:
- foo
- users
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
type: object
properties:
foo: { type: string, enum: [bar] }
foo: { type: string, const: bar }
users: { type: array, items: { $ref: '#/components/schemas/UserResource' } }
meta: { type: object, properties: { foo: { type: string, enum: [bar] } }, required: [foo] }
meta: { type: object, properties: { foo: { type: string, const: bar } }, required: [foo] }
required:
- foo
- users
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
type: object
properties:
foo: { type: string, enum: [bar] }
foo: { type: string, const: bar }
users: { type: array, items: { $ref: '#/components/schemas/UserResource' } }
meta: { type: object, properties: { foo: { type: string, enum: [bar] } }, required: [foo] }
meta: { type: object, properties: { foo: { type: string, const: bar } }, required: [foo] }
required:
- foo
- users
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ response:
description: '`UserCollection_Three`'
content: { application/json: { schema: { type: object, properties: { data: { $ref: '#/components/schemas/UserCollection_Three' } }, required: [data] } } }
components:
schemas: { UserCollection_Three: { type: array, items: { $ref: '#/components/schemas/UserResource' }, title: UserCollection_Three }, UserResource: { type: object, properties: { id: { type: integer, enum: [1] } }, required: [id], title: UserResource } }
schemas: { UserCollection_Three: { type: array, items: { $ref: '#/components/schemas/UserResource' }, title: UserCollection_Three }, UserResource: { type: object, properties: { id: { type: integer, const: 1 } }, required: [id], title: UserResource } }
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ response:
description: '`UserCollection_Three`'
content: { application/json: { schema: { type: object, properties: { data: { $ref: '#/components/schemas/UserCollection_Three' } }, required: [data] } } }
components:
schemas: { UserCollection_Three: { type: array, items: { $ref: '#/components/schemas/UserResource' }, title: UserCollection_Three }, UserResource: { type: object, properties: { id: { type: integer, enum: [1] } }, required: [id], title: UserResource } }
schemas: { UserCollection_Three: { type: array, items: { $ref: '#/components/schemas/UserResource' }, title: UserCollection_Three }, UserResource: { type: object, properties: { id: { type: integer, const: 1 } }, required: [id], title: UserResource } }
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ response:
description: '`UserCollection_Four`'
content: { application/json: { schema: { type: object, properties: { data: { $ref: '#/components/schemas/UserCollection_Four' } }, required: [data] } } }
components:
schemas: { UserCollection_Four: { type: array, items: { $ref: '#/components/schemas/UserResource' }, title: UserCollection_Four }, UserResource: { type: object, properties: { id: { type: integer, enum: [1] } }, required: [id], title: UserResource } }
schemas: { UserCollection_Four: { type: array, items: { $ref: '#/components/schemas/UserResource' }, title: UserCollection_Four }, UserResource: { type: object, properties: { id: { type: integer, const: 1 } }, required: [id], title: UserResource } }
Loading