Skip to content

Commit

Permalink
tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
tymondesigns committed Jan 13, 2025
1 parent 460d26f commit e4f3af5
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 28 deletions.
21 changes: 21 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) Sean Tymon <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
89 changes: 67 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ A PHP library for fluently building and validating JSON Schemas.
## Installation

```bash
composer require cortex/json-schema
composer require cortexphp/json-schema
```

## Usage

```php
use Cortex\JsonSchema\SchemaFactory;
use Cortex\JsonSchema\Enums\SchemaFormat;

// Create a basic user schema
$schema = SchemaFactory::object('user')
Expand All @@ -22,11 +23,11 @@ $schema = SchemaFactory::object('user')
->maxLength(100)
->required(),
SchemaFactory::string('email')
->format('email')
->format(SchemaFormat::Email)
->required(),
SchemaFactory::integer('age')
->minimum(0)
->maximum(120),
->minimum(18)
->maximum(150),
SchemaFactory::boolean('active')
->default(true),
SchemaFactory::object('settings')
Expand All @@ -40,34 +41,43 @@ $schema = SchemaFactory::object('user')
// Convert to array
$schema->toArray();

// Validate data
$schema->validate([
'name' => 'John Doe',
'email' => '[email protected]',
'age' => 30,
'active' => true,
'settings' => [
'theme' => 'dark',
'notifications' => true
],
]);
// Convert to JSON string
$schema->toJson();

// Validate data against the schema
try {
$schema->validate([
'name' => 'John Doe',
'email' => '[email protected]',
'age' => 16,
'active' => true,
'settings' => [
'theme' => 'dark',
'notifications' => true,
],
]);
} catch (SchemaException $e) {
echo $e->getMessage(); // "The data must match the 'email' format"
}

// Validate data against the schema
$schema->isValid($data);
```

## Available Schema Types

### String Schema

```php
use Cortex\JsonSchema\SchemaFactory;
use Cortex\JsonSchema\Enums\SchemaFormat;

SchemaFactory::string('name')
$schema = SchemaFactory::string('name')
->minLength(2)
->maxLength(100)
->pattern('^[A-Za-z]+$')
->format(SchemaFormat::Email)
->nullable()
->readOnly()
->writeOnly();
->readOnly();
```

<details>
Expand All @@ -81,13 +91,33 @@ SchemaFactory::string('name')
"minLength": 2,
"maxLength": 100,
"pattern": "^[A-Za-z]+$",
"format": "email",
"readOnly": true,
"writeOnly": true
"readOnly": true
}
```
</details>


```php
use Cortex\JsonSchema\SchemaFactory;
use Cortex\JsonSchema\Enums\SchemaFormat;

$schema = SchemaFactory::string('email')
->format(SchemaFormat::Email)
->nullable()
```
<details>
<summary>View JSON Schema</summary>

```json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": ["string", "null"],
"format": "email"
}
```
</details>


### Number Schema

```php
Expand Down Expand Up @@ -371,3 +401,18 @@ Example JSON output:
}
}
```

## Testing

```bash
composer test
```

## Credits

- [Sean Tymon](https://github.com/tymondesigns)
- [All Contributors](../../contributors)

## License

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
33 changes: 32 additions & 1 deletion src/Exceptions/SchemaException.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,36 @@
namespace Cortex\JsonSchema\Exceptions;

use Exception;
use Opis\JsonSchema\Errors\ErrorFormatter;
use Opis\JsonSchema\Errors\ValidationError;

class SchemaException extends Exception {}
class SchemaException extends Exception
{
protected ValidationError $error;

public static function failedValidation(ValidationError $error): self
{
$exception = new self(
(new ErrorFormatter())->formatErrorMessage($error),
);

$exception->setError($error);

return $exception;
}

protected function setError(ValidationError $error): void
{
$this->error = $error;
}

public function getError(): ValidationError
{
return $this->error;
}

public function getErrors(): array

Check failure on line 36 in src/Exceptions/SchemaException.php

View workflow job for this annotation

GitHub Actions / phpstan

Method Cortex\JsonSchema\Exceptions\SchemaException::getErrors() return type has no value type specified in iterable type array.
{
return (new ErrorFormatter())->format($this->error);
}
}
4 changes: 1 addition & 3 deletions src/Types/Concerns/HasValidation.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ public function validate(mixed $value): void
$error = $result->error();

if ($error !== null) {
throw new SchemaException(
(new ErrorFormatter())->formatErrorMessage($error),
);
throw SchemaException::failedValidation($error);
}
}

Expand Down
29 changes: 27 additions & 2 deletions tests/Unit/Targets/ObjectSchemaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Cortex\JsonSchema\Tests\Unit;

use Cortex\JsonSchema\Enums\SchemaFormat;
use Opis\JsonSchema\Errors\ErrorFormatter;
use Cortex\JsonSchema\SchemaFactory as Schema;
use Cortex\JsonSchema\Exceptions\SchemaException;

Expand All @@ -21,7 +22,7 @@
->format(SchemaFormat::Email)
->required(),
Schema::integer('age')
->minimum(0)
->minimum(18)
->maximum(150),
);

Expand All @@ -37,7 +38,7 @@
expect($schemaArray)->toHaveKey('properties.email.type', 'string');
expect($schemaArray)->toHaveKey('properties.email.format', 'email');
expect($schemaArray)->toHaveKey('properties.age.type', 'integer');
expect($schemaArray)->toHaveKey('properties.age.minimum', 0);
expect($schemaArray)->toHaveKey('properties.age.minimum', 18);
expect($schemaArray)->toHaveKey('properties.age.maximum', 150);
expect($schemaArray)->toHaveKey('required', ['name', 'email']);

Expand Down Expand Up @@ -78,6 +79,30 @@
);
});

it('can get the underlying errors', function (): void {
$schema = Schema::object('user')
->properties(
Schema::string('name')->required(),
Schema::string('email')->format(SchemaFormat::Email),
);

try {
$schema->validate([
'name' => 'John Doe',
'email' => 'foo',
]);
} catch (SchemaException $e) {
expect($e->getMessage())->toBe('The properties must match schema: email');
expect($e->getErrors())->toBe([
'/email' => [
'The data must match the \'email\' format'
],
]);

throw $e;
}
})->throws(SchemaException::class);

it('can create an object schema with additional properties control', function (): void {
$schema = Schema::object('config')
->description('Configuration object')
Expand Down

0 comments on commit e4f3af5

Please sign in to comment.