jsonschema_rs 0.49.9-aarch64-linux → 0.50.0-aarch64-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +37 -1
- data/README.md +78 -0
- data/lib/jsonschema/3.3/jsonschema_rb.so +0 -0
- data/lib/jsonschema/3.4/jsonschema_rb.so +0 -0
- data/lib/jsonschema/4.0/jsonschema_rb.so +0 -0
- data/lib/jsonschema/version.rb +1 -1
- data/sig/jsonschema.rbs +96 -10
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 25eabdf997035d336701b550d29389ed1f9b894beb03d77fc45a0b10ccb4d29c
|
|
4
|
+
data.tar.gz: d62cff75ffb98e41ce3977d518c2427f38b3625925b76c036b46c0f45b75de8e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 46b9f8e8fc9a227c31299f26f3542ca5885ec1f680956d723cbe6978fd4b280a87a24e9b0a277e103ba6290a1fe2392a28e7387f590e7801f254f3de9f0d37f2
|
|
7
|
+
data.tar.gz: fe336068954a246f515ea3adf1f9c269891fabeed2e286a7109df28f80d7ae2d100bebfa80cd62bb66251d472a800d87805dcec7d0fe95e440e988d55bf427d2
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,41 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.50.0] - 2026-08-20
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- `CanonicalSchema#union` and `CanonicalSchema#subtract`.
|
|
10
|
+
- `JSONSchema::Canonical::UnsupportedResult`, raised where the canonical form does not support a set operation's result.
|
|
11
|
+
- `JSONSchema::Canonical::IncompatibleOperands` where both operands read `#` and it names a different document on each side.
|
|
12
|
+
- `JSONSchema::Canonical::Containment`, `Satisfiability`, `Distinctness` and `Kind`: named constants for the symbols `covers`, `satisfiability`, `kind` and `ArrayView#distinctness` return, each with an `ALL` list.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- `CanonicalSchema#satisfiable?` is now `CanonicalSchema#satisfiability`, answering `:yes`, `:no`, or `:unknown` - `:yes` wherever a value can be exhibited, not only for the forms listing their members.
|
|
17
|
+
- `CanonicalSchema#covers` decides through the difference as well: `:no` where the argument keeps values the receiver rejects, `:yes` where nothing is left over.
|
|
18
|
+
- `CanonicalSchema#is_subset_of` is now `CanonicalSchema#covers`, answering `:yes`, `:no`, or `:unknown` for whether the receiver admits every value the argument admits.
|
|
19
|
+
- `CanonicalSchema#negate` raises where it used to return `nil`.
|
|
20
|
+
- `JSONSchema::Canonical::UnmodeledOperand` is now `JSONSchema::Canonical::UnsupportedOperand`, and means only that an operand is a `Raw` pass-through.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Combining nodes of two different documents repointing a `$ref` to `#` at the combined result instead of the document it was written in, including one named by a definition the result keeps.
|
|
25
|
+
- Intersecting a `$ref` whose target is `true` or `false`, which crashed the interpreter.
|
|
26
|
+
- A key constraint left un-narrowed once a run is out of intersections, which crashed the interpreter on the next read of it.
|
|
27
|
+
- `CanonicalSchema#covers` answering `:unknown` for a schema against itself, where that schema is a `$ref`.
|
|
28
|
+
- `CanonicalSchema#union` keeping a `$ref` beside the schema it names, where the other three operations read through it.
|
|
29
|
+
- `CanonicalSchema#covers` and `CanonicalSchema#subtract` cancelling two nodes written the same way whose `#` names a different document.
|
|
30
|
+
- Two results accepting the same values comparing unequal over the part of their documents neither reads.
|
|
31
|
+
- `additionalProperties` reaching a key the pattern map matches when a finite key constraint closes the map, which dropped values both operands accept.
|
|
32
|
+
- A recursive definition stopping every other pointer in the document from being read through.
|
|
33
|
+
- One `$defs` entry read past a wider schema written out at every use, rather than kept as the pointer it was.
|
|
34
|
+
- Set operations rejecting one document canonicalized twice, and a pruned result rejected against the document it came from, where the maps resolve every shared reference the same way.
|
|
35
|
+
- Set operations comparing a `$ref` as a pointer instead of reading through it, so a schema written with a `$ref` did not cancel against the same schema written out.
|
|
36
|
+
- `CanonicalSchema#subtract` asking for a complement where the difference is one of the operands or empty, declining on schemas it can subtract.
|
|
37
|
+
- Set operations keeping `$defs` entries the result no longer references, which then showed up in the emitted schema.
|
|
38
|
+
- `CanonicalSchema#union` declining over an approximated intersection, where the union itself is exact.
|
|
39
|
+
|
|
5
40
|
## [0.49.9] - 2026-08-10
|
|
6
41
|
|
|
7
42
|
### Added
|
|
@@ -387,7 +422,8 @@
|
|
|
387
422
|
|
|
388
423
|
- Initial public release
|
|
389
424
|
|
|
390
|
-
[Unreleased]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.
|
|
425
|
+
[Unreleased]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.50.0...HEAD
|
|
426
|
+
[0.50.0]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.9...ruby-v0.50.0
|
|
391
427
|
[0.49.9]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.8...ruby-v0.49.9
|
|
392
428
|
[0.49.8]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.7...ruby-v0.49.8
|
|
393
429
|
[0.49.7]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.6...ruby-v0.49.7
|
data/README.md
CHANGED
|
@@ -50,6 +50,7 @@ end
|
|
|
50
50
|
- 🔧 Custom keywords and format validators
|
|
51
51
|
- ✨ Meta-schema validation for schema documents
|
|
52
52
|
- 📦 Schema bundling into Compound Schema Documents
|
|
53
|
+
- 🧮 Experimental schema canonicalization
|
|
53
54
|
- ♦️ Supports Ruby 3.2, 3.4 and 4.0
|
|
54
55
|
|
|
55
56
|
### Supported drafts
|
|
@@ -291,6 +292,83 @@ dump_a == dump_b # => true
|
|
|
291
292
|
|
|
292
293
|
Main use case: deduplicating equivalent JSON Schemas.
|
|
293
294
|
|
|
295
|
+
## Schema Canonicalization
|
|
296
|
+
|
|
297
|
+
> **Experimental**: the canonicalization API may change in minor releases.
|
|
298
|
+
|
|
299
|
+
`JSONSchema.canonicalize` reduces a schema to a normal form without changing the values it accepts. Schemas that accept the same values reduce to equal `CanonicalSchema` objects, and contradictions reduce to `false`:
|
|
300
|
+
|
|
301
|
+
```ruby
|
|
302
|
+
canonical = JSONSchema.canonicalize(
|
|
303
|
+
{ "allOf" => [{ "type" => "integer", "minimum" => 0 }, { "minimum" => 10, "maximum" => 100 }] }
|
|
304
|
+
)
|
|
305
|
+
canonical.to_json_schema
|
|
306
|
+
# => {"$schema"=>"https://json-schema.org/draft/2020-12/schema",
|
|
307
|
+
# "type"=>"integer", "minimum"=>10, "maximum"=>100}
|
|
308
|
+
|
|
309
|
+
# However they were written, equivalent schemas compare equal
|
|
310
|
+
canonical == JSONSchema.canonicalize({ "type" => "integer", "maximum" => 100, "minimum" => 10 })
|
|
311
|
+
# => true
|
|
312
|
+
|
|
313
|
+
# A schema no value can satisfy collapses
|
|
314
|
+
JSONSchema.canonicalize({ "type" => "integer", "minimum" => 10, "maximum" => 5 }).satisfiability
|
|
315
|
+
# => :no, which is JSONSchema::Canonical::Satisfiability::NO
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
A canonical schema *is* the set of values it accepts, so canonical schemas combine as sets. Every emitted schema carries `$schema`, left out of the comments below:
|
|
319
|
+
|
|
320
|
+
```ruby
|
|
321
|
+
positive = JSONSchema.canonicalize({ "type" => "integer", "minimum" => 0 })
|
|
322
|
+
bounded = JSONSchema.canonicalize({ "type" => "integer", "maximum" => 100 })
|
|
323
|
+
|
|
324
|
+
# Every value both admit
|
|
325
|
+
positive.intersect(bounded).to_json_schema
|
|
326
|
+
# => {"type"=>"integer", "minimum"=>0, "maximum"=>100}
|
|
327
|
+
|
|
328
|
+
# Every value either admits
|
|
329
|
+
positive.union(bounded).to_json_schema
|
|
330
|
+
# => {"type"=>"integer"}
|
|
331
|
+
|
|
332
|
+
# Every value `positive` admits and `bounded` rejects
|
|
333
|
+
positive.subtract(bounded).to_json_schema
|
|
334
|
+
# => {"type"=>"integer", "minimum"=>101}
|
|
335
|
+
|
|
336
|
+
# Every value `positive` rejects, across the types it never admitted
|
|
337
|
+
positive.negate.to_json_schema
|
|
338
|
+
# => {"anyOf"=>[{"type"=>["null", "boolean", "string", "array", "object"]},
|
|
339
|
+
# {"type"=>"integer", "maximum"=>-1},
|
|
340
|
+
# {"type"=>"number", "not"=>{"multipleOf"=>1}}]}
|
|
341
|
+
|
|
342
|
+
positive.covers(bounded) # => :no - `bounded` takes negative integers, `positive` does not
|
|
343
|
+
positive.satisfiability # => :yes
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Comparing two versions of a schema
|
|
347
|
+
|
|
348
|
+
The difference answers what editing a schema did to the values it takes: it accepts exactly what the old schema took and the new one turns away, and is unsatisfiable exactly when nothing was lost.
|
|
349
|
+
|
|
350
|
+
```ruby
|
|
351
|
+
old = JSONSchema.canonicalize({ "type" => "string" })
|
|
352
|
+
new = JSONSchema.canonicalize({ "type" => "string", "maxLength" => 50 })
|
|
353
|
+
|
|
354
|
+
# What `new` stopped accepting, as a schema
|
|
355
|
+
old.subtract(new).to_json_schema
|
|
356
|
+
# => {"$schema"=>"https://json-schema.org/draft/2020-12/schema",
|
|
357
|
+
# "type"=>"string", "minLength"=>51}
|
|
358
|
+
|
|
359
|
+
# Nothing is accepted that was not accepted before, so the change only narrows
|
|
360
|
+
new.subtract(old).satisfiability
|
|
361
|
+
# => :no
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
Compare a request schema new-against-old and a response schema old-against-new: narrowing a request turns away payloads a caller used to send, widening a response returns values a caller never agreed to read.
|
|
365
|
+
|
|
366
|
+
`:no` on the difference proves nothing was lost. `:unknown` proves nothing either way.
|
|
367
|
+
|
|
368
|
+
`JSONSchema::Canonical::Containment`, `Satisfiability`, `Distinctness` and `Kind` hold these symbols as constants, each with an `ALL` list.
|
|
369
|
+
|
|
370
|
+
Both operands must share one setup - the same draft, format policy, regular-expression engine and definitions - or `IncompatibleOperands` is raised. `UnsupportedOperand` means an operand is a `Raw` pass-through, and `UnsupportedResult` that the canonical form does not support the result. All three live under `JSONSchema::Canonical`.
|
|
371
|
+
|
|
294
372
|
## Schema Bundling
|
|
295
373
|
|
|
296
374
|
Produce a Compound Schema Document ([Appendix B](https://json-schema.org/draft/2020-12/json-schema-core#appendix-B)) by embedding all external `$ref` targets into a draft-appropriate container. The result validates identically to the original.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/lib/jsonschema/version.rb
CHANGED
data/sig/jsonschema.rbs
CHANGED
|
@@ -17,11 +17,64 @@ module JSONSchema
|
|
|
17
17
|
|
|
18
18
|
# Structural discriminant of a canonical schema, one per view class.
|
|
19
19
|
type kind = :multi_type | :typed_group | :string | :integer | :number | :array
|
|
20
|
-
| :object | :const | :enum | :
|
|
20
|
+
| :object | :const | :enum | :not | :all_of | :any_of | :one_of
|
|
21
|
+
| :reference | :true | :false | :raw
|
|
22
|
+
|
|
23
|
+
# What an array requires of its elements: all distinct, some repeated, or neither.
|
|
24
|
+
type distinctness = :unconstrained | :all_distinct | :some_repeated
|
|
25
|
+
|
|
26
|
+
# Whether one schema admits every value another does.
|
|
27
|
+
type containment = :yes | :no | :unknown
|
|
28
|
+
|
|
29
|
+
# Whether any value satisfies a schema.
|
|
30
|
+
type satisfiability = :yes | :no | :unknown
|
|
21
31
|
|
|
22
32
|
type view = TrueView | FalseView | MultiTypeView | TypedGroupView | StringView
|
|
23
|
-
| IntegerView | NumberView | ArrayView | ObjectView |
|
|
24
|
-
|
|
|
33
|
+
| IntegerView | NumberView | ArrayView | ObjectView | NotView
|
|
34
|
+
| AllOfView | AnyOfView | OneOfView | ReferenceView | ConstView
|
|
35
|
+
| EnumView | RawView
|
|
36
|
+
|
|
37
|
+
module Containment
|
|
38
|
+
YES: :yes
|
|
39
|
+
NO: :no
|
|
40
|
+
UNKNOWN: :unknown
|
|
41
|
+
ALL: Array[containment]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
module Satisfiability
|
|
45
|
+
YES: :yes
|
|
46
|
+
NO: :no
|
|
47
|
+
UNKNOWN: :unknown
|
|
48
|
+
ALL: Array[satisfiability]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
module Distinctness
|
|
52
|
+
UNCONSTRAINED: :unconstrained
|
|
53
|
+
ALL_DISTINCT: :all_distinct
|
|
54
|
+
SOME_REPEATED: :some_repeated
|
|
55
|
+
ALL: Array[distinctness]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
module Kind
|
|
59
|
+
MULTI_TYPE: :multi_type
|
|
60
|
+
TYPED_GROUP: :typed_group
|
|
61
|
+
STRING: :string
|
|
62
|
+
INTEGER: :integer
|
|
63
|
+
NUMBER: :number
|
|
64
|
+
ARRAY: :array
|
|
65
|
+
OBJECT: :object
|
|
66
|
+
CONST: :const
|
|
67
|
+
ENUM: :enum
|
|
68
|
+
NOT: :not
|
|
69
|
+
ALL_OF: :all_of
|
|
70
|
+
ANY_OF: :any_of
|
|
71
|
+
ONE_OF: :one_of
|
|
72
|
+
REFERENCE: :reference
|
|
73
|
+
TRUE: :true
|
|
74
|
+
FALSE: :false
|
|
75
|
+
RAW: :raw
|
|
76
|
+
ALL: Array[kind]
|
|
77
|
+
end
|
|
25
78
|
|
|
26
79
|
class CanonicalizationError < StandardError
|
|
27
80
|
end
|
|
@@ -35,7 +88,10 @@ module JSONSchema
|
|
|
35
88
|
class IncompatibleOperands < CanonicalizationError
|
|
36
89
|
end
|
|
37
90
|
|
|
38
|
-
class
|
|
91
|
+
class UnsupportedOperand < CanonicalizationError
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
class UnsupportedResult < CanonicalizationError
|
|
39
95
|
end
|
|
40
96
|
|
|
41
97
|
# A schema reduced to canonical form: schemas accepting the same values share one form.
|
|
@@ -45,11 +101,13 @@ module JSONSchema
|
|
|
45
101
|
def kind: () -> kind
|
|
46
102
|
def view: () -> view
|
|
47
103
|
def intersect: (CanonicalSchema other) -> CanonicalSchema
|
|
48
|
-
def
|
|
49
|
-
def
|
|
104
|
+
def union: (CanonicalSchema other) -> CanonicalSchema
|
|
105
|
+
def subtract: (CanonicalSchema other) -> CanonicalSchema
|
|
106
|
+
def covers: (CanonicalSchema other) -> containment
|
|
107
|
+
def negate: () -> CanonicalSchema
|
|
50
108
|
def definition: (String uri) -> CanonicalSchema?
|
|
51
109
|
def definitions: () -> Hash[String, CanonicalSchema]
|
|
52
|
-
def
|
|
110
|
+
def satisfiability: () -> satisfiability
|
|
53
111
|
def inspect: () -> String
|
|
54
112
|
def ==: (untyped other) -> bool
|
|
55
113
|
def eql?: (untyped other) -> bool
|
|
@@ -121,7 +179,7 @@ module JSONSchema
|
|
|
121
179
|
class ArrayView
|
|
122
180
|
def min_items: () -> Integer?
|
|
123
181
|
def max_items: () -> Integer?
|
|
124
|
-
def distinctness: () ->
|
|
182
|
+
def distinctness: () -> distinctness
|
|
125
183
|
def prefix_items: () -> Array[CanonicalSchema]
|
|
126
184
|
def items: () -> CanonicalSchema?
|
|
127
185
|
def contains: () -> Array[ContainsView]
|
|
@@ -129,7 +187,7 @@ module JSONSchema
|
|
|
129
187
|
def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
|
|
130
188
|
end
|
|
131
189
|
|
|
132
|
-
# One `contains`
|
|
190
|
+
# One `contains` requirement of an array; an absent minimum means the default of one.
|
|
133
191
|
class ContainsView
|
|
134
192
|
def schema: () -> CanonicalSchema
|
|
135
193
|
def min_contains: () -> Integer?
|
|
@@ -168,6 +226,34 @@ module JSONSchema
|
|
|
168
226
|
def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
|
|
169
227
|
end
|
|
170
228
|
|
|
229
|
+
# The complement of an opaque schema.
|
|
230
|
+
class NotView
|
|
231
|
+
def schema: () -> CanonicalSchema
|
|
232
|
+
def inspect: () -> String
|
|
233
|
+
def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# A value matches iff every branch matches.
|
|
237
|
+
class AllOfView
|
|
238
|
+
def branches: () -> Array[CanonicalSchema]
|
|
239
|
+
def inspect: () -> String
|
|
240
|
+
def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# A value matches iff exactly one branch matches.
|
|
244
|
+
class OneOfView
|
|
245
|
+
def branches: () -> Array[CanonicalSchema]
|
|
246
|
+
def inspect: () -> String
|
|
247
|
+
def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# The target a `$ref` names.
|
|
251
|
+
class ReferenceView
|
|
252
|
+
def uri: () -> String
|
|
253
|
+
def inspect: () -> String
|
|
254
|
+
def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
|
|
255
|
+
end
|
|
256
|
+
|
|
171
257
|
# A value matches iff at least one branch matches.
|
|
172
258
|
class AnyOfView
|
|
173
259
|
def branches: () -> Array[CanonicalSchema]
|
|
@@ -189,7 +275,7 @@ module JSONSchema
|
|
|
189
275
|
def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
|
|
190
276
|
end
|
|
191
277
|
|
|
192
|
-
# A schema the canonical form does not
|
|
278
|
+
# A schema the canonical form does not support structurally, kept verbatim.
|
|
193
279
|
class RawView
|
|
194
280
|
def schema: () -> untyped
|
|
195
281
|
def inspect: () -> String
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jsonschema_rs
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.50.0
|
|
5
5
|
platform: aarch64-linux
|
|
6
6
|
authors:
|
|
7
7
|
- Dmitry Dygalo
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bigdecimal
|