Skip to content

Commit efaa067

Browse files
nunomaduroStyleCIBottaylorotwell
authored
[12.x] Adds internal class (#56903)
* Adds internal json schema class * Apply fixes from StyleCI * Removes phpstan ignores * missing type * missing import * visibility * formatting --------- Co-authored-by: StyleCI Bot <[email protected]> Co-authored-by: Taylor Otwell <[email protected]>
1 parent 5680b61 commit efaa067

23 files changed

+1383
-0
lines changed

composer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
"illuminate/filesystem": "self.version",
8282
"illuminate/hashing": "self.version",
8383
"illuminate/http": "self.version",
84+
"illuminate/json-schema": "self.version",
8485
"illuminate/log": "self.version",
8586
"illuminate/macroable": "self.version",
8687
"illuminate/mail": "self.version",
@@ -113,6 +114,7 @@
113114
"league/flysystem-read-only": "^3.25.1",
114115
"league/flysystem-sftp-v3": "^3.25.1",
115116
"mockery/mockery": "^1.6.10",
117+
"opis/json-schema": "^2.4.1",
116118
"orchestra/testbench-core": "^10.6.5",
117119
"pda/pheanstalk": "^5.0.6|^7.0.0",
118120
"php-http/discovery": "^1.15",
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/.github export-ignore
2+
.gitattributes export-ignore
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name: Close Pull Request
2+
3+
on:
4+
pull_request_target:
5+
types: [opened]
6+
7+
jobs:
8+
run:
9+
runs-on: ubuntu-24.04
10+
steps:
11+
- uses: superbrothers/close-pull-request@v3
12+
with:
13+
comment: "Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!"
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Illuminate\JsonSchema;
4+
5+
use Closure;
6+
use Illuminate\JsonSchema\Types\Type;
7+
8+
/**
9+
* @method static Types\ObjectType object(Closure|array<string, Types\Type> $properties = [])
10+
* @method static Types\IntegerType integer()
11+
* @method static Types\NumberType number()
12+
* @method static Types\StringType string()
13+
* @method static Types\BooleanType boolean()
14+
* @method static Types\ArrayType array()
15+
*/
16+
class JsonSchema
17+
{
18+
/**
19+
* Dynamically pass static methods to the schema instance.
20+
*/
21+
public static function __callStatic(string $name, mixed $arguments): Type
22+
{
23+
return (new JsonSchemaTypeFactory)->$name(...$arguments);
24+
}
25+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
namespace Illuminate\JsonSchema;
4+
5+
use Closure;
6+
7+
class JsonSchemaTypeFactory extends JsonSchema
8+
{
9+
/**
10+
* Create a new object schema instance.
11+
*
12+
* @param (Closure(JsonSchemaTypeFactory): array<string, Types\Type>)|array<string, Types\Type> $properties
13+
*/
14+
public function object(Closure|array $properties = []): Types\ObjectType
15+
{
16+
if ($properties instanceof Closure) {
17+
$properties = $properties($this);
18+
}
19+
20+
return new Types\ObjectType($properties);
21+
}
22+
23+
/**
24+
* Create a new array property instance.
25+
*/
26+
public function array(): Types\ArrayType
27+
{
28+
return new Types\ArrayType;
29+
}
30+
31+
/**
32+
* Create a new string property instance.
33+
*/
34+
public function string(): Types\StringType
35+
{
36+
return new Types\StringType;
37+
}
38+
39+
/**
40+
* Create a new integer property instance.
41+
*/
42+
public function integer(): Types\IntegerType
43+
{
44+
return new Types\IntegerType;
45+
}
46+
47+
/**
48+
* Create a new number property instance.
49+
*/
50+
public function number(): Types\NumberType
51+
{
52+
return new Types\NumberType;
53+
}
54+
55+
/**
56+
* Create a new boolean property instance.
57+
*/
58+
public function boolean(): Types\BooleanType
59+
{
60+
return new Types\BooleanType;
61+
}
62+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) Taylor Otwell
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
namespace Illuminate\JsonSchema;
4+
5+
use RuntimeException;
6+
7+
class Serializer
8+
{
9+
/**
10+
* The properties to ignore when serializing.
11+
*
12+
* @var array<int, string>
13+
*/
14+
protected static array $ignore = ['required'];
15+
16+
/**
17+
* Serialize the given property to an array.
18+
*
19+
* @return array<string, mixed>
20+
*/
21+
public static function serialize(Types\Type $type): array
22+
{
23+
/** @var array<string, mixed> $attributes */
24+
$attributes = (fn () => get_object_vars($type))->call($type);
25+
26+
$attributes['type'] = match (get_class($type)) {
27+
Types\ArrayType::class => 'array',
28+
Types\BooleanType::class => 'boolean',
29+
Types\IntegerType::class => 'integer',
30+
Types\NumberType::class => 'number',
31+
Types\ObjectType::class => 'object',
32+
Types\StringType::class => 'string',
33+
default => throw new RuntimeException('Unsupported ['.get_class($type).'] type.'),
34+
};
35+
36+
$attributes = array_filter($attributes, static function (mixed $value, string $key) {
37+
if (in_array($key, static::$ignore, true)) {
38+
return false;
39+
}
40+
41+
return $value !== null;
42+
}, ARRAY_FILTER_USE_BOTH);
43+
44+
if ($type instanceof Types\ObjectType) {
45+
if (count($attributes['properties']) === 0) {
46+
unset($attributes['properties']);
47+
} else {
48+
$required = array_keys(array_filter(
49+
$attributes['properties'],
50+
static fn (Types\Type $property) => static::isRequired($property),
51+
));
52+
53+
if (count($required) > 0) {
54+
$attributes['required'] = $required;
55+
}
56+
57+
$attributes['properties'] = array_map(
58+
static fn (Types\Type $property) => static::serialize($property),
59+
$attributes['properties'],
60+
);
61+
}
62+
}
63+
64+
if ($type instanceof Types\ArrayType) {
65+
if (isset($attributes['items']) && $attributes['items'] instanceof Types\Type) {
66+
$attributes['items'] = static::serialize($attributes['items']);
67+
}
68+
}
69+
70+
return $attributes;
71+
}
72+
73+
/**
74+
* Determine if the given type is required.
75+
*/
76+
protected static function isRequired(Types\Type $type): bool
77+
{
78+
$attributes = (fn () => get_object_vars($type))->call($type);
79+
80+
return isset($attributes['required']) && $attributes['required'] === true;
81+
}
82+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
namespace Illuminate\JsonSchema\Types;
4+
5+
class ArrayType extends Type
6+
{
7+
/**
8+
* The minimum number of items (inclusive).
9+
*/
10+
protected ?int $minItems = null;
11+
12+
/**
13+
* The maximum number of items (inclusive).
14+
*/
15+
protected ?int $maxItems = null;
16+
17+
/**
18+
* The schema of the items contained in the array.
19+
*/
20+
protected ?Type $items = null;
21+
22+
/**
23+
* Set the minimum number of items (inclusive).
24+
*/
25+
public function min(int $value): static
26+
{
27+
$this->minItems = $value;
28+
29+
return $this;
30+
}
31+
32+
/**
33+
* Set the maximum number of items (inclusive).
34+
*/
35+
public function max(int $value): static
36+
{
37+
$this->maxItems = $value;
38+
39+
return $this;
40+
}
41+
42+
/**
43+
* Set the schema for array items.
44+
*/
45+
public function items(Type $type): static
46+
{
47+
$this->items = $type;
48+
49+
return $this;
50+
}
51+
52+
/**
53+
* Set the type's default value.
54+
*
55+
* @param array<int, mixed> $value
56+
*/
57+
public function default(array $value): static
58+
{
59+
$this->default = $value;
60+
61+
return $this;
62+
}
63+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Illuminate\JsonSchema\Types;
4+
5+
class BooleanType extends Type
6+
{
7+
/**
8+
* Set the type's default value.
9+
*/
10+
public function default(bool $value): static
11+
{
12+
$this->default = $value;
13+
14+
return $this;
15+
}
16+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
namespace Illuminate\JsonSchema\Types;
4+
5+
class IntegerType extends Type
6+
{
7+
/**
8+
* The minimum value (inclusive).
9+
*/
10+
protected ?int $minimum = null;
11+
12+
/**
13+
* The maximum value (inclusive).
14+
*/
15+
protected ?int $maximum = null;
16+
17+
/**
18+
* Set the minimum value (inclusive).
19+
*/
20+
public function min(int $value): static
21+
{
22+
$this->minimum = $value;
23+
24+
return $this;
25+
}
26+
27+
/**
28+
* Set the maximum value (inclusive).
29+
*/
30+
public function max(int $value): static
31+
{
32+
$this->maximum = $value;
33+
34+
return $this;
35+
}
36+
37+
/**
38+
* Set the type's default value.
39+
*/
40+
public function default(int $value): static
41+
{
42+
$this->default = $value;
43+
44+
return $this;
45+
}
46+
}

0 commit comments

Comments
 (0)