Skip to content

Commit db54642

Browse files
authored
feat: Multiple schema versions (#9)
1 parent 37e27d0 commit db54642

40 files changed

+4674
-77
lines changed

README.md

Lines changed: 353 additions & 4 deletions
Large diffs are not rendered by default.

ecs.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
])
2727
->withRootFiles()
2828
->withSpacing(indentation: Option::INDENTATION_SPACES)
29+
->withEditorConfig()
2930
->withPreparedSets(
3031
psr12: true,
3132
common: true,

src/Contracts/Schema.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace Cortex\JsonSchema\Contracts;
66

7+
use Cortex\JsonSchema\Enums\SchemaVersion;
8+
79
interface Schema
810
{
911
/**
@@ -76,4 +78,14 @@ public function validate(mixed $value): void;
7678
* Determine if the given value is valid against the schema.
7779
*/
7880
public function isValid(mixed $value): bool;
81+
82+
/**
83+
* Set the JSON Schema version for this schema.
84+
*/
85+
public function version(SchemaVersion $schemaVersion): static;
86+
87+
/**
88+
* Get the JSON Schema version for this schema.
89+
*/
90+
public function getVersion(): SchemaVersion;
7991
}

src/Converters/ClassConverter.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Cortex\JsonSchema\Support\DocParser;
1414
use Cortex\JsonSchema\Types\ObjectSchema;
1515
use Cortex\JsonSchema\Contracts\Converter;
16+
use Cortex\JsonSchema\Enums\SchemaVersion;
1617
use Cortex\JsonSchema\Converters\Concerns\InteractsWithTypes;
1718

1819
class ClassConverter implements Converter
@@ -30,13 +31,15 @@ class ClassConverter implements Converter
3031
public function __construct(
3132
protected object|string $class,
3233
protected bool $publicOnly = true,
34+
protected ?SchemaVersion $version = null,
3335
) {
3436
$this->reflection = new ReflectionClass($this->class);
37+
$this->version = $version ?? SchemaVersion::default();
3538
}
3639

3740
public function convert(): ObjectSchema
3841
{
39-
$objectSchema = new ObjectSchema();
42+
$objectSchema = new ObjectSchema(schemaVersion: $this->version);
4043

4144
// Get the description from the doc parser
4245
$description = $this->getDocParser($this->reflection)?->description() ?? null;

src/Converters/ClosureConverter.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Cortex\JsonSchema\Support\DocParser;
1515
use Cortex\JsonSchema\Types\ObjectSchema;
1616
use Cortex\JsonSchema\Contracts\Converter;
17+
use Cortex\JsonSchema\Enums\SchemaVersion;
1718
use Cortex\JsonSchema\Support\NodeCollection;
1819
use Cortex\JsonSchema\Converters\Concerns\InteractsWithTypes;
1920

@@ -25,13 +26,15 @@ class ClosureConverter implements Converter
2526

2627
public function __construct(
2728
protected Closure $closure,
29+
protected ?SchemaVersion $version = null,
2830
) {
2931
$this->reflection = new ReflectionFunction($this->closure);
32+
$this->version = $version ?? SchemaVersion::default();
3033
}
3134

3235
public function convert(): ObjectSchema
3336
{
34-
$objectSchema = new ObjectSchema();
37+
$objectSchema = new ObjectSchema(schemaVersion: $this->version);
3538

3639
// Get the description from the doc parser
3740
$description = $this->getDocParser()?->description() ?? null;

src/Converters/Concerns/InteractsWithTypes.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,31 @@ trait InteractsWithTypes
1818
/**
1919
* Resolve the schema instance from the given reflection type.
2020
*/
21-
protected static function getSchemaFromReflectionType(
21+
protected function getSchemaFromReflectionType(
2222
ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null $type,
2323
): Schema {
2424
$schemaTypes = match (true) {
2525
$type instanceof ReflectionUnionType, $type instanceof ReflectionIntersectionType => array_map(
2626
// @phpstan-ignore argument.type
27-
fn(ReflectionNamedType $reflectionNamedType): SchemaType => self::resolveSchemaType(
27+
fn(ReflectionNamedType $reflectionNamedType): SchemaType => $this->resolveSchemaType(
2828
$reflectionNamedType,
2929
),
3030
$type->getTypes(),
3131
),
3232
// If the parameter is not typed or explicitly typed as mixed, we use all schema types
3333
in_array($type?->getName(), ['mixed', null], true) => SchemaType::cases(),
34-
default => [self::resolveSchemaType($type)],
34+
default => [$this->resolveSchemaType($type)],
3535
};
3636

3737
return count($schemaTypes) === 1
38-
? $schemaTypes[0]->instance()
39-
: new UnionSchema(array_values($schemaTypes));
38+
? $schemaTypes[0]->instance(null, $this->version)
39+
: new UnionSchema(array_values($schemaTypes), null, $this->version);
4040
}
4141

4242
/**
4343
* Resolve the schema type from the given reflection type.
4444
*/
45-
protected static function resolveSchemaType(ReflectionNamedType $reflectionNamedType): SchemaType
45+
protected function resolveSchemaType(ReflectionNamedType $reflectionNamedType): SchemaType
4646
{
4747
$typeName = $reflectionNamedType->getName();
4848

src/Converters/EnumConverter.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Cortex\JsonSchema\Support\DocParser;
99
use Cortex\JsonSchema\Types\StringSchema;
1010
use Cortex\JsonSchema\Contracts\Converter;
11+
use Cortex\JsonSchema\Enums\SchemaVersion;
1112
use Cortex\JsonSchema\Types\IntegerSchema;
1213
use Cortex\JsonSchema\Exceptions\SchemaException;
1314

@@ -23,8 +24,10 @@ class EnumConverter implements Converter
2324
*/
2425
public function __construct(
2526
protected string $enum,
27+
protected ?SchemaVersion $version = null,
2628
) {
2729
$this->reflection = new ReflectionEnum($this->enum);
30+
$this->version = $version ?? SchemaVersion::default();
2831

2932
if (! $this->reflection->isBacked()) {
3033
throw new SchemaException('Enum must be a backed enum');
@@ -38,8 +41,8 @@ public function convert(): StringSchema|IntegerSchema
3841

3942
// Determine the backing type
4043
$schema = match ($this->reflection->getBackingType()?->getName()) {
41-
'string' => new StringSchema($enumName),
42-
'int' => new IntegerSchema($enumName),
44+
'string' => new StringSchema($enumName, $this->version),
45+
'int' => new IntegerSchema($enumName, $this->version),
4346
default => throw new SchemaException(
4447
'Unsupported enum backing type. Only "int" or "string" are supported.',
4548
),

0 commit comments

Comments
 (0)