From 4934d7e0ca25ede026abc397caf1a39882f72df3 Mon Sep 17 00:00:00 2001 From: Sean Tymon Date: Mon, 26 Jan 2026 21:24:22 +0000 Subject: [PATCH 1/3] docs: Small updates --- docs/assets/favicon.svg | 13 +++++++ docs/docs.json | 17 +++------ .../advanced/conditional-validation.mdx | 6 +-- .../json-schema/advanced/definitions-refs.mdx | 10 ++--- .../advanced/dependent-schemas.mdx | 4 +- .../advanced/pattern-properties.mdx | 4 +- docs/json-schema/advanced/string-formats.mdx | 4 +- .../advanced/unevaluated-properties.mdx | 4 +- .../code-generation/from-classes.mdx | 6 +-- .../code-generation/from-closures.mdx | 2 +- .../code-generation/from-enums.mdx | 2 +- .../json-schema/code-generation/from-json.mdx | 6 +-- docs/json-schema/introduction.mdx | 27 +++++-------- docs/json-schema/quickstart.mdx | 38 +------------------ docs/json-schema/schema-types/array.mdx | 2 +- docs/json-schema/schema-types/boolean.mdx | 4 +- docs/json-schema/schema-types/integer.mdx | 4 +- docs/json-schema/schema-types/null.mdx | 2 +- docs/json-schema/schema-types/number.mdx | 2 +- docs/json-schema/schema-types/object.mdx | 10 ++++- docs/json-schema/schema-types/string.mdx | 4 +- docs/json-schema/schema-types/union.mdx | 2 +- 22 files changed, 71 insertions(+), 102 deletions(-) create mode 100644 docs/assets/favicon.svg diff --git a/docs/assets/favicon.svg b/docs/assets/favicon.svg new file mode 100644 index 0000000..3d52675 --- /dev/null +++ b/docs/assets/favicon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/docs/docs.json b/docs/docs.json index c124427..1b70cfa 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -1,20 +1,20 @@ { "$schema": "https://mintlify.com/docs.json", - "theme": "aspen", + "theme": "palm", "name": "CortexPHP", "colors": { "primary": "#1C85FE", "light": "#1C85FE", "dark": "#1C85FE" }, - "favicon": "/favicon.svg", + "favicon": "/assets/favicon.svg", "icons": { "library": "lucide" }, "navigation": { - "dropdowns": [ + "products": [ { - "dropdown": "JSON Schema", + "product": "JSON Schema", "icon": "braces", "groups": [ { @@ -76,18 +76,13 @@ "light": "/assets/logo-light.svg", "dark": "/assets/logo-dark.svg" }, - "navbar": { - "primary": { - "type": "github", - "href": "https://github.com/cortexphp/json-schema" - } - }, "contextual": { "options": ["copy", "view", "chatgpt", "claude"] }, "footer": { "socials": { - "github": "https://github.com/cortexphp" + "github": "https://github.com/cortexphp", + "x": "https://twitter.com/cortexphp" } } } diff --git a/docs/json-schema/advanced/conditional-validation.mdx b/docs/json-schema/advanced/conditional-validation.mdx index 004cd17..231cdf0 100644 --- a/docs/json-schema/advanced/conditional-validation.mdx +++ b/docs/json-schema/advanced/conditional-validation.mdx @@ -618,13 +618,13 @@ $complexSchema = Schema::object('complex_validation') Different validation rules for personal vs business accounts, or basic vs premium users. - + Validate different payment types with their specific required fields and formats. - + Forms where required fields change based on user selections or enabled features. - + Different validation rules for different API versions or client types. diff --git a/docs/json-schema/advanced/definitions-refs.mdx b/docs/json-schema/advanced/definitions-refs.mdx index 38ca420..82663a6 100644 --- a/docs/json-schema/advanced/definitions-refs.mdx +++ b/docs/json-schema/advanced/definitions-refs.mdx @@ -443,10 +443,10 @@ $ecommerceApiSchema = Schema::object('ecommerce_api') Update shared schemas in one place and have changes propagate throughout your API. - + Ensure consistent validation rules across different parts of your application. - + Break complex schemas into manageable, reusable components. @@ -526,13 +526,13 @@ $schema->addDefinition( ## Common Use Cases - + Create reusable components for API request/response schemas across multiple endpoints. - + Define common business objects like User, Product, Order that are used throughout your application. - + Share configuration patterns across different parts of your application configuration. diff --git a/docs/json-schema/advanced/dependent-schemas.mdx b/docs/json-schema/advanced/dependent-schemas.mdx index 43abe3f..fc40587 100644 --- a/docs/json-schema/advanced/dependent-schemas.mdx +++ b/docs/json-schema/advanced/dependent-schemas.mdx @@ -553,10 +553,10 @@ $schema->dependentSchemas([ Forms where available fields and validation rules change based on user selections. - + Configuration objects where certain settings require additional parameters. - + Different validation rules for different payment methods and options. diff --git a/docs/json-schema/advanced/pattern-properties.mdx b/docs/json-schema/advanced/pattern-properties.mdx index 5c71f0c..43bd70b 100644 --- a/docs/json-schema/advanced/pattern-properties.mdx +++ b/docs/json-schema/advanced/pattern-properties.mdx @@ -476,13 +476,13 @@ $schema->patternProperties([ ## Common Use Cases - + Configure applications with dynamic settings that follow naming conventions. Validate internationalization data with language-specific property patterns. - + Handle different API versions with version-specific property validation. diff --git a/docs/json-schema/advanced/string-formats.mdx b/docs/json-schema/advanced/string-formats.mdx index e6b4ae4..fefcfd6 100644 --- a/docs/json-schema/advanced/string-formats.mdx +++ b/docs/json-schema/advanced/string-formats.mdx @@ -204,10 +204,10 @@ $userProfileSchema->isValid($validProfile); // true Validate API endpoints, UUIDs, timestamps, and other structured data in API requests. - + Validate URLs, hostnames, IP addresses, and other configuration values. - + Validate formatted data during import processes with appropriate type checking. diff --git a/docs/json-schema/advanced/unevaluated-properties.mdx b/docs/json-schema/advanced/unevaluated-properties.mdx index cff31ad..c46b88f 100644 --- a/docs/json-schema/advanced/unevaluated-properties.mdx +++ b/docs/json-schema/advanced/unevaluated-properties.mdx @@ -413,13 +413,13 @@ $schema = Schema::object('strict_user', SchemaVersion::Draft_2019_09) Ensure API requests/responses contain only expected properties, even with conditional fields. - + Validate configuration files with complex conditional requirements and strict property control. Handle dynamic forms where available fields depend on user selections or conditions. - + Validate data during migration with strict control over allowed properties and transformations. diff --git a/docs/json-schema/code-generation/from-classes.mdx b/docs/json-schema/code-generation/from-classes.mdx index dd92a73..30e980f 100644 --- a/docs/json-schema/code-generation/from-classes.mdx +++ b/docs/json-schema/code-generation/from-classes.mdx @@ -499,16 +499,16 @@ Validation rules like minLength, pattern, format are not extracted from docblock ## Common Use Cases - + Generate OpenAPI schemas from your data transfer objects and API models. Create client-side validation schemas from your backend models. - + Validate data integrity during migrations using existing model definitions. - + Generate schemas for application configuration classes. diff --git a/docs/json-schema/code-generation/from-closures.mdx b/docs/json-schema/code-generation/from-closures.mdx index 3614e05..d76700a 100644 --- a/docs/json-schema/code-generation/from-closures.mdx +++ b/docs/json-schema/code-generation/from-closures.mdx @@ -469,7 +469,7 @@ function handleUserStuff($data, $action, $options = []) {} Validate data transformations and processing steps in data pipelines. - + Generate validation for configuration and setup functions. diff --git a/docs/json-schema/code-generation/from-enums.mdx b/docs/json-schema/code-generation/from-enums.mdx index 2c22a8a..0e915e3 100644 --- a/docs/json-schema/code-generation/from-enums.mdx +++ b/docs/json-schema/code-generation/from-enums.mdx @@ -625,7 +625,7 @@ try { Validate API request parameters and response codes using enumerated values. - + Ensure application configuration uses only valid environment and option values. diff --git a/docs/json-schema/code-generation/from-json.mdx b/docs/json-schema/code-generation/from-json.mdx index 977e3f0..0da532c 100644 --- a/docs/json-schema/code-generation/from-json.mdx +++ b/docs/json-schema/code-generation/from-json.mdx @@ -357,13 +357,13 @@ class CachedSchemaLoader ## Common Use Cases - + Import OpenAPI schemas for request/response validation in API applications. - + Validate application configuration files using predefined JSON schemas. - + Import legacy schemas and validate data during migration processes. diff --git a/docs/json-schema/introduction.mdx b/docs/json-schema/introduction.mdx index 168f515..1d4a388 100644 --- a/docs/json-schema/introduction.mdx +++ b/docs/json-schema/introduction.mdx @@ -13,65 +13,56 @@ icon: 'book-open' Build JSON Schemas using an intuitive fluent interface that feels natural and reduces boilerplate code. Support for JSON Schema Draft-07, Draft 2019-09, and Draft 2020-12 with automatic feature validation. Validate data against schemas with detailed error messages and boolean validation methods. Built with PHP 8.3+ features and strict typing for reliable, maintainable code. Support for if/then/else, allOf, anyOf, oneOf, and not conditions for complex validation logic. Generate schemas automatically from PHP Classes, Enums, and Closures using reflection. Comprehensive validation rules including formats, patterns, ranges, and custom constraints. Automatic validation of version-specific features with helpful error messages. diff --git a/docs/json-schema/quickstart.mdx b/docs/json-schema/quickstart.mdx index c6517b6..97963dd 100644 --- a/docs/json-schema/quickstart.mdx +++ b/docs/json-schema/quickstart.mdx @@ -288,6 +288,7 @@ Schema::setDefaultVersion(SchemaVersion::Draft_07); // For maximum compatibility When `type` is "business", the `company_name` field becomes required. Personal accounts don't need a company name. + Learn more about conditional validation @@ -329,40 +330,3 @@ Schema::setDefaultVersion(SchemaVersion::Draft_07); // For maximum compatibility - -## Next Steps - - - - Learn about all available schema types and their validation options - - - Explore conditional validation, definitions, and complex patterns - - - Generate schemas automatically from PHP classes and functions - - - Master data validation and error handling techniques - - - - -The Schema class provides the most convenient way to create schemas. All examples in this documentation use the factory methods unless otherwise specified. - diff --git a/docs/json-schema/schema-types/array.mdx b/docs/json-schema/schema-types/array.mdx index 5f43e62..e749285 100644 --- a/docs/json-schema/schema-types/array.mdx +++ b/docs/json-schema/schema-types/array.mdx @@ -531,7 +531,7 @@ try { Validate fixed-length arrays like coordinates, RGB values, or structured tuples. - + Validate complex nested structures like menu trees or organizational hierarchies. diff --git a/docs/json-schema/schema-types/boolean.mdx b/docs/json-schema/schema-types/boolean.mdx index c230d70..9fef258 100644 --- a/docs/json-schema/schema-types/boolean.mdx +++ b/docs/json-schema/schema-types/boolean.mdx @@ -387,10 +387,10 @@ $booleanSchema->isValid(false); // true ## Common Use Cases - + Control application features and functionality with boolean flags and feature switches. - + Store user settings, notifications preferences, and privacy choices. diff --git a/docs/json-schema/schema-types/integer.mdx b/docs/json-schema/schema-types/integer.mdx index 930d658..8aa794a 100644 --- a/docs/json-schema/schema-types/integer.mdx +++ b/docs/json-schema/schema-types/integer.mdx @@ -356,13 +356,13 @@ try { Validate counts, quantities, stock levels, and other discrete numeric values. - + Validate database IDs, reference numbers, and other unique integer identifiers. Validate user ratings, test scores, and other integer-based measurements. - + Validate integer configuration parameters like ports, timeouts, and limits. diff --git a/docs/json-schema/schema-types/null.mdx b/docs/json-schema/schema-types/null.mdx index 93d050d..dac2325 100644 --- a/docs/json-schema/schema-types/null.mdx +++ b/docs/json-schema/schema-types/null.mdx @@ -341,7 +341,7 @@ $processedDataSchema = Schema::object('processed_data') Handle optional relationships and foreign key references that may not exist. - + Represent fields that are only relevant under certain conditions. diff --git a/docs/json-schema/schema-types/number.mdx b/docs/json-schema/schema-types/number.mdx index 2a7d8a7..e6d4ee6 100644 --- a/docs/json-schema/schema-types/number.mdx +++ b/docs/json-schema/schema-types/number.mdx @@ -324,7 +324,7 @@ $integerSchema->isValid(42.5); // false (not whole number) Validate user ratings, test scores, and other numeric feedback with defined scales. - + Validate numeric configuration parameters with appropriate ranges and precision. diff --git a/docs/json-schema/schema-types/object.mdx b/docs/json-schema/schema-types/object.mdx index fe9473b..f352cee 100644 --- a/docs/json-schema/schema-types/object.mdx +++ b/docs/json-schema/schema-types/object.mdx @@ -519,10 +519,16 @@ $schema->isValid([ ## Common Use Cases - + + Define schemas for LLM responses to ensure consistent, parseable structured data from AI models. + + + Specify function parameters for AI agents and assistants to enable reliable tool invocation. + + Validate JSON API payloads with structured data and specific field requirements. - + Validate application configuration with known properties and constraints. diff --git a/docs/json-schema/schema-types/string.mdx b/docs/json-schema/schema-types/string.mdx index 60cb4c9..668023a 100644 --- a/docs/json-schema/schema-types/string.mdx +++ b/docs/json-schema/schema-types/string.mdx @@ -289,10 +289,10 @@ $uuidSchema = Schema::string('id', SchemaVersion::Draft_2019_09) Validate API parameters, paths, and identifiers with strict patterns and format requirements. - + Validate configuration strings with enumerated values and predefined options. - + Validate imported text data against expected patterns and formats before processing. diff --git a/docs/json-schema/schema-types/union.mdx b/docs/json-schema/schema-types/union.mdx index a7dfd2a..a8ae077 100644 --- a/docs/json-schema/schema-types/union.mdx +++ b/docs/json-schema/schema-types/union.mdx @@ -403,7 +403,7 @@ $shapeSchema = Schema::union([SchemaType::Object], 'shape') Support both string and numeric identifiers in APIs and databases. - + Handle configuration values that can be different types (string, number, boolean). From c380286aedc2428afe264a17f183312ba2aa8561 Mon Sep 17 00:00:00 2001 From: Sean Tymon Date: Mon, 26 Jan 2026 21:42:26 +0000 Subject: [PATCH 2/3] cleanup --- docs/docs.json | 1 - .../advanced/conditional-validation.mdx | 19 - .../json-schema/advanced/definitions-refs.mdx | 21 +- .../advanced/dependent-schemas.mdx | 19 - .../advanced/pattern-properties.mdx | 19 - docs/json-schema/advanced/string-formats.mdx | 19 - .../advanced/unevaluated-properties.mdx | 19 - .../code-generation/from-classes.mdx | 19 - .../code-generation/from-closures.mdx | 21 +- .../code-generation/from-enums.mdx | 21 +- .../json-schema/code-generation/from-json.mdx | 136 ---- docs/json-schema/installation.mdx | 12 - docs/json-schema/mcp-server.mdx | 7 - docs/json-schema/schema-types/array.mdx | 19 - docs/json-schema/schema-types/boolean.mdx | 18 - docs/json-schema/schema-types/integer.mdx | 19 - docs/json-schema/schema-types/null.mdx | 19 - docs/json-schema/schema-types/number.mdx | 19 - docs/json-schema/schema-types/object.mdx | 19 - docs/json-schema/schema-types/string.mdx | 19 - docs/json-schema/schema-types/union.mdx | 18 - .../validation/data-validation.mdx | 19 - .../json-schema/validation/error-handling.mdx | 739 ------------------ .../validation/version-features.mdx | 490 ------------ docs/json-schema/versions.mdx | 2 +- 25 files changed, 4 insertions(+), 1729 deletions(-) delete mode 100644 docs/json-schema/validation/error-handling.mdx diff --git a/docs/docs.json b/docs/docs.json index 1b70cfa..f3858c4 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -64,7 +64,6 @@ "group": "Validation", "pages": [ "json-schema/validation/data-validation", - "json-schema/validation/error-handling", "json-schema/validation/version-features" ] } diff --git a/docs/json-schema/advanced/conditional-validation.mdx b/docs/json-schema/advanced/conditional-validation.mdx index 231cdf0..d4b114d 100644 --- a/docs/json-schema/advanced/conditional-validation.mdx +++ b/docs/json-schema/advanced/conditional-validation.mdx @@ -628,22 +628,3 @@ $complexSchema = Schema::object('complex_validation') Different validation rules for different API versions or client types. - -## Next Steps - - - - Learn to create reusable schema components for complex conditional logic - - - Explore property-dependent validation in modern JSON Schema versions - - diff --git a/docs/json-schema/advanced/definitions-refs.mdx b/docs/json-schema/advanced/definitions-refs.mdx index 82663a6..3fe554b 100644 --- a/docs/json-schema/advanced/definitions-refs.mdx +++ b/docs/json-schema/advanced/definitions-refs.mdx @@ -443,7 +443,7 @@ $ecommerceApiSchema = Schema::object('ecommerce_api') Update shared schemas in one place and have changes propagate throughout your API. - + Ensure consistent validation rules across different parts of your application. @@ -539,22 +539,3 @@ $schema->addDefinition( Reuse field validation patterns across different forms and input structures. - -## Next Steps - - - - Learn how to use definitions with conditional validation logic - - - Generate schemas with definitions from PHP classes - - diff --git a/docs/json-schema/advanced/dependent-schemas.mdx b/docs/json-schema/advanced/dependent-schemas.mdx index fc40587..8a8e875 100644 --- a/docs/json-schema/advanced/dependent-schemas.mdx +++ b/docs/json-schema/advanced/dependent-schemas.mdx @@ -563,22 +563,3 @@ $schema->dependentSchemas([ Profile settings where enabled features require additional information. - -## Next Steps - - - - Learn about regex-based property validation patterns - - - Master if/then/else and other conditional validation techniques - - diff --git a/docs/json-schema/advanced/pattern-properties.mdx b/docs/json-schema/advanced/pattern-properties.mdx index 43bd70b..3c21645 100644 --- a/docs/json-schema/advanced/pattern-properties.mdx +++ b/docs/json-schema/advanced/pattern-properties.mdx @@ -489,22 +489,3 @@ $schema->patternProperties([ Allow users to define custom fields that follow specific naming rules. - -## Next Steps - - - - Learn more about object validation and additional properties - - - Generate schemas with pattern properties from PHP classes - - diff --git a/docs/json-schema/advanced/string-formats.mdx b/docs/json-schema/advanced/string-formats.mdx index fefcfd6..1b1b161 100644 --- a/docs/json-schema/advanced/string-formats.mdx +++ b/docs/json-schema/advanced/string-formats.mdx @@ -211,22 +211,3 @@ $userProfileSchema->isValid($validProfile); // true Validate formatted data during import processes with appropriate type checking. - -## Next Steps - - - - Learn more about string validation and pattern matching - - - Master data validation techniques and error handling - - diff --git a/docs/json-schema/advanced/unevaluated-properties.mdx b/docs/json-schema/advanced/unevaluated-properties.mdx index c46b88f..d258f48 100644 --- a/docs/json-schema/advanced/unevaluated-properties.mdx +++ b/docs/json-schema/advanced/unevaluated-properties.mdx @@ -423,22 +423,3 @@ $schema = Schema::object('strict_user', SchemaVersion::Draft_2019_09) Validate data during migration with strict control over allowed properties and transformations. - -## Next Steps - - - - Learn about property-dependent validation in modern JSON Schema - - - Understand JSON Schema version compatibility and feature support - - diff --git a/docs/json-schema/code-generation/from-classes.mdx b/docs/json-schema/code-generation/from-classes.mdx index 30e980f..828bb03 100644 --- a/docs/json-schema/code-generation/from-classes.mdx +++ b/docs/json-schema/code-generation/from-classes.mdx @@ -512,22 +512,3 @@ Validation rules like minLength, pattern, format are not extracted from docblock Generate schemas for application configuration classes. - -## Next Steps - - - - Learn to generate schemas from function signatures - - - Generate validation schemas from PHP enums - - diff --git a/docs/json-schema/code-generation/from-closures.mdx b/docs/json-schema/code-generation/from-closures.mdx index d76700a..3e0aeb4 100644 --- a/docs/json-schema/code-generation/from-closures.mdx +++ b/docs/json-schema/code-generation/from-closures.mdx @@ -466,29 +466,10 @@ function handleUserStuff($data, $action, $options = []) {} Create client-side validation from server-side form processing functions. - + Validate data transformations and processing steps in data pipelines. Generate validation for configuration and setup functions. - -## Next Steps - - - - Generate validation schemas from PHP enums - - - Import and work with existing JSON Schema definitions - - diff --git a/docs/json-schema/code-generation/from-enums.mdx b/docs/json-schema/code-generation/from-enums.mdx index 0e915e3..73dac60 100644 --- a/docs/json-schema/code-generation/from-enums.mdx +++ b/docs/json-schema/code-generation/from-enums.mdx @@ -628,29 +628,10 @@ try { Ensure application configuration uses only valid environment and option values. - + Validate state transitions and status changes in business workflows. Generate client-side validation and form options from backend enums. - -## Next Steps - - - - Import and work with existing JSON Schema definitions - - - Learn advanced validation techniques for enum values - - diff --git a/docs/json-schema/code-generation/from-json.mdx b/docs/json-schema/code-generation/from-json.mdx index 0da532c..1cbdd18 100644 --- a/docs/json-schema/code-generation/from-json.mdx +++ b/docs/json-schema/code-generation/from-json.mdx @@ -237,123 +237,6 @@ $singleUserResponse = [ $apiSchema->isValid($singleUserResponse); // true ``` -## Loading from Files - -Load schemas from external files: - -```php -/** - * Load schema from file - */ -function loadSchemaFromFile(string $filepath): Schema -{ - if (!file_exists($filepath)) { - throw new InvalidArgumentException("Schema file not found: {$filepath}"); - } - - $content = file_get_contents($filepath); - $schemaData = json_decode($content, true); - - if (json_last_error() !== JSON_ERROR_NONE) { - throw new InvalidArgumentException("Invalid JSON in schema file: " . json_last_error_msg()); - } - - return Schema::fromJson($schemaData); -} - -// Usage -$userSchema = loadSchemaFromFile('schemas/user.json'); -$productSchema = loadSchemaFromFile('schemas/product.json'); -$orderSchema = loadSchemaFromFile('schemas/order.json'); -``` - -## Best Practices - -### 1. Validate JSON Before Import - -```php -function safeJsonImport(string $jsonString): Schema -{ - $data = json_decode($jsonString, true); - - if (json_last_error() !== JSON_ERROR_NONE) { - throw new InvalidArgumentException( - "Invalid JSON: " . json_last_error_msg() - ); - } - - // Basic schema validation - if (!isset($data['type'])) { - throw new InvalidArgumentException("Schema must have a 'type' property"); - } - - return Schema::fromJson($data); -} -``` - -### 2. Handle Schema Dependencies - -```php -function resolveSchemaReferences(array $schema, array $definitions = []): array -{ - // Recursively resolve $ref properties - foreach ($schema as $key => $value) { - if ($key === '$ref' && is_string($value)) { - // Resolve reference to actual schema - $refPath = str_replace('#/definitions/', '', $value); - if (isset($definitions[$refPath])) { - return $definitions[$refPath]; - } - } elseif (is_array($value)) { - $schema[$key] = resolveSchemaReferences($value, $definitions); - } - } - - return $schema; -} -``` - -### 3. Version Compatibility Checking - -```php -function checkVersionCompatibility(array $schema): void -{ - $schemaVersion = $schema['$schema'] ?? ''; - - $supportedVersions = [ - 'http://json-schema.org/draft-07/schema#', - 'https://json-schema.org/draft/2019-09/schema', - 'https://json-schema.org/draft/2020-12/schema' - ]; - - if ($schemaVersion && !in_array($schemaVersion, $supportedVersions)) { - throw new InvalidArgumentException( - "Unsupported schema version: {$schemaVersion}" - ); - } -} -``` - -### 4. Schema Caching - -```php -class CachedSchemaLoader -{ - private array $cache = []; - - public function load(string $filepath): Schema - { - $cacheKey = md5($filepath . filemtime($filepath)); - - if (!isset($this->cache[$cacheKey])) { - $this->cache[$cacheKey] = loadSchemaFromFile($filepath); - } - - return $this->cache[$cacheKey]; - } -} -``` - ## Common Use Cases @@ -370,22 +253,3 @@ class CachedSchemaLoader Work with external JSON schemas from APIs, services, or documentation. - -## Next Steps - - - - Learn to validate data with imported schemas - - - Explore the complete Schema Factory API reference - - diff --git a/docs/json-schema/installation.mdx b/docs/json-schema/installation.mdx index 4efef6d..839efc3 100644 --- a/docs/json-schema/installation.mdx +++ b/docs/json-schema/installation.mdx @@ -68,15 +68,3 @@ If you're contributing to the package or want to run tests: ``` - -## Next Steps - -Now that you have the package installed, you're ready to create your first JSON Schema: - - - Learn how to create and validate schemas with practical examples - diff --git a/docs/json-schema/mcp-server.mdx b/docs/json-schema/mcp-server.mdx index 8e282ec..4382e24 100644 --- a/docs/json-schema/mcp-server.mdx +++ b/docs/json-schema/mcp-server.mdx @@ -280,13 +280,6 @@ The MCP server provides access to comprehensive documentation, code examples, an ## Additional Resources - - Browse the complete CortexPHP documentation - - -## Next Steps - - - - Learn about validating complex object structures - - - Explore advanced array validation features in modern JSON Schema versions - - diff --git a/docs/json-schema/schema-types/boolean.mdx b/docs/json-schema/schema-types/boolean.mdx index 9fef258..83089d8 100644 --- a/docs/json-schema/schema-types/boolean.mdx +++ b/docs/json-schema/schema-types/boolean.mdx @@ -401,21 +401,3 @@ $booleanSchema->isValid(false); // true -## Next Steps - - - - Learn about null value validation - - - Use booleans in conditional schema logic - - diff --git a/docs/json-schema/schema-types/integer.mdx b/docs/json-schema/schema-types/integer.mdx index 8aa794a..15596af 100644 --- a/docs/json-schema/schema-types/integer.mdx +++ b/docs/json-schema/schema-types/integer.mdx @@ -366,22 +366,3 @@ try { Validate integer configuration parameters like ports, timeouts, and limits. - -## Next Steps - - - - Learn about number validation for decimal values - - - Validate boolean true/false values - - diff --git a/docs/json-schema/schema-types/null.mdx b/docs/json-schema/schema-types/null.mdx index dac2325..80d00c8 100644 --- a/docs/json-schema/schema-types/null.mdx +++ b/docs/json-schema/schema-types/null.mdx @@ -348,22 +348,3 @@ $processedDataSchema = Schema::object('processed_data') Handle API fields that may not be present or applicable in all responses. - -## Next Steps - - - - Learn about combining multiple types including null - - - Use null in conditional schema logic - - diff --git a/docs/json-schema/schema-types/number.mdx b/docs/json-schema/schema-types/number.mdx index e6d4ee6..f45939a 100644 --- a/docs/json-schema/schema-types/number.mdx +++ b/docs/json-schema/schema-types/number.mdx @@ -328,22 +328,3 @@ $integerSchema->isValid(42.5); // false (not whole number) Validate numeric configuration parameters with appropriate ranges and precision. - -## Next Steps - - - - Learn about integer-specific validation and constraints - - - Validate arrays of numbers and other complex data structures - - diff --git a/docs/json-schema/schema-types/object.mdx b/docs/json-schema/schema-types/object.mdx index f352cee..fa5fd9d 100644 --- a/docs/json-schema/schema-types/object.mdx +++ b/docs/json-schema/schema-types/object.mdx @@ -538,22 +538,3 @@ $schema->isValid([ Validate data models before persistence with property and constraint validation. - -## Next Steps - - - - Learn about array validation and nested data structures - - - Explore pattern properties and advanced object validation - - diff --git a/docs/json-schema/schema-types/string.mdx b/docs/json-schema/schema-types/string.mdx index 668023a..59696a7 100644 --- a/docs/json-schema/schema-types/string.mdx +++ b/docs/json-schema/schema-types/string.mdx @@ -296,22 +296,3 @@ $uuidSchema = Schema::string('id', SchemaVersion::Draft_2019_09) Validate imported text data against expected patterns and formats before processing. - -## Next Steps - - - - Learn about numeric validation with ranges and constraints - - - Comprehensive guide to all available string formats - - diff --git a/docs/json-schema/schema-types/union.mdx b/docs/json-schema/schema-types/union.mdx index a8ae077..560733a 100644 --- a/docs/json-schema/schema-types/union.mdx +++ b/docs/json-schema/schema-types/union.mdx @@ -414,21 +414,3 @@ $shapeSchema = Schema::union([SchemaType::Object], 'shape') -## Next Steps - - - - Learn advanced conditional logic with anyOf, oneOf, and allOf - - - Master validation techniques for complex union types - - diff --git a/docs/json-schema/validation/data-validation.mdx b/docs/json-schema/validation/data-validation.mdx index 389e139..91b650f 100644 --- a/docs/json-schema/validation/data-validation.mdx +++ b/docs/json-schema/validation/data-validation.mdx @@ -220,22 +220,3 @@ try { echo "Score validation error: " . $e->getMessage(); } ``` - -## Next Steps - - - - Learn advanced error handling and custom exception management - - - Explore the complete Schema Factory API reference - - diff --git a/docs/json-schema/validation/error-handling.mdx b/docs/json-schema/validation/error-handling.mdx deleted file mode 100644 index de37f01..0000000 --- a/docs/json-schema/validation/error-handling.mdx +++ /dev/null @@ -1,739 +0,0 @@ ---- -title: Error Handling -description: 'Advanced error handling and exception management for schema validation' -icon: 'x' ---- - -Master error handling in JSON Schema validation with detailed exception information, custom error messages, and graceful error recovery patterns. - -## SchemaException Overview - -All validation errors throw `SchemaException` with detailed information: - -```php -use Cortex\JsonSchema\Schema; -use Cortex\JsonSchema\Exceptions\SchemaException; - -$schema = Schema::string('email') - ->format(SchemaFormat::Email) - ->minLength(5) - ->maxLength(100) - ->required(); - -try { - $schema->validate('invalid-email-format'); -} catch (SchemaException $e) { - echo "Error: " . $e->getMessage(); // User-friendly message - echo "Code: " . $e->getCode(); // Error code - echo "Property: " . $e->getProperty(); // Failed property (if available) - echo "Value: " . $e->getFailedValue(); // Value that failed (if available) -} -``` - -## Exception Types and Error Codes - -Different validation failures produce specific error codes: - -```php -$userSchema = Schema::object('user') - ->properties( - Schema::string('name') - ->minLength(2) - ->maxLength(50) - ->required(), - Schema::string('email') - ->format(SchemaFormat::Email) - ->required(), - Schema::integer('age') - ->minimum(0) - ->maximum(150) - ->required() - ); - -// Test different error scenarios -$testCases = [ - // Missing required field - ['name' => 'John'], - - // String too short - ['name' => 'J', 'email' => 'john@example.com', 'age' => 30], - - // Invalid format - ['name' => 'John', 'email' => 'invalid-email', 'age' => 30], - - // Type mismatch - ['name' => 'John', 'email' => 'john@example.com', 'age' => 'thirty'], - - // Value out of range - ['name' => 'John', 'email' => 'john@example.com', 'age' => -5] -]; - -foreach ($testCases as $index => $testData) { - try { - $userSchema->validate($testData); - echo "Test case {$index}: Valid\n"; - } catch (SchemaException $e) { - echo "Test case {$index}: {$e->getMessage()}\n"; - echo " Error code: {$e->getCode()}\n"; - echo " Failed property: " . ($e->getProperty() ?? 'unknown') . "\n\n"; - } -} -``` - -## Error Message Categories - -Schema validation errors fall into several categories: - -### Type Validation Errors - -```php -$typeSchema = Schema::string('name'); - -try { - $typeSchema->validate(123); // Number instead of string -} catch (SchemaException $e) { - echo $e->getMessage(); // "Value must be a string" - echo $e->getCode(); // Type validation error code -} -``` - -### Format Validation Errors - -```php -$emailSchema = Schema::string('email')->format(SchemaFormat::Email); - -try { - $emailSchema->validate('not-an-email'); -} catch (SchemaException $e) { - echo $e->getMessage(); // "Value must match the 'email' format" -} -``` - -### Constraint Validation Errors - -```php -$lengthSchema = Schema::string('username') - ->minLength(3) - ->maxLength(20); - -try { - $lengthSchema->validate('ab'); // Too short -} catch (SchemaException $e) { - echo $e->getMessage(); // "String must have minimum length of 3" -} - -try { - $lengthSchema->validate('very_long_username_that_exceeds_limit'); -} catch (SchemaException $e) { - echo $e->getMessage(); // "String must have maximum length of 20" -} -``` - -### Required Field Errors - -```php -$requiredSchema = Schema::object('user') - ->properties( - Schema::string('name')->required(), - Schema::string('email')->required() - ); - -try { - $requiredSchema->validate(['name' => 'John']); // Missing email -} catch (SchemaException $e) { - echo $e->getMessage(); // "Property 'email' is required" - echo $e->getProperty(); // "email" -} -``` - -## Custom Error Messages - -Create user-friendly error messages for different contexts: - -```php -class UserFriendlyErrorHandler -{ - private array $messageMap = [ - // Type errors - 'must be a string' => 'Please enter text for this field', - 'must be an integer' => 'Please enter a whole number', - 'must be a number' => 'Please enter a valid number', - 'must be a boolean' => 'Please select yes or no', - - // Format errors - 'must match the \'email\' format' => 'Please enter a valid email address', - 'must match the \'uri\' format' => 'Please enter a valid URL', - 'must match the \'date\' format' => 'Please enter a valid date (YYYY-MM-DD)', - - // Constraint errors - 'must have minimum length' => 'This field is too short', - 'must have maximum length' => 'This field is too long', - 'must be greater than or equal to' => 'Value is too small', - 'must be less than or equal to' => 'Value is too large', - - // Required field errors - 'is required' => 'This field is required', - ]; - - public function getFriendlyMessage(SchemaException $e): string - { - $originalMessage = $e->getMessage(); - - foreach ($this->messageMap as $pattern => $friendlyMessage) { - if (strpos($originalMessage, $pattern) !== false) { - return $friendlyMessage; - } - } - - return $originalMessage; // Fallback to original message - } - - public function getFieldSpecificMessage(SchemaException $e): string - { - $property = $e->getProperty(); - $friendlyMessage = $this->getFriendlyMessage($e); - - if ($property) { - $fieldName = ucfirst(str_replace('_', ' ', $property)); - return "{$fieldName}: {$friendlyMessage}"; - } - - return $friendlyMessage; - } -} - -// Usage -$errorHandler = new UserFriendlyErrorHandler(); - -try { - $userSchema->validate(['name' => 'J', 'email' => 'invalid']); -} catch (SchemaException $e) { - echo "Technical: " . $e->getMessage() . "\n"; - echo "User-friendly: " . $errorHandler->getFriendlyMessage($e) . "\n"; - echo "Field-specific: " . $errorHandler->getFieldSpecificMessage($e) . "\n"; -} -``` - -## Validation Result Objects - -Create structured validation results for better error handling: - -```php -class ValidationResult -{ - public function __construct( - public bool $isValid, - public array $errors = [], - public ?array $data = null - ) {} - - public function hasErrors(): bool - { - return !empty($this->errors); - } - - public function getFirstError(): ?string - { - return $this->errors[0] ?? null; - } - - public function getErrorsForField(string $field): array - { - return array_filter($this->errors, fn($error) => - isset($error['field']) && $error['field'] === $field - ); - } -} - -class ValidatorWithResults -{ - public function validate(Schema $schema, mixed $data): ValidationResult - { - if ($schema->isValid($data)) { - return new ValidationResult(true, [], $data); - } - - $errors = []; - try { - $schema->validate($data); - } catch (SchemaException $e) { - $errors[] = [ - 'message' => $e->getMessage(), - 'code' => $e->getCode(), - 'field' => $e->getProperty(), - 'value' => $e->getFailedValue() - ]; - } - - return new ValidationResult(false, $errors, $data); - } - - public function validateMultiple(Schema $schema, array $items): array - { - $results = []; - - foreach ($items as $index => $item) { - $results[$index] = $this->validate($schema, $item); - } - - return $results; - } -} - -// Usage -$validator = new ValidatorWithResults(); -$userSchema = Schema::object('user') - ->properties( - Schema::string('name')->minLength(2)->required(), - Schema::string('email')->format(SchemaFormat::Email)->required() - ); - -$result = $validator->validate($userSchema, ['name' => 'J']); - -if (!$result->isValid) { - echo "Validation failed:\n"; - foreach ($result->errors as $error) { - echo "- {$error['message']}\n"; - } -} -``` - -## Nested Object Error Handling - -Handle errors in complex nested structures: - -```php -class NestedErrorHandler -{ - public function validateWithPath(Schema $schema, mixed $data, string $path = ''): array - { - $errors = []; - - try { - $schema->validate($data); - } catch (SchemaException $e) { - $fieldPath = $path; - if ($e->getProperty()) { - $fieldPath .= ($fieldPath ? '.' : '') . $e->getProperty(); - } - - $errors[] = [ - 'path' => $fieldPath, - 'message' => $e->getMessage(), - 'value' => $e->getFailedValue() - ]; - } - - return $errors; - } - - public function validateObject(Schema $schema, array $data, string $basePath = ''): array - { - $allErrors = []; - - // First validate the entire object - $errors = $this->validateWithPath($schema, $data, $basePath); - $allErrors = array_merge($allErrors, $errors); - - // If the object validation passes, validate individual properties - if (empty($errors) && is_array($data)) { - $schemaArray = $schema->toArray(); - - if (isset($schemaArray['properties'])) { - foreach ($schemaArray['properties'] as $property => $propSchema) { - if (isset($data[$property])) { - $propertyPath = $basePath . ($basePath ? '.' : '') . $property; - $propertySchema = Schema::fromJson($propSchema); - - $propertyErrors = $this->validateWithPath( - $propertySchema, - $data[$property], - $propertyPath - ); - - $allErrors = array_merge($allErrors, $propertyErrors); - } - } - } - } - - return $allErrors; - } -} - -// Complex nested schema -$orderSchema = Schema::object('order') - ->properties( - Schema::string('id')->required(), - Schema::object('customer') - ->properties( - Schema::string('name')->minLength(2)->required(), - Schema::string('email')->format(SchemaFormat::Email)->required(), - Schema::object('address') - ->properties( - Schema::string('street')->required(), - Schema::string('city')->required(), - Schema::string('postal_code') - ->pattern('^\d{5}$') - ->required() - ) - ->required() - ) - ->required(), - Schema::array('items') - ->items( - Schema::object() - ->properties( - Schema::string('sku')->required(), - Schema::integer('quantity')->minimum(1)->required() - ) - ) - ->minItems(1) - ->required() - ); - -$nestedHandler = new NestedErrorHandler(); - -$invalidOrder = [ - 'id' => 'ORD-123', - 'customer' => [ - 'name' => 'J', // Too short - 'email' => 'invalid-email', // Invalid format - 'address' => [ - 'street' => '123 Main St', - // Missing city - 'postal_code' => '1234' // Invalid format - ] - ], - 'items' => [ - [ - 'sku' => 'ITEM-001', - 'quantity' => 0 // Below minimum - ] - ] -]; - -$errors = $nestedHandler->validateObject($orderSchema, $invalidOrder); - -foreach ($errors as $error) { - echo "Error at {$error['path']}: {$error['message']}\n"; -} -``` - -## Error Recovery and Suggestions - -Provide helpful suggestions for common validation errors: - -```php -class ErrorRecoveryHelper -{ - public function suggestCorrections(SchemaException $e): array - { - $suggestions = []; - $message = $e->getMessage(); - $value = $e->getFailedValue(); - - // Email format suggestions - if (strpos($message, 'email') !== false && is_string($value)) { - if (!strpos($value, '@')) { - $suggestions[] = "Add an '@' symbol to your email address"; - } elseif (!strpos($value, '.')) { - $suggestions[] = "Add a domain extension like '.com' to your email"; - } - } - - // String length suggestions - if (strpos($message, 'minimum length') !== false) { - preg_match('/minimum length of (\d+)/', $message, $matches); - if ($matches) { - $required = (int)$matches[1]; - $current = is_string($value) ? strlen($value) : 0; - $needed = $required - $current; - $suggestions[] = "Add {$needed} more character" . ($needed > 1 ? 's' : ''); - } - } - - if (strpos($message, 'maximum length') !== false) { - preg_match('/maximum length of (\d+)/', $message, $matches); - if ($matches) { - $allowed = (int)$matches[1]; - $current = is_string($value) ? strlen($value) : 0; - $excess = $current - $allowed; - $suggestions[] = "Remove {$excess} character" . ($excess > 1 ? 's' : ''); - } - } - - // Numeric range suggestions - if (strpos($message, 'greater than or equal to') !== false) { - preg_match('/greater than or equal to ([\d.]+)/', $message, $matches); - if ($matches) { - $minimum = $matches[1]; - $suggestions[] = "Enter a value of {$minimum} or higher"; - } - } - - // Enum suggestions - if (strpos($message, 'must be one of') !== false) { - $suggestions[] = "Choose from the available options"; - } - - return $suggestions; - } - - public function getDetailedError(SchemaException $e): array - { - return [ - 'message' => $e->getMessage(), - 'code' => $e->getCode(), - 'field' => $e->getProperty(), - 'value' => $e->getFailedValue(), - 'suggestions' => $this->suggestCorrections($e) - ]; - } -} - -// Usage -$recoveryHelper = new ErrorRecoveryHelper(); - -try { - $emailSchema = Schema::string('email')->format(SchemaFormat::Email); - $emailSchema->validate('userexample.com'); // Missing @ -} catch (SchemaException $e) { - $detailedError = $recoveryHelper->getDetailedError($e); - - echo "Error: {$detailedError['message']}\n"; - if (!empty($detailedError['suggestions'])) { - echo "Suggestions:\n"; - foreach ($detailedError['suggestions'] as $suggestion) { - echo "- {$suggestion}\n"; - } - } -} -``` - -## Bulk Validation Error Handling - -Handle errors when validating multiple items: - -```php -class BulkValidator -{ - public function validateBatch(Schema $schema, array $items): array - { - $results = []; - - foreach ($items as $index => $item) { - try { - $schema->validate($item); - $results[$index] = [ - 'valid' => true, - 'data' => $item, - 'errors' => [] - ]; - } catch (SchemaException $e) { - $results[$index] = [ - 'valid' => false, - 'data' => $item, - 'errors' => [ - [ - 'message' => $e->getMessage(), - 'field' => $e->getProperty(), - 'code' => $e->getCode() - ] - ] - ]; - } - } - - return $results; - } - - public function getValidItems(array $batchResults): array - { - $validItems = []; - - foreach ($batchResults as $index => $result) { - if ($result['valid']) { - $validItems[$index] = $result['data']; - } - } - - return $validItems; - } - - public function getErrorSummary(array $batchResults): array - { - $summary = [ - 'total' => count($batchResults), - 'valid' => 0, - 'invalid' => 0, - 'error_types' => [] - ]; - - foreach ($batchResults as $result) { - if ($result['valid']) { - $summary['valid']++; - } else { - $summary['invalid']++; - - foreach ($result['errors'] as $error) { - $errorType = $error['message']; - $summary['error_types'][$errorType] = - ($summary['error_types'][$errorType] ?? 0) + 1; - } - } - } - - return $summary; - } -} - -// Usage -$bulkValidator = new BulkValidator(); -$userSchema = Schema::object('user') - ->properties( - Schema::string('name')->minLength(2)->required(), - Schema::string('email')->format(SchemaFormat::Email)->required() - ); - -$users = [ - ['name' => 'John Doe', 'email' => 'john@example.com'], // Valid - ['name' => 'J', 'email' => 'jane@example.com'], // Invalid name - ['name' => 'Bob Smith', 'email' => 'invalid-email'], // Invalid email - ['name' => 'Alice Johnson', 'email' => 'alice@example.com'] // Valid -]; - -$results = $bulkValidator->validateBatch($userSchema, $users); -$validUsers = $bulkValidator->getValidItems($results); -$summary = $bulkValidator->getErrorSummary($results); - -echo "Validation Summary:\n"; -echo "Total: {$summary['total']}\n"; -echo "Valid: {$summary['valid']}\n"; -echo "Invalid: {$summary['invalid']}\n"; - -if (!empty($summary['error_types'])) { - echo "\nError Types:\n"; - foreach ($summary['error_types'] as $errorType => $count) { - echo "- {$errorType}: {$count} occurrence(s)\n"; - } -} -``` - -## Best Practices - -### 1. Use Specific Error Messages - -```php -// Good: Specific validation rules with clear error context -$passwordSchema = Schema::string('password') - ->minLength(8) - ->pattern('(?=.*[a-z])(?=.*[A-Z])(?=.*\d)') - ->description('Password must be at least 8 characters with uppercase, lowercase, and number'); - -// Provide context in error handling -try { - $passwordSchema->validate($password); -} catch (SchemaException $e) { - $errorContext = [ - 'field' => 'password', - 'message' => $e->getMessage(), - 'requirements' => 'At least 8 characters with uppercase, lowercase, and number' - ]; -} -``` - -### 2. Log Validation Errors - -```php -class ValidatorWithLogging -{ - private LoggerInterface $logger; - - public function validateWithLogging(Schema $schema, mixed $data, array $context = []): bool - { - try { - $schema->validate($data); - return true; - } catch (SchemaException $e) { - $this->logger->warning('Schema validation failed', [ - 'message' => $e->getMessage(), - 'code' => $e->getCode(), - 'field' => $e->getProperty(), - 'context' => $context - ]); - - return false; - } - } -} -``` - -### 3. Graceful Degradation - -```php -function processUserDataSafely(array $userData): array -{ - $userSchema = Schema::object('user') - ->properties( - Schema::string('name')->required(), - Schema::string('email')->format(SchemaFormat::Email)->required() - ); - - try { - $userSchema->validate($userData); - return ['status' => 'success', 'data' => $userData]; - } catch (SchemaException $e) { - // Log error but continue with partial processing - error_log("User data validation failed: " . $e->getMessage()); - - // Return what we can process safely - $safeData = []; - if (isset($userData['name']) && is_string($userData['name'])) { - $safeData['name'] = $userData['name']; - } - - return [ - 'status' => 'partial', - 'data' => $safeData, - 'errors' => [$e->getMessage()] - ]; - } -} -``` - -## Common Use Cases - - - - Provide user-friendly error messages and suggestions for form input validation. - - - Structure detailed error responses for API endpoints with validation failures. - - - Handle validation errors during bulk data import with detailed error reporting. - - - Provide helpful error messages for application configuration validation. - - - -## Next Steps - - - - Learn about version-specific validation features and compatibility - - - Master the core validation methods and techniques - - diff --git a/docs/json-schema/validation/version-features.mdx b/docs/json-schema/validation/version-features.mdx index ee09d65..7c42d05 100644 --- a/docs/json-schema/validation/version-features.mdx +++ b/docs/json-schema/validation/version-features.mdx @@ -144,493 +144,3 @@ $latestSchema = Schema::array('tuple_array', SchemaVersion::Draft_2020_12) // Unevaluated items control ->unevaluatedItems(false); ``` - -## Version Detection and Error Messages - -The package provides clear error messages when incompatible features are used: - -```php -function demonstrateVersionErrors() -{ - $examples = [ - 'Deprecated annotation' => function() { - return Schema::string('field', SchemaVersion::Draft_07) - ->deprecated(); - }, - - 'Min/Max contains' => function() { - return Schema::array('items', SchemaVersion::Draft_07) - ->minContains(1); - }, - - 'UUID format' => function() { - return Schema::string('id', SchemaVersion::Draft_07) - ->format(SchemaFormat::Uuid); - }, - - 'Unevaluated properties' => function() { - return Schema::object('strict', SchemaVersion::Draft_07) - ->unevaluatedProperties(false); - }, - - 'Dependent schemas' => function() { - return Schema::object('conditional', SchemaVersion::Draft_07) - ->dependentSchema('field', Schema::object()); - } - ]; - - foreach ($examples as $featureName => $schemaBuilder) { - try { - $schemaBuilder(); - echo "✅ {$featureName}: Compatible\n"; - } catch (SchemaException $e) { - echo "❌ {$featureName}: {$e->getMessage()}\n"; - } - } -} - -demonstrateVersionErrors(); -``` - -## Feature Detection - -Check feature support programmatically: - -```php -use Cortex\JsonSchema\Enums\SchemaFeature; - -/** - * Check if a feature is supported in a specific version - */ -function checkFeatureSupport(SchemaVersion $version, SchemaFeature $feature): bool -{ - return $version->supports($feature); -} - -/** - * Get minimum version required for a feature - */ -function getMinimumVersion(SchemaFeature $feature): SchemaVersion -{ - return $feature->getMinimumVersion(); -} - -// Feature compatibility checking -$features = [ - SchemaFeature::Deprecated, - SchemaFeature::MinContains, - SchemaFeature::MaxContains, - SchemaFeature::UnevaluatedProperties, - SchemaFeature::DependentSchemas, - SchemaFeature::PrefixItems -]; - -foreach ($features as $feature) { - $minVersion = getMinimumVersion($feature); - $description = $feature->getDescription(); - - echo "Feature: {$description}\n"; - echo "Minimum version: {$minVersion->name}\n"; - echo "Supported in Draft-07: " . - (checkFeatureSupport(SchemaVersion::Draft_07, $feature) ? 'Yes' : 'No') . "\n"; - echo "Supported in Draft 2019-09: " . - (checkFeatureSupport(SchemaVersion::Draft_2019_09, $feature) ? 'Yes' : 'No') . "\n"; - echo "Supported in Draft 2020-12: " . - (checkFeatureSupport(SchemaVersion::Draft_2020_12, $feature) ? 'Yes' : 'No') . "\n\n"; -} -``` - -## Schema Migration Between Versions - -Migrate schemas to take advantage of newer features: - -```php -class SchemaMigrator -{ - public function upgradeToDraft201909(Schema $draft07Schema): Schema - { - $schemaArray = $draft07Schema->toArray(); - - // Update schema version - $schemaArray['$schema'] = 'https://json-schema.org/draft/2019-09/schema'; - - // Convert definitions to $defs - if (isset($schemaArray['definitions'])) { - $schemaArray['$defs'] = $schemaArray['definitions']; - unset($schemaArray['definitions']); - - // Update $ref paths - $schemaArray = $this->updateRefPaths($schemaArray); - } - - return Schema::fromJson($schemaArray, SchemaVersion::Draft_2019_09); - } - - public function addModernFeatures(Schema $basicSchema): Schema - { - $schemaArray = $basicSchema->toArray(); - - // Ensure we're using a modern version - if (!isset($schemaArray['$schema']) || - strpos($schemaArray['$schema'], '2019-09') === false) { - $schemaArray['$schema'] = 'https://json-schema.org/draft/2019-09/schema'; - } - - // Add modern validation features - if ($schemaArray['type'] === 'object') { - // Add strict property validation - $schemaArray['unevaluatedProperties'] = false; - - // Add examples for better documentation - if (isset($schemaArray['properties'])) { - foreach ($schemaArray['properties'] as $prop => &$propSchema) { - if ($propSchema['type'] === 'string' && !isset($propSchema['examples'])) { - $propSchema['examples'] = ["example_{$prop}"]; - } - } - } - } - - return Schema::fromJson($schemaArray, SchemaVersion::Draft_2019_09); - } - - private function updateRefPaths(array $schema): array - { - foreach ($schema as $key => &$value) { - if ($key === '$ref' && is_string($value)) { - $value = str_replace('#/definitions/', '#/$defs/', $value); - } elseif (is_array($value)) { - $value = $this->updateRefPaths($value); - } - } - - return $schema; - } -} - -// Usage example -$migrator = new SchemaMigrator(); - -// Original Draft-07 schema -$originalSchema = Schema::object('user', SchemaVersion::Draft_07) - ->properties( - Schema::string('name')->required(), - Schema::string('email')->required() - ) - ->addDefinition('address', - Schema::object() - ->properties( - Schema::string('street')->required(), - Schema::string('city')->required() - ) - ); - -// Upgrade to take advantage of Draft 2019-09 features -$modernSchema = $migrator->upgradeToDraft201909($originalSchema); -$enhancedSchema = $migrator->addModernFeatures($modernSchema); - -// Now we can use modern features -$enhancedSchema = $enhancedSchema - ->unevaluatedProperties(false) // This now works - ->properties( - Schema::string('legacy_field') - ->deprecated() // This now works too - ); -``` - -## Conditional Feature Usage - -Use features conditionally based on version support: - -```php -class VersionAwareSchemaBuilder -{ - public function buildUserSchema(SchemaVersion $version): Schema - { - $schema = Schema::object('user', $version) - ->properties( - Schema::string('name')->required(), - Schema::string('email')->required() - ); - - // Add version-specific features - if ($version->supports(SchemaFeature::Deprecated)) { - $schema = $schema->properties( - Schema::string('old_email') - ->deprecated() - ->comment('Use email field instead') - ); - } - - if ($version->supports(SchemaFeature::UnevaluatedProperties)) { - $schema = $schema->unevaluatedProperties(false); - } - - if ($version->supports(SchemaFeature::MinContains)) { - $schema = $schema->properties( - Schema::array('roles') - ->items(Schema::string()) - ->minContains(1) - ->maxContains(5) - ); - } else { - // Fallback for older versions - $schema = $schema->properties( - Schema::array('roles') - ->items(Schema::string()) - ->minItems(1) - ->maxItems(5) - ); - } - - return $schema; - } - - public function buildWithBestFeatures(SchemaVersion $targetVersion): Schema - { - // Use the most advanced features available - $availableFeatures = [ - SchemaFeature::Deprecated, - SchemaFeature::UnevaluatedProperties, - SchemaFeature::MinContains, - SchemaFeature::DependentSchemas - ]; - - $schema = Schema::object('advanced_user', $targetVersion) - ->properties( - Schema::string('username')->required(), - Schema::string('email')->required() - ); - - foreach ($availableFeatures as $feature) { - if ($targetVersion->supports($feature)) { - $schema = $this->addFeatureToSchema($schema, $feature); - } - } - - return $schema; - } - - private function addFeatureToSchema(Schema $schema, SchemaFeature $feature): Schema - { - switch ($feature) { - case SchemaFeature::Deprecated: - return $schema->properties( - Schema::string('legacy_username') - ->deprecated() - ->comment('Use username instead') - ); - - case SchemaFeature::UnevaluatedProperties: - return $schema->unevaluatedProperties(false); - - case SchemaFeature::MinContains: - return $schema->properties( - Schema::array('permissions') - ->items(Schema::string()) - ->minContains(1) - ); - - case SchemaFeature::DependentSchemas: - return $schema->dependentSchema('legacy_username', - Schema::object() - ->properties( - Schema::string('migration_date') - ->format(SchemaFormat::Date) - ->required() - ) - ); - - default: - return $schema; - } - } -} - -// Usage -$builder = new VersionAwareSchemaBuilder(); - -// Build schemas for different target environments -$draft07Schema = $builder->buildUserSchema(SchemaVersion::Draft_07); -$modernSchema = $builder->buildUserSchema(SchemaVersion::Draft_2019_09); -$latestSchema = $builder->buildUserSchema(SchemaVersion::Draft_2020_12); - -// Each schema uses the best features available for its version -``` - -## Validation Environment Detection - -Detect and adapt to different validation environments: - -```php -class EnvironmentAwareValidator -{ - private SchemaVersion $supportedVersion; - - public function __construct() - { - $this->supportedVersion = $this->detectEnvironmentVersion(); - } - - private function detectEnvironmentVersion(): SchemaVersion - { - // In a real application, you might: - // - Check client capabilities - // - Read from configuration - // - Test feature support - - // For demo, assume based on PHP version or configuration - $configVersion = $_ENV['JSON_SCHEMA_VERSION'] ?? 'draft-2020-12'; - - return match($configVersion) { - 'draft-07' => SchemaVersion::Draft_07, - 'draft-2019-09' => SchemaVersion::Draft_2019_09, - default => SchemaVersion::Draft_2020_12 - }; - } - - public function createCompatibleSchema(array $requirements): Schema - { - $schema = Schema::object('dynamic', $this->supportedVersion); - - foreach ($requirements as $field => $config) { - $fieldSchema = $this->createFieldSchema($config); - $schema = $schema->properties($fieldSchema->propertyName($field)); - } - - // Add version-appropriate constraints - if ($this->supportedVersion->supports(SchemaFeature::UnevaluatedProperties)) { - $schema = $schema->unevaluatedProperties(false); - } else { - $schema = $schema->additionalProperties(false); - } - - return $schema; - } - - private function createFieldSchema(array $config): Schema - { - $type = $config['type'] ?? 'string'; - $fieldSchema = match($type) { - 'string' => Schema::string(), - 'integer' => Schema::integer(), - 'number' => Schema::number(), - 'boolean' => Schema::boolean(), - 'array' => Schema::array(), - default => Schema::string() - }; - - // Apply constraints based on version support - if (isset($config['deprecated']) && - $this->supportedVersion->supports(SchemaFeature::Deprecated)) { - $fieldSchema = $fieldSchema->deprecated(); - } - - if (isset($config['format'])) { - $format = SchemaFormat::from($config['format']); - if ($this->isFormatSupported($format)) { - $fieldSchema = $fieldSchema->format($format); - } - } - - return $fieldSchema; - } - - private function isFormatSupported(SchemaFormat $format): bool - { - $modernFormats = [SchemaFormat::Uuid, SchemaFormat::Duration]; - - if (in_array($format, $modernFormats)) { - return $this->supportedVersion->supports(SchemaFeature::ExtendedFormats); - } - - return true; // Basic formats supported in all versions - } -} -``` - -## Best Practices - -### 1. Use Version Detection - -```php -// Good: Check version support before using features -if (SchemaVersion::Draft_2019_09->supports(SchemaFeature::Deprecated)) { - $schema = $schema->deprecated(); -} - -// Avoid: Assuming feature support -$schema = $schema->deprecated(); // May fail in older versions -``` - -### 2. Provide Fallbacks - -```php -// Good: Provide fallbacks for unsupported features -function addStrictValidation(Schema $schema, SchemaVersion $version): Schema -{ - if ($version->supports(SchemaFeature::UnevaluatedProperties)) { - return $schema->unevaluatedProperties(false); - } else { - return $schema->additionalProperties(false); - } -} -``` - -### 3. Document Version Requirements - -```php -/** - * Create a modern user schema with advanced validation - * - * @param SchemaVersion $version Must be Draft 2019-09 or later for full features - * @throws SchemaException If version doesn't support required features - */ -function createAdvancedUserSchema(SchemaVersion $version): Schema -{ - if (!$version->supports(SchemaFeature::UnevaluatedProperties)) { - throw new SchemaException( - "Advanced user schema requires Draft 2019-09 or later" - ); - } - - return Schema::object('advanced_user', $version) - ->unevaluatedProperties(false); -} -``` - -## Common Use Cases - - - - Adapt schema validation based on API version and client capabilities. - - - Start with basic validation and add advanced features when supported. - - - Ensure schema compatibility across different JSON Schema validators. - - - Migrate schemas to newer versions while maintaining backward compatibility. - - - -## Next Steps - - - - Learn more about JSON Schema version differences and capabilities - - - Explore the complete API reference and method documentation - - diff --git a/docs/json-schema/versions.mdx b/docs/json-schema/versions.mdx index e100098..78c6b3c 100644 --- a/docs/json-schema/versions.mdx +++ b/docs/json-schema/versions.mdx @@ -9,7 +9,7 @@ icon: 'history' This package supports multiple JSON Schema specification versions with automatic feature validation to ensure compatibility. - + Legacy version for maximum compatibility across tools and libraries. Includes core validation features and basic conditionals. From d16ea983860702cdbc9225e5270a40807df4cf63 Mon Sep 17 00:00:00 2001 From: Sean Tymon Date: Mon, 26 Jan 2026 21:51:14 +0000 Subject: [PATCH 3/3] cleanup --- .../validation/data-validation.mdx | 222 ------------------ .../validation/version-features.mdx | 146 ------------ 2 files changed, 368 deletions(-) delete mode 100644 docs/json-schema/validation/data-validation.mdx delete mode 100644 docs/json-schema/validation/version-features.mdx diff --git a/docs/json-schema/validation/data-validation.mdx b/docs/json-schema/validation/data-validation.mdx deleted file mode 100644 index 91b650f..0000000 --- a/docs/json-schema/validation/data-validation.mdx +++ /dev/null @@ -1,222 +0,0 @@ ---- -title: Data Validation -description: 'Master data validation techniques with validate() and isValid() methods' -icon: 'check' ---- - -Data validation is the core functionality of JSON Schema. Learn how to validate data against your schemas, handle validation results, and work with validation errors effectively. - -## Basic Validation Methods - -Every schema provides two primary validation methods: - -```php -use Cortex\JsonSchema\Schema; -use Cortex\JsonSchema\Exceptions\SchemaException; - -$schema = Schema::string('name') - ->minLength(2) - ->maxLength(50) - ->required(); - -// Method 1: isValid() - returns boolean -$isValid = $schema->isValid('John Doe'); // true -$isValid = $schema->isValid('J'); // false - -// Method 2: validate() - throws exception on failure -try { - $schema->validate('John Doe'); - echo "Valid!"; -} catch (SchemaException $e) { - echo "Invalid: " . $e->getMessage(); -} -``` - -## Using isValid() for Boolean Checks - -The `isValid()` method is perfect for simple true/false validation: - -```php -$emailSchema = Schema::string('email') - ->format(SchemaFormat::Email) - ->required(); - -$emails = [ - 'valid@example.com', - 'invalid-email', - 'another@test.org' -]; - -$validEmails = []; -foreach ($emails as $email) { - if ($emailSchema->isValid($email)) { - $validEmails[] = $email; - } -} - -// $validEmails contains: ['valid@example.com', 'another@test.org'] -``` - -### Conditional Logic with isValid() - -```php -$userSchema = Schema::object('user') - ->properties( - Schema::string('name')->required(), - Schema::integer('age')->minimum(18)->required(), - Schema::string('email')->format(SchemaFormat::Email)->required() - ); - -$userData = [ - 'name' => 'John Doe', - 'age' => 25, - 'email' => 'john@example.com' -]; - -if ($userSchema->isValid($userData)) { - // Process valid user data - echo "Processing user: " . $userData['name']; -} else { - // Handle invalid data - echo "User data is invalid"; -} -``` - -## Using validate() for Detailed Error Information - -The `validate()` method throws descriptive exceptions when validation fails: - -```php -$productSchema = Schema::object('product') - ->properties( - Schema::string('name') - ->minLength(1) - ->maxLength(100) - ->required(), - Schema::number('price') - ->minimum(0) - ->multipleOf(0.01) - ->required(), - Schema::array('tags') - ->items(Schema::string()) - ->maxItems(10) - ) - ->additionalProperties(false); - -$productData = [ - 'name' => '', // Too short - 'price' => -10, // Below minimum - 'tags' => ['electronics', 'mobile', /* 9 more tags */], // Too many items - 'invalid_field' => 'not allowed' // Additional property -]; - -try { - $productSchema->validate($productData); -} catch (SchemaException $e) { - echo "Validation error: " . $e->getMessage(); - // "String must have minimum length of 1" - - // Access detailed error information - $errors = $e->getErrors(); - print_r($errors); -} -``` - -## Validating Complex Data Structures - -### Object Validation - -```php -$orderSchema = Schema::object('order') - ->properties( - Schema::string('id')->required(), - Schema::object('customer') - ->properties( - Schema::string('name')->required(), - Schema::string('email')->format(SchemaFormat::Email)->required() - ) - ->required(), - Schema::array('items') - ->items( - Schema::object() - ->properties( - Schema::string('sku')->required(), - Schema::integer('quantity')->minimum(1)->required(), - Schema::number('price')->minimum(0)->required() - ) - ) - ->minItems(1) - ->required() - ); - -$orderData = [ - 'id' => 'ORD-123', - 'customer' => [ - 'name' => 'John Doe', - 'email' => 'john@example.com' - ], - 'items' => [ - [ - 'sku' => 'PROD-001', - 'quantity' => 2, - 'price' => 29.99 - ], - [ - 'sku' => 'PROD-002', - 'quantity' => 1, - 'price' => 15.50 - ] - ] -]; - -if ($orderSchema->isValid($orderData)) { - echo "Order is valid"; -} else { - try { - $orderSchema->validate($orderData); - } catch (SchemaException $e) { - echo "Order validation failed: " . $e->getMessage(); - } -} -``` - -### Array Validation - -```php -$scoresSchema = Schema::array('test_scores') - ->items( - Schema::object() - ->properties( - Schema::string('student_id')->required(), - Schema::integer('score') - ->minimum(0) - ->maximum(100) - ->required(), - Schema::string('subject') - ->enum(['math', 'science', 'english', 'history']) - ->required() - ) - ) - ->minItems(1) - ->uniqueItems(true); - -$scoresData = [ - [ - 'student_id' => 'STU-001', - 'score' => 95, - 'subject' => 'math' - ], - [ - 'student_id' => 'STU-002', - 'score' => 87, - 'subject' => 'science' - ] -]; - -try { - $scoresSchema->validate($scoresData); - echo "All scores are valid"; -} catch (SchemaException $e) { - echo "Score validation error: " . $e->getMessage(); -} -``` diff --git a/docs/json-schema/validation/version-features.mdx b/docs/json-schema/validation/version-features.mdx deleted file mode 100644 index 7c42d05..0000000 --- a/docs/json-schema/validation/version-features.mdx +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: Version Feature Validation -description: 'Automatic validation of JSON Schema version compatibility and feature support' -icon: 'ticket-check' ---- - -The package automatically validates that schema features are compatible with the specified JSON Schema version, preventing runtime errors and ensuring schema portability across different validators. - -## Automatic Feature Validation - -When you use features that require specific JSON Schema versions, the package automatically validates compatibility: - -```php -use Cortex\JsonSchema\Schema; -use Cortex\JsonSchema\Enums\SchemaVersion; -use Cortex\JsonSchema\Exceptions\SchemaException; - -// ✅ This works - deprecated is supported in Draft 2019-09+ -$modernSchema = Schema::string('legacy_field', SchemaVersion::Draft_2019_09) - ->deprecated() - ->comment('Use new_field instead'); - -// ❌ This throws an exception - deprecated requires Draft 2019-09+ -try { - $invalidSchema = Schema::string('legacy_field', SchemaVersion::Draft_07) - ->deprecated(); // SchemaException thrown here -} catch (SchemaException $e) { - echo $e->getMessage(); - // "Feature 'Property deprecation annotation' is not supported in Draft 7. - // Minimum version required: Draft 2019-09." -} -``` - -## Feature Support Matrix - -Understanding which features are available in each JSON Schema version: - -### Core Validation (All Versions) - -```php -// These features work in all supported versions -$basicSchema = Schema::object('basic', SchemaVersion::Draft_07) - ->properties( - Schema::string('name') - ->minLength(2) - ->maxLength(100) - ->pattern('^[A-Za-z\s]+$') - ->required(), - Schema::integer('age') - ->minimum(0) - ->maximum(150) - ->required(), - Schema::array('tags') - ->items(Schema::string()) - ->minItems(1) - ->maxItems(10) - ->uniqueItems(true) - ) - ->additionalProperties(false); -``` - -### Conditional Logic (Draft-07+) - -```php -// if/then/else works in Draft-07 and later -$conditionalSchema = Schema::object('user', SchemaVersion::Draft_07) - ->properties( - Schema::string('type')->enum(['personal', 'business']), - Schema::string('company_name'), - Schema::string('tax_id') - ) - ->if( - Schema::object()->properties( - Schema::string('type')->const('business') - ) - ) - ->then( - Schema::object()->properties( - Schema::string('company_name')->required(), - Schema::string('tax_id')->required() - ) - ); -``` - -### Draft 2019-09 Features - -```php -// Advanced features requiring Draft 2019-09+ -$modernSchema = Schema::object('modern_user', SchemaVersion::Draft_2019_09) - ->properties( - Schema::string('name')->required(), - Schema::string('email')->required(), - - // Deprecated annotation - Schema::string('old_email') - ->deprecated() - ->comment('Use email field instead'), - - // Array contains validation - Schema::array('roles') - ->items(Schema::string()) - ->minContains(1) // At least one role required - ->maxContains(5), // Maximum 5 roles - - // Extended format support - Schema::string('id') - ->format(SchemaFormat::Uuid), - - Schema::string('session_duration') - ->format(SchemaFormat::Duration) - ) - // Unevaluated properties - ->unevaluatedProperties(false) - - // Dependent schemas - ->dependentSchema('old_email', - Schema::object() - ->if(Schema::object()->properties( - Schema::string('old_email')->minLength(1) - )) - ->then(Schema::object() - ->properties( - Schema::string('migration_date') - ->format(SchemaFormat::Date) - ->required() - ) - ) - ); -``` - -### Draft 2020-12 Features - -```php -// Cutting-edge features in Draft 2020-12 -$latestSchema = Schema::array('tuple_array', SchemaVersion::Draft_2020_12) - // Prefix items for tuple validation - ->prefixItems([ - Schema::string()->description('Name'), - Schema::integer()->minimum(0)->description('Age'), - Schema::boolean()->description('Active status') - ]) - // Additional items after prefix - ->items(Schema::string()->description('Additional info')) - // Unevaluated items control - ->unevaluatedItems(false); -```