Skip to content

Commit 76bba55

Browse files
tymondesignsCopilotCopilotgithub-advanced-security[bot]
authored
feat: Draft-06 support, adding $id and string content annotations (#22)
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: tymondesigns <1801923+tymondesigns@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
1 parent 1bcc68d commit 76bba55

31 files changed

+767
-80
lines changed

.github/workflows/sync-docs.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Sync Docs
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- 'docs/**'
8+
9+
jobs:
10+
notify-docs-repo:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: read
14+
steps:
15+
- uses: peter-evans/repository-dispatch@v3
16+
with:
17+
token: ${{ secrets.DOCS_TOKEN }}
18+
repository: cortexphp/docs
19+
event-type: docs-updated

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
## Features
1010

1111
- 🏗️ **Fluent Builder API** - Build JSON Schemas using an intuitive fluent interface
12-
- 📝 **Multi-Version Support** - Support for JSON Schema Draft-07, Draft 2019-09, and Draft 2020-12
12+
- 📝 **Multi-Version Support** - Support for JSON Schema Draft-06, Draft-07, Draft 2019-09, and Draft 2020-12
1313
-**Validation** - Validate data against schemas with detailed error messages
1414
- 🤝 **Conditional Schemas** - Support for if/then/else, allOf, anyOf, and not conditions
1515
- 🔄 **Reflection** - Generate schemas from PHP Classes, Enums and Closures
@@ -24,7 +24,8 @@ This package supports multiple JSON Schema specification versions with automatic
2424

2525
- **Draft 2020-12** - (Default) Latest version with `prefixItems`, dynamic references, and format vocabularies
2626
- **Draft 2019-09** - Adds advanced features like `$defs`, `unevaluatedProperties`, `deprecated`
27-
- **Draft-07** (2018) - Legacy version for maximum compatibility
27+
- **Draft-07** (2018) - Legacy version with broad tool compatibility
28+
- **Draft-06** (2017) - Legacy version for maximum compatibility with older tooling
2829

2930
## Requirements
3031

docs/json-schema/advanced/string-formats.mdx

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -173,27 +173,28 @@ $userProfileSchema->isValid($validProfile); // true
173173

174174
## Format Support by Version
175175

176-
| Format | Draft-07 | Draft 2019-09 | Draft 2020-12 | Description |
177-
|--------|----------|---------------|---------------|-------------|
178-
| `Email` |||| Standard email address |
179-
| `Uri` |||| URI reference |
180-
| `UriReference` |||| URI reference (relative or absolute) |
181-
| `Hostname` |||| Internet hostname |
182-
| `Ipv4` |||| IPv4 address |
183-
| `Ipv6` |||| IPv6 address |
184-
| `Date` |||| Full date |
185-
| `Time` |||| Time |
186-
| `DateTime` |||| Date and time |
187-
| `JsonPointer` |||| JSON Pointer |
188-
| `RelativeJsonPointer` |||| Relative JSON Pointer |
189-
| `UriTemplate` |||| URI Template |
190-
| `Regex` |||| Regular expression pattern |
176+
| Format | Draft-06 | Draft-07 | Draft 2019-09 | Draft 2020-12 | Description |
177+
|--------|----------|----------|---------------|---------------|-------------|
178+
| `Email` ||||| Standard email address |
179+
| `Uri` ||||| URI reference |
180+
| `UriReference` ||||| URI reference (relative or absolute) |
181+
| `Hostname` ||||| Internet hostname |
182+
| `Ipv4` ||||| IPv4 address |
183+
| `Ipv6` ||||| IPv6 address |
184+
| `Date` ||||| Full date |
185+
| `Time` ||||| Time |
186+
| `DateTime` ||||| Date and time |
187+
| `JsonPointer` ||||| JSON Pointer |
188+
| `RelativeJsonPointer` ||||| Relative JSON Pointer |
189+
| `UriTemplate` ||||| URI Template |
190+
| `Regex` ||||| Regular expression pattern |
191+
| `IdnEmail` ||||| Internationalized email |
192+
| `IdnHostname` ||||| Internationalized hostname |
193+
| `Iri` ||||| Internationalized URI |
194+
| `IriReference` ||||| IRI reference |
191195
| **Draft 2019-09+** |
192-
| `Duration` |||| ISO 8601 duration |
193-
| `Uuid` |||| UUID string |
194-
| `IdnEmail` |||| Internationalized email |
195-
| `Iri` |||| Internationalized URI |
196-
| `IriReference` |||| IRI reference |
196+
| `Duration` ||||| ISO 8601 duration |
197+
| `Uuid` ||||| UUID string |
197198

198199
## Common Use Cases
199200

docs/json-schema/installation.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ icon: 'terminal'
2626
use Cortex\JsonSchema\Enums\SchemaVersion;
2727

2828
// Override default version (if needed)
29-
Schema::setDefaultVersion(SchemaVersion::Draft_07); // For maximum compatibility
29+
Schema::setDefaultVersion(SchemaVersion::Draft_06); // For maximum compatibility
3030
// or
3131
Schema::setDefaultVersion(SchemaVersion::Draft_2019_09); // For balanced features
3232
```

docs/json-schema/introduction.mdx

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ icon: 'book-open'
2323
href="/json-schema/versions"
2424
icon="layers"
2525
>
26-
Support for JSON Schema Draft-07, Draft 2019-09, and Draft 2020-12 with automatic feature validation.
26+
Support for JSON Schema Draft-06, Draft-07, Draft 2019-09, and Draft 2020-12 with automatic feature validation.
2727
</Card>
2828
<Card
2929
title="Data Validation"
@@ -157,17 +157,17 @@ The package automatically validates feature compatibility with your chosen JSON
157157
</Warning>
158158

159159
<Tip>
160-
The package defaults to Draft 2020-12 for the latest features. Use Draft-07 for maximum compatibility with older tools, or Draft 2019-09 for a balance of features and compatibility.
160+
The package defaults to Draft 2020-12 for the latest features. Use Draft-06 for maximum compatibility with older tools, or Draft 2019-09 for a balance of features and compatibility.
161161
</Tip>
162162

163-
| Feature | Draft-07 | Draft 2019-09 | Draft 2020-12 |
164-
|---------|----------|---------------|---------------|
165-
| Basic validation ||||
166-
| Conditionals ||||
167-
| Basic formats ||||
168-
| `deprecated` ||||
169-
| `$defs` ||||
170-
| `minContains`/`maxContains` ||||
171-
| `unevaluatedProperties` ||||
172-
| `dependentSchemas` ||||
173-
| `prefixItems` ||||
163+
| Feature | Draft-06 | Draft-07 | Draft 2019-09 | Draft 2020-12 |
164+
|---------|----------|----------|---------------|---------------|
165+
| Basic validation |||||
166+
| Conditionals | | |||
167+
| Basic formats |||||
168+
| `deprecated` || | ||
169+
| `$defs` || | ||
170+
| `minContains`/`maxContains` || | ||
171+
| `unevaluatedProperties` || | ||
172+
| `dependentSchemas` || | ||
173+
| `prefixItems` ||| | |

docs/json-schema/quickstart.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ $modernSchema = Schema::string('field')
258258
->comment('Use newField instead');
259259

260260
// Override default version if needed
261-
Schema::setDefaultVersion(SchemaVersion::Draft_07); // For maximum compatibility
261+
Schema::setDefaultVersion(SchemaVersion::Draft_06); // For maximum compatibility
262262
```
263263

264264
## Common Validation Patterns
@@ -322,7 +322,7 @@ Schema::setDefaultVersion(SchemaVersion::Draft_07); // For maximum compatibility
322322
->comment('Use new_field instead');
323323

324324
// Override default version if needed for compatibility
325-
Schema::setDefaultVersion(SchemaVersion::Draft_07);
325+
Schema::setDefaultVersion(SchemaVersion::Draft_06);
326326
```
327327

328328
<Warning>

docs/json-schema/schema-types/string.mdx

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -129,23 +129,73 @@ $timeSchema = Schema::string('appointment_time')
129129
| `Hostname` | Internet hostname | `example.com` |
130130
| `Ipv4` | IPv4 address | `192.168.1.1` |
131131
| `Ipv6` | IPv6 address | `2001:db8::1` |
132-
| `Date` | Full date (RFC 3339) | `2023-12-25` |
133-
| `Time` | Time (RFC 3339) | `14:30:00` |
132+
| `Date` | Full date (RFC 3339) | `2023-12-25` |
133+
| `Time` | Time (RFC 3339) | `14:30:00` |
134134
| `DateTime` | Date-time (RFC 3339) | `2023-12-25T14:30:00Z` |
135135
| `Duration` | Duration (ISO 8601)* | `P1Y2M3DT4H5M6S` |
136136
| `Uuid` | UUID string* | `123e4567-e89b-12d3-a456-426614174000` |
137137
| `JsonPointer` | JSON Pointer | `/users/123/name` |
138-
| `RelativeJsonPointer` | Relative JSON Pointer | `1/name` |
138+
| `RelativeJsonPointer` | Relative JSON Pointer | `1/name` |
139139
| `UriTemplate` | URI Template | `/users/{id}` |
140-
| `IdnEmail` | Internationalized email | `用户@example.com` |
141-
| `IdnHostname` | Internationalized hostname | `例え.テスト` |
142-
| `Iri` | Internationalized URI | `https://例え.テスト` |
143-
| `IriReference` | IRI reference | `//例え.テスト/path` |
140+
| `Regex`| Regular expression pattern | `^[a-zA-Z0-9_]+$` |
141+
| `IdnEmail`| Internationalized email | `用户@example.com` |
142+
| `IdnHostname`| Internationalized hostname | `例え.テスト` |
143+
| `Iri`| Internationalized URI | `https://例え.テスト` |
144+
| `IriReference`| IRI reference | `//例え.テスト/path` |
144145

145146
<Note>
146-
Formats marked with * require JSON Schema Draft 2019-09 or later.
147+
Formats marked with require JSON Schema Draft-07 or later. Formats marked with * require Draft 2019-09 or later.
147148
</Note>
148149

150+
## Content Annotations
151+
152+
Describe encoded content carried by a string using `contentEncoding` and `contentMediaType`, and (optionally) validate the decoded content with `contentSchema`:
153+
154+
```php
155+
use Cortex\JsonSchema\Enums\SchemaVersion;
156+
use Cortex\JsonSchema\Enums\SchemaFormat;
157+
158+
$payloadSchema = Schema::string('payload', SchemaVersion::Draft_2019_09)
159+
->contentEncoding('base64')
160+
->contentMediaType('application/json')
161+
->contentSchema(
162+
Schema::object()
163+
->properties(
164+
Schema::string('event_id')->required(),
165+
Schema::string('type')->required(),
166+
Schema::string('created_at')->format(SchemaFormat::DateTime)->required(),
167+
Schema::object('data')
168+
->properties(
169+
Schema::string('user_id')->required(),
170+
Schema::string('email')->format(SchemaFormat::Email),
171+
)
172+
->required(),
173+
),
174+
);
175+
```
176+
177+
<Note>
178+
`contentSchema` requires JSON Schema Draft 2019-09 or later. `contentEncoding` and `contentMediaType` are available in all supported versions.
179+
</Note>
180+
181+
Validation examples:
182+
183+
```php
184+
$payloadSchema->isValid(base64_encode(
185+
json_encode([
186+
'event_id' => 'evt_123',
187+
'type' => 'user.created',
188+
'created_at' => '2024-03-14T12:00:00Z',
189+
'data' => [
190+
'user_id' => 'usr_1',
191+
'email' => 'ada@example.com',
192+
],
193+
], JSON_THROW_ON_ERROR),
194+
)); // true (base64 encoded string value and matches the content schema)
195+
196+
$payloadSchema->isValid(123); // false (not a string)
197+
```
198+
149199
## Enumeration Values
150200

151201
Restrict strings to a specific set of allowed values:
@@ -195,6 +245,10 @@ $passwordSchema = Schema::string('password')
195245
->pattern('(?=.*[a-z])(?=.*[A-Z])(?=.*\d)');
196246
```
197247

248+
<Note>
249+
Read-only and write-only annotations require JSON Schema Draft-07 or later.
250+
</Note>
251+
198252
## Complex Example
199253

200254
Here's a comprehensive example combining multiple string validation features:

docs/json-schema/versions.mdx

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ icon: 'history'
99
This package supports multiple JSON Schema specification versions with automatic feature validation to ensure compatibility.
1010

1111
<CardGroup cols={1}>
12+
<Card title="Draft-06 (2017)" icon="shield-check">
13+
Legacy version for maximum compatibility with older tools. Includes core validation features and basic constraints.
14+
</Card>
1215
<Card title="Draft-07 (2018)" icon="shield-check">
13-
Legacy version for maximum compatibility across tools and libraries. Includes core validation features and basic conditionals.
16+
Legacy version with broad compatibility across tools and libraries. Includes core validation features and conditionals.
1417
</Card>
1518
<Card title="Draft 2019-09" icon="star">
1619
Adds advanced features like `$defs`, `unevaluatedProperties`, `deprecated`, and enhanced array validation.
@@ -96,28 +99,28 @@ $arraySchema = Schema::array('items', SchemaVersion::Draft_07)
9699

97100
## Feature Support Matrix
98101

99-
| Feature | Draft-07 | Draft 2019-09 | Draft 2020-12 | Description |
100-
|---------|----------|---------------|---------------|-------------|
102+
| Feature | Draft-06 | Draft-07 | Draft 2019-09 | Draft 2020-12 | Description |
103+
|---------|----------|----------|---------------|---------------|-------------|
101104
| **Core Validation** |
102-
| `minLength`, `maxLength`, `pattern` |||| Basic string validation |
103-
| `minimum`, `maximum`, `multipleOf` |||| Numeric constraints |
104-
| `minItems`, `maxItems`, `uniqueItems` |||| Array validation |
105-
| `properties`, `required`, `additionalProperties` |||| Object validation |
105+
| `minLength`, `maxLength`, `pattern` |||| | Basic string validation |
106+
| `minimum`, `maximum`, `multipleOf` |||| | Numeric constraints |
107+
| `minItems`, `maxItems`, `uniqueItems` |||| | Array validation |
108+
| `properties`, `required`, `additionalProperties` |||| | Object validation |
106109
| **Conditionals** |
107-
| `if`/`then`/`else` |||| Conditional schemas |
108-
| `allOf`, `anyOf`, `oneOf`, `not` |||| Logical combinations |
110+
| `if`/`then`/`else` | | ||| Conditional schemas |
111+
| `allOf`, `anyOf`, `oneOf`, `not` |||| | Logical combinations |
109112
| **Advanced Features** |
110-
| `deprecated` |||| Property deprecation |
111-
| `$defs` (replaces `definitions`) |||| Schema definitions |
112-
| `minContains`, `maxContains` |||| Array contains validation |
113-
| `unevaluatedProperties`, `unevaluatedItems` |||| Strict validation |
114-
| `dependentSchemas` |||| Property dependencies |
113+
| `deprecated` || | || Property deprecation |
114+
| `$defs` (replaces `definitions`) || | || Schema definitions |
115+
| `minContains`, `maxContains` || | || Array contains validation |
116+
| `unevaluatedProperties`, `unevaluatedItems` || | || Strict validation |
117+
| `dependentSchemas` || | || Property dependencies |
115118
| **Draft 2020-12 Only** |
116-
| `prefixItems` |||| Tuple validation |
117-
| Dynamic references (`$dynamicRef`) |||| Dynamic schema refs |
119+
| `prefixItems` ||| | | Tuple validation |
120+
| Dynamic references (`$dynamicRef`) ||| | | Dynamic schema refs |
118121
| **Formats** |
119-
| `email`, `uri`, `date-time` |||| Basic formats |
120-
| `duration`, `uuid` |||| Extended formats |
122+
| `email`, `uri`, `date-time` |||| | Basic formats |
123+
| `duration`, `uuid` || | || Extended formats |
121124

122125
## Version-Appropriate Output
123126

@@ -181,5 +184,5 @@ echo $feature->getMinimumVersion()->name; // "Draft201909"
181184
```
182185

183186
<Tip>
184-
The package defaults to Draft 2020-12 for the latest features. Use Draft-07 for maximum compatibility with older tools if needed.
187+
The package defaults to Draft 2020-12 for the latest features. Use Draft-06 for maximum compatibility with older tools if needed.
185188
</Tip>

0 commit comments

Comments
 (0)