Skip to content

feat: Multiple schema versions #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jul 1, 2025
Merged

Conversation

tymondesigns
Copy link
Contributor

@tymondesigns tymondesigns commented Jun 26, 2025

🎯 Add Multi-Version JSON Schema Support

This PR implements comprehensive support for multiple JSON Schema specification versions, allowing users to choose between Draft 7, Draft 2019-09, and Draft 2020-12.

🚀 Key Features

Multi-Version Schema Support

  • Added SchemaVersion enum with support for:
    • Draft 7 (default) - http://json-schema.org/draft-07/schema#
    • Draft 2019-09 - https://json-schema.org/draft/2019-09/schema
    • Draft 2020-12 - https://json-schema.org/draft/2020-12/schema

Feature-Based Version Validation

  • New SchemaFeature enum cataloging 35+ JSON Schema features across versions
  • Automatic validation that prevents using unsupported features for target versions
  • Runtime feature detection and validation during schema generation

Flexible API Design

  • Direct instantiation: Set version on any schema instance
    $schema = (new ObjectSchema())->version(SchemaVersion::Draft_2020_12);
  • Factory with defaults: Configure default version for all factory-created schemas
    SchemaFactory::setDefaultVersion(SchemaVersion::Draft_2019_09);
    $schema = SchemaFactory::string(); // Uses Draft 2019-09
  • Per-schema override: Override default version for specific schemas
    $schema = SchemaFactory::object('user', SchemaVersion::Draft_2020_12);

JSON Schema Import/Export

  • New JsonConverter for parsing existing JSON Schema documents
  • Automatic version detection from $schema property
  • Full round-trip support: parse JSON Schema → modify → export JSON Schema

🔧 Technical Implementation

Version-Aware Keywords

Schemas automatically use appropriate keywords for their target version:

  • Draft 7: Uses definitions
  • Draft 2019-09+: Uses $defs

Feature Validation System

  • Compile-time validation: Features validated when methods are called
  • Runtime validation: Complete feature validation during toArray()
  • Helpful error messages: Clear guidance on minimum version requirements

Advanced Features by Version

Feature Draft 7 Draft 2019-09 Draft 2020-12
Basic validation
Conditionals (if/then/else)
deprecated annotation
minContains/maxContains
unevaluatedProperties
dependentSchemas
Version-specific formats ✅ (duration, uuid)

📝 Usage Examples

Basic Version Selection

use Cortex\JsonSchema\Enums\SchemaVersion;
use Cortex\JsonSchema\SchemaFactory;

// Set default version
SchemaFactory::setDefaultVersion(SchemaVersion::Draft_2019_09);

// Create schema with default version
$schema = SchemaFactory::object('User');

// Override version for specific schema
$modernSchema = SchemaFactory::string('name', SchemaVersion::Draft_2020_12);

Feature Validation

// This will throw an exception in Draft 7
$schema = SchemaFactory::object('User', SchemaVersion::Draft_07);
$schema->deprecated(); // ❌ SchemaException: Feature not supported

// This works in Draft 2019-09+
$schema = SchemaFactory::object('User', SchemaVersion::Draft_2019_09);
$schema->deprecated(); // ✅ Works

JSON Schema Import

$jsonSchema = [
    '$schema' => 'https://json-schema.org/draft/2019-09/schema',
    'type' => 'object',
    'properties' => [
        'name' => ['type' => 'string'],
        'status' => ['type' => 'string', 'deprecated' => true]
    ]
];

$schema = SchemaFactory::fromJson($jsonSchema);
// Automatically detects and uses Draft 2019-09

🧪 Testing

  • 184 tests with 1103 assertions covering all version scenarios
  • Comprehensive feature validation testing
  • JSON import/export round-trip testing
  • Backward compatibility verification

🔄 Backward Compatibility

  • 100% backward compatible - existing code continues to work unchanged
  • Default version remains Draft 7 for maximum compatibility
  • All existing APIs preserved with optional version parameters

@tymondesigns tymondesigns requested a review from Copilot July 1, 2025 08:26
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR integrates comprehensive multi‐version JSON Schema support using a new SchemaVersion enum and updates to core schema types and factory methods. Key changes include:

  • Adding an optional SchemaVersion parameter to all schema constructors and factory conversion methods.
  • Updating test cases and converters to validate and detect the correct schema version.
  • Enhancing schema feature validations and ensuring version‐specific keyword generation.

Reviewed Changes

Copilot reviewed 40 out of 40 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/Enums/SchemaVersion.php Introduced SchemaVersion enum with cases for Draft 07, Draft 2019-09, and Draft 2020-12.
SchemaFactory.php Updated static methods to accept and use an optional SchemaVersion parameter and default version management.
Various Schema Types (e.g., StringSchema.php, ObjectSchema.php, etc.) Modified constructors to pass SchemaVersion to parent and update toArray() logic accordingly.
Converter classes (e.g., JsonConverter.php, EnumConverter.php) Adjusted conversion logic to propagate SchemaVersion from input or default settings.
Tests (e.g., VersionSupportTest.php, etc.) Updated expectation checks for schema version in output and feature validation testing.
Comments suppressed due to low confidence (2)

src/Converters/EnumConverter.php:45

  • The EnumConverter now passes the SchemaVersion to the constructed schema. Verify that all enum-backed conversions consistently handle the version parameter, and add a comment documenting the supported backing types for clarity.
            'int' => new IntegerSchema($enumName, $this->version),

tests/Unit/VersionSupportTest.php:19

  • [nitpick] The tests correctly validate enum values and names. Consider adding brief comments in the tests to explain the significance of validating different versions, aiding future maintainers in understanding version-dependent behaviors.
    expect(SchemaVersion::Draft_07->value)->toBe('http://json-schema.org/draft-07/schema#');

@tymondesigns tymondesigns marked this pull request as ready for review July 1, 2025 08:29
@tymondesigns tymondesigns merged commit db54642 into main Jul 1, 2025
12 checks passed
@tymondesigns tymondesigns deleted the feat/multiple-versions branch July 1, 2025 08:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant