jsonschema_rs 0.58.4-x86_64-linux → 0.58.5-x86_64-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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1367fe986e5e10343a016ffbbbf4102d6bd8fb3f2d4fa3a95ab0910a6d5bcefc
4
- data.tar.gz: ea28a97d4e2df110b0e8e0dc9f374fe05976f33e3180f3ce49e3b46bc67c605c
3
+ metadata.gz: 609381d7d1434b191f8a4baf7419da3ed20aade3158453a003828e8514fe271a
4
+ data.tar.gz: 520691c03c36c7b4a76e58f10262596229d3c7113193917b87e67e62b523b604
5
5
  SHA512:
6
- metadata.gz: 67ca8481e73e7015f2af0b58d9529f5b82810bb1bd4880ed988d1ea911780a797bdb627e690588e285326aec9ceebaf9ad02ce9928102de414c10e2e0d08d5e5
7
- data.tar.gz: 6c782a5efb03a129bd4de7ad0228ccac6ae659a080388a4755d7e227841da981db3ae0988bf4eea101e76bb007329efd93b3b41d8bbfa46d87d1d6e81c73a442
6
+ metadata.gz: 9177a2102587dfc344015a8994ce836dc80aa8010acb42eec4abef86866988ceec8f0d33fb2fcba12dafc2b1ded51bf26adc7d5d266b609f854aaa6e80a68884
7
+ data.tar.gz: 5047aab2859b1dc3839013ea99abe15b4cc846bbb86591431636dfd3dc4750b589063fd37376c3a30478fcc684727f9a611a4c985a30a452602715dd94d12d5b
data/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.58.5] - 2026-10-02
6
+
7
+ ### Fixed
8
+
9
+ - `canonicalize` keeping a reference to a cycle of bare references under `not` or `oneOf` instead of treating it as accepting every value.
10
+ - Validator construction holding the GVL while it retrieves external resources over HTTP or from files.
11
+
5
12
  ## [0.58.4] - 2026-10-01
6
13
 
7
14
  ### Fixed
@@ -637,7 +644,8 @@
637
644
 
638
645
  - Initial public release
639
646
 
640
- [Unreleased]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.58.4...HEAD
647
+ [Unreleased]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.58.5...HEAD
648
+ [0.58.5]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.58.4...ruby-v0.58.5
641
649
  [0.58.4]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.58.3...ruby-v0.58.4
642
650
  [0.58.3]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.58.2...ruby-v0.58.3
643
651
  [0.58.2]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.58.1...ruby-v0.58.2
data/README.md CHANGED
@@ -45,29 +45,29 @@ end
45
45
 
46
46
  ## Highlights
47
47
 
48
- - 📚 Full support for popular JSON Schema drafts
49
- - 🌐 Remote reference fetching (network/file)
48
+ - 📚 Drafts 4, 6, 7, 2019-09 and 2020-12
50
49
  - 🔧 Custom keywords and format validators
51
- - ✨ Meta-schema validation for schema documents
50
+ - ⚡ Compile-time validators for your own native extensions, via the Rust crate
51
+ - 🌐 `$ref` resolution over HTTP and from files
52
52
  - 📦 Schema bundling into Compound Schema Documents, and `$ref` dereferencing
53
+ - 🎨 Structured Output v1 reports (flag/list/hierarchical)
54
+ - ✨ Meta-schema validation for schema documents, including custom metaschemas
53
55
  - 🧮 Experimental schema canonicalization
54
56
  - ♦️ Supports Ruby 3.2, 3.4 and 4.0
55
57
 
56
58
  ### Supported drafts
57
59
 
58
- The following drafts are supported:
59
-
60
60
  - [![Draft 2020-12](https://img.shields.io/endpoint?url=https%3A%2F%2Fbowtie.report%2Fbadges%2Frust-jsonschema%2Fcompliance%2Fdraft2020-12.json)](https://bowtie.report/#/implementations/rust-jsonschema)
61
61
  - [![Draft 2019-09](https://img.shields.io/endpoint?url=https%3A%2F%2Fbowtie.report%2Fbadges%2Frust-jsonschema%2Fcompliance%2Fdraft2019-09.json)](https://bowtie.report/#/implementations/rust-jsonschema)
62
62
  - [![Draft 7](https://img.shields.io/endpoint?url=https%3A%2F%2Fbowtie.report%2Fbadges%2Frust-jsonschema%2Fcompliance%2Fdraft7.json)](https://bowtie.report/#/implementations/rust-jsonschema)
63
63
  - [![Draft 6](https://img.shields.io/endpoint?url=https%3A%2F%2Fbowtie.report%2Fbadges%2Frust-jsonschema%2Fcompliance%2Fdraft6.json)](https://bowtie.report/#/implementations/rust-jsonschema)
64
64
  - [![Draft 4](https://img.shields.io/endpoint?url=https%3A%2F%2Fbowtie.report%2Fbadges%2Frust-jsonschema%2Fcompliance%2Fdraft4.json)](https://bowtie.report/#/implementations/rust-jsonschema)
65
65
 
66
- You can check the current status on the [Bowtie Report](https://bowtie.report/#/implementations/rust-jsonschema).
66
+ Per-draft compliance results are on the [Bowtie Report](https://bowtie.report/#/implementations/rust-jsonschema).
67
67
 
68
68
  ## Playground
69
69
 
70
- If you'd like to try `jsonschema`, you can check the WebAssembly-powered [playground](https://jsonschema.dygalo.dev/) to see the results instantly.
70
+ Try schemas in the browser with the WebAssembly [playground](https://jsonschema.dygalo.dev/).
71
71
 
72
72
  ## Installation
73
73
 
@@ -77,13 +77,13 @@ Add to your Gemfile:
77
77
  gem 'jsonschema_rs'
78
78
  ```
79
79
 
80
- Pre-built native gems are available for:
80
+ Pre-built native gems:
81
81
 
82
82
  - **Linux**: `x86_64`, `aarch64` (glibc and musl)
83
83
  - **macOS**: `x86_64`, `arm64`
84
84
  - **Windows**: `x64` (mingw-ucrt)
85
85
 
86
- If no pre-built gem is available for your platform, it will be compiled from source during installation. You'll need:
86
+ On other platforms, `gem install` compiles from source and needs:
87
87
  - Ruby 3.2+
88
88
  - Rust toolchain ([rustup](https://rustup.rs/))
89
89
 
@@ -91,8 +91,8 @@ If no pre-built gem is available for your platform, it will be compiled from sou
91
91
 
92
92
  ### Reusable validators
93
93
 
94
- For validating multiple instances against the same schema, create a reusable validator.
95
- `validator_for` automatically detects the draft version from the `$schema` keyword in the schema and falls back to Draft 2020-12:
94
+ Build a validator once to check many instances against one schema.
95
+ `validator_for` detects the draft from `$schema` and falls back to Draft 2020-12:
96
96
 
97
97
  ```ruby
98
98
  validator = JSONSchema.validator_for({
@@ -108,7 +108,7 @@ validator.valid?({ "name" => "Alice", "age" => 30 }) # => true
108
108
  validator.valid?({ "age" => 30 }) # => false
109
109
  ```
110
110
 
111
- You can use draft-specific validators for different JSON Schema versions:
111
+ To pick the draft yourself, use a draft-specific class:
112
112
 
113
113
  ```ruby
114
114
  validator = JSONSchema::Draft7Validator.new(schema)
@@ -119,6 +119,8 @@ validator = JSONSchema::Draft7Validator.new(schema)
119
119
 
120
120
  ### Custom format validators
121
121
 
122
+ Pass a callable that takes a `String` and returns a boolean via `formats`. Drafts 2019-09 and 2020-12 treat `format` as an annotation, so set `validate_formats: true` to get it checked:
123
+
122
124
  ```ruby
123
125
  phone_format = ->(value) { value.match?(/^\+?[1-9]\d{1,14}$/) }
124
126
 
@@ -150,10 +152,10 @@ validator = JSONSchema.validator_for(
150
152
  ```
151
153
 
152
154
  Each custom keyword class must implement:
153
- - `initialize(parent_schema, value, schema_path)` - called during schema compilation
154
- - `validate(instance)` - raise on failure, return normally on success
155
+ - `initialize(parent_schema, value, schema_path)`: called once when the validator is built
156
+ - `validate(instance)`: raise to reject the value, return to accept it
155
157
 
156
- A class may also implement `iter_errors(instance)`, returning an array of exceptions, to report several problems from one keyword. `each_error` then surfaces each of them; when the method is absent it falls back to the single error from `validate`:
158
+ To report several problems from one keyword, also implement `iter_errors(instance)` returning an array of exceptions. `each_error` yields each of them. Without it, `each_error` yields the single error from `validate`:
157
159
 
158
160
  ```ruby
159
161
  class AllPositive
@@ -172,7 +174,7 @@ class AllPositive
172
174
  end
173
175
  ```
174
176
 
175
- When `validate` raises, the original exception is preserved as the `cause` of the `ValidationError`, so callers can inspect it (errors from `iter_errors` keep their exception as `cause` in the same way):
177
+ The resulting `ValidationError` keeps the raised exception as `cause`, for both `validate` and `iter_errors`:
176
178
 
177
179
  ```ruby
178
180
  begin
@@ -185,7 +187,7 @@ end
185
187
 
186
188
  ### Structured evaluation output
187
189
 
188
- When you need more than a boolean result, use the `evaluate` API to access the [JSON Schema Output v1](https://json-schema.org/draft/2020-12/json-schema-core#name-output-formatting) formats:
190
+ `evaluate` returns the [JSON Schema Output v1](https://json-schema.org/draft/2020-12/json-schema-core#name-output-formatting) formats instead of a boolean:
189
191
 
190
192
  ```ruby
191
193
  schema = {
@@ -203,14 +205,14 @@ evaluation = validator.evaluate({ "age" => "not_an_integer" })
203
205
  evaluation.valid? # => false
204
206
  ```
205
207
 
206
- **Flag output** — simplest, just valid/invalid:
208
+ **Flag output**: valid or invalid, nothing else:
207
209
 
208
210
  ```ruby
209
211
  evaluation.flag
210
212
  # => {valid: false}
211
213
  ```
212
214
 
213
- **List output** — flat list of all evaluation nodes:
215
+ **List output**: every evaluation node in a flat list:
214
216
 
215
217
  ```ruby
216
218
  evaluation.list
@@ -231,7 +233,7 @@ evaluation.list
231
233
  # ]}
232
234
  ```
233
235
 
234
- **Hierarchical output** — nested tree following schema structure:
236
+ **Hierarchical output**: the same nodes nested by schema structure:
235
237
 
236
238
  ```ruby
237
239
  evaluation.hierarchical
@@ -255,7 +257,7 @@ evaluation.hierarchical
255
257
  # ]}
256
258
  ```
257
259
 
258
- **Collected errors** — flat list of all errors across evaluation nodes:
260
+ **Collected errors**: every error across all nodes:
259
261
 
260
262
  ```ruby
261
263
  evaluation.errors
@@ -266,8 +268,8 @@ evaluation.errors
266
268
  # error: "\"not_an_integer\" is not of type \"integer\""}]
267
269
  ```
268
270
 
269
- **Collected annotations** — flat list of annotations from successfully validated nodes.
270
- When a node fails validation, its annotations appear as `droppedAnnotations` in the list/hierarchical output instead.
271
+ **Collected annotations**: annotations from the nodes that passed.
272
+ A failed node reports its annotations as `droppedAnnotations` in the list and hierarchical output instead.
271
273
 
272
274
  ```ruby
273
275
  valid_eval = validator.evaluate({ "name" => "Alice", "age" => 30 })
@@ -278,7 +280,7 @@ valid_eval.annotations
278
280
 
279
281
  ### Canonical JSON serialization
280
282
 
281
- Use `Canonical::JSON.to_string` when you need a stable JSON representation:
283
+ `Canonical::JSON.to_string` serializes equal JSON values to the same string, regardless of key order:
282
284
 
283
285
  ```ruby
284
286
  schema_a = { "type" => "object", "properties" => { "b" => { "type" => "integer" }, "a" => { "type" => "string" } } }
@@ -290,13 +292,13 @@ dump_b = JSONSchema::Canonical::JSON.to_string(schema_b)
290
292
  dump_a == dump_b # => true
291
293
  ```
292
294
 
293
- Main use case: deduplicating equivalent JSON Schemas.
295
+ Use it to deduplicate schemas that differ only in key order.
294
296
 
295
297
  ## Schema Canonicalization
296
298
 
297
299
  > **Experimental**: the canonicalization API may change in minor releases.
298
300
 
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`:
301
+ `JSONSchema.canonicalize` reduces a schema to a normal form that accepts the same values. Schemas that accept the same values reduce to equal `CanonicalSchema` objects, and a schema proven to accept nothing reduces to `false`:
300
302
 
301
303
  ```ruby
302
304
  canonical = JSONSchema.canonicalize(
@@ -315,7 +317,9 @@ JSONSchema.canonicalize({ "type" => "integer", "minimum" => 10, "maximum" => 5 }
315
317
  # => :no, which is JSONSchema::Canonical::Satisfiability::NO
316
318
  ```
317
319
 
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:
320
+ A schema the canonical form cannot model exactly comes back unchanged, with `kind == :raw`. Its `view.reason` names what stopped the run, and `view.pointer` the subschema at fault when a single one is.
321
+
322
+ Canonical schemas combine like sets of values. Every emitted schema carries `$schema`; the comments below leave it out:
319
323
 
320
324
  ```ruby
321
325
  positive = JSONSchema.canonicalize({ "type" => "integer", "minimum" => 0 })
@@ -333,19 +337,19 @@ positive.union(bounded).to_json_schema
333
337
  positive.subtract(bounded).to_json_schema
334
338
  # => {"type"=>"integer", "minimum"=>101}
335
339
 
336
- # Every value `positive` rejects, across the types it never admitted
340
+ # Every value `positive` rejects: other types, negative integers and non-integer numbers
337
341
  positive.negate.to_json_schema
338
342
  # => {"anyOf"=>[{"type"=>["null", "boolean", "string", "array", "object"]},
339
343
  # {"type"=>"integer", "maximum"=>-1},
340
344
  # {"type"=>"number", "not"=>{"multipleOf"=>1}}]}
341
345
 
342
- positive.covers(bounded) # => :no - `bounded` takes negative integers, `positive` does not
346
+ positive.covers(bounded) # => :no: `bounded` takes negative integers, `positive` does not
343
347
  positive.satisfiability # => :yes
344
348
  ```
345
349
 
346
350
  ### Comparing two versions of a schema
347
351
 
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.
352
+ `subtract` tells you what an edit did to a schema. `old.subtract(new)` accepts exactly the values `old` accepts and `new` rejects, so it accepts nothing when the edit lost nothing.
349
353
 
350
354
  ```ruby
351
355
  old = JSONSchema.canonicalize({ "type" => "string" })
@@ -361,19 +365,23 @@ new.subtract(old).satisfiability
361
365
  # => :no
362
366
  ```
363
367
 
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.
368
+ The direction to check depends on who sends the value:
365
369
 
366
- `:no` on the difference proves nothing was lost. `:unknown` proves nothing either way.
370
+ - For a request schema, check `old.subtract(new)`. It accepts the payloads existing callers send that the new schema rejects.
371
+ - For a response schema, check `new.subtract(old)`. It accepts the values the new schema lets a server return that callers never agreed to read.
367
372
 
368
- `:unknown` is undecided, not negative, so the two questions have opposite safe tests: only `satisfiability == :no` proves a schema admits nothing, and only `covers == :yes` proves containment.
373
+ `:no` on the difference proves the edit safe in that direction. `:unknown` means the canonicalizer could not decide, and proves nothing either way. Read it as the answer that keeps you safe:
374
+
375
+ - `satisfiability`: only `:no` proves a schema accepts nothing. Treat `:unknown` like `:yes`.
376
+ - `a.covers(b)`: only `:yes` proves `a` accepts every value `b` accepts. Treat `:unknown` like `:no`.
369
377
 
370
378
  `JSONSchema::Canonical::Containment`, `Satisfiability`, `Distinctness` and `Kind` hold these symbols as constants, each with an `ALL` list.
371
379
 
372
- 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`.
380
+ The set operations raise `IncompatibleOperands` when the operands differ in draft, `format` assertion or regular-expression engine, or resolve `#` or one external resource to different schemas. They raise `UnsupportedOperand` when an operand is `:raw`, and `UnsupportedResult` when the canonical form cannot express the result exactly. All three live under `JSONSchema::Canonical`.
373
381
 
374
382
  ### Finding the dead subschemas of a document
375
383
 
376
- `JSONSchema::Canonical.find_unsatisfiable` walks a whole document and answers which of its subschemas admit no value, and why - the keywords at fault and where they sit:
384
+ `JSONSchema::Canonical.find_unsatisfiable` walks a whole document and reports each subschema that accepts no value, with the keywords at fault and their pointers:
377
385
 
378
386
  ```ruby
379
387
  reasons = JSONSchema::Canonical.find_unsatisfiable(
@@ -396,11 +404,11 @@ reasons.key?("/properties/name")
396
404
  # => false
397
405
  ```
398
406
 
399
- A reason is a `LiteralReason` (written as `false`), an `EmptyReason` (one part admits nothing by itself) or a `ConflictReason` (each part admits values, together they admit none). A pointer left out is not proven satisfiable: a document canonicalization cannot model reports nothing, as `satisfiability` answers `:unknown`.
407
+ A reason is a `LiteralReason` (written as `false`), an `EmptyReason` (one part admits nothing by itself) or a `ConflictReason` (each part admits values, together they admit none). A missing pointer does not prove that subschema satisfiable. For a document the canonical form cannot model, `find_unsatisfiable` reports nothing, the same way `satisfiability` answers `:unknown`.
400
408
 
401
409
  ## Schema Bundling and Dereferencing
402
410
 
403
- 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.
411
+ 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 bundle accepts the same values as the original.
404
412
 
405
413
  ```ruby
406
414
  address_schema = {
@@ -430,7 +438,7 @@ dereferenced = JSONSchema.dereference(schema, registry: registry)
430
438
 
431
439
  ## Meta-Schema Validation
432
440
 
433
- Validate that a JSON Schema document is itself valid:
441
+ `JSONSchema::Meta` checks a schema against the meta-schema of its draft:
434
442
 
435
443
  ```ruby
436
444
  JSONSchema::Meta.valid?({ "type" => "string" }) # => true
@@ -443,9 +451,24 @@ rescue JSONSchema::ValidationError => e
443
451
  end
444
452
  ```
445
453
 
454
+ For a custom metaschema, register it and point `$schema` at its URI:
455
+
456
+ ```ruby
457
+ metaschema = {
458
+ "$schema" => "https://json-schema.org/draft/2020-12/schema",
459
+ "$id" => "https://example.com/meta",
460
+ "type" => "object",
461
+ "required" => ["title"]
462
+ }
463
+ meta_registry = JSONSchema::Registry.new([["https://example.com/meta", metaschema]])
464
+
465
+ JSONSchema::Meta.valid?({ "$schema" => "https://example.com/meta", "title" => "Person" }, registry: meta_registry) # => true
466
+ JSONSchema::Meta.valid?({ "$schema" => "https://example.com/meta" }, registry: meta_registry) # => false
467
+ ```
468
+
446
469
  ## External References
447
470
 
448
- By default, `jsonschema` resolves HTTP references and file references from the local file system. You can implement a custom retriever to handle external references:
471
+ By default, `jsonschema_rs` fetches external `$ref` targets over HTTP and from the local file system. Pass a `retriever:` to load them yourself:
449
472
 
450
473
  ```ruby
451
474
  schemas = {
@@ -468,9 +491,21 @@ validator.valid?({ "name" => "Alice", "age" => 30 }) # => true
468
491
  validator.valid?({ "name" => "Bob" }) # => false (missing "age")
469
492
  ```
470
493
 
494
+ For schemas from untrusted sources, pass `offline: true`. The validator then refuses to fetch any `$ref` target, so a schema cannot reach your network or file system. Schemas held in a `Registry` still resolve:
495
+
496
+ ```ruby
497
+ begin
498
+ JSONSchema.validator_for({ "$ref" => "https://example.com/other.json" }, offline: true)
499
+ rescue JSONSchema::ReferencingError => e
500
+ e.message # => "Resource 'https://example.com/other.json' is not present in a registry ..."
501
+ end
502
+ ```
503
+
504
+ `bundle` and `dereference` take `offline:` too.
505
+
471
506
  ## Schema Registry
472
507
 
473
- For applications that frequently use the same schemas, create a registry to store and reference them:
508
+ A `Registry` holds schemas by URI, so a validator resolves `$ref`s to them without fetching anything:
474
509
 
475
510
  ```ruby
476
511
  registry = JSONSchema::Registry.new([
@@ -501,7 +536,7 @@ validator.valid?({
501
536
  }) # => true
502
537
  ```
503
538
 
504
- The registry also accepts `draft:` and `retriever:` options:
539
+ `Registry` also takes a default `draft:` and a `retriever:` for URIs it does not hold:
505
540
 
506
541
  ```ruby
507
542
  registry = JSONSchema::Registry.new(
@@ -513,7 +548,7 @@ registry = JSONSchema::Registry.new(
513
548
 
514
549
  ## Regular Expression Configuration
515
550
 
516
- When validating schemas with regex patterns (in `pattern` or `patternProperties`), you can configure the underlying regex engine:
551
+ `pattern_options:` picks the regex engine for `pattern` and `patternProperties` and sets its limits:
517
552
 
518
553
  ```ruby
519
554
  # Default fancy-regex engine with backtracking limits
@@ -540,24 +575,22 @@ validator = JSONSchema.validator_for(
540
575
  )
541
576
  ```
542
577
 
543
- The available options:
544
-
545
- - `FancyRegexOptions`: Default engine with lookaround and backreferences support
578
+ - `FancyRegexOptions`: default engine, supports lookaround and backreferences
546
579
 
547
580
  - `backtrack_limit`: Maximum backtracking steps
548
581
  - `size_limit`: Maximum compiled regex size in bytes
549
582
  - `dfa_size_limit`: Maximum DFA cache size in bytes
550
583
 
551
- - `RegexOptions`: Safer engine with linear-time guarantee
584
+ - `RegexOptions`: matches in linear time, no lookaround or backreferences
552
585
 
553
586
  - `size_limit`: Maximum compiled regex size in bytes
554
587
  - `dfa_size_limit`: Maximum DFA cache size in bytes
555
588
 
556
- This configuration is crucial when working with untrusted schemas where attackers might craft malicious regex patterns.
589
+ If you validate against schemas from untrusted sources, use `RegexOptions`: a crafted pattern cannot make it backtrack.
557
590
 
558
591
  ## Email Format Configuration
559
592
 
560
- When validating email addresses using `{"format": "email"}`, you can customize the validation behavior:
593
+ `email_options:` makes `{"format": "email"}` stricter or looser than the spec default:
561
594
 
562
595
  ```ruby
563
596
  # Require a top-level domain (reject "user@localhost")
@@ -587,16 +620,14 @@ validator = JSONSchema.validator_for(
587
620
  )
588
621
  ```
589
622
 
590
- Available options:
591
-
592
- - `require_tld`: Require a top-level domain (e.g., reject "user@localhost")
623
+ - `require_tld`: Require a top-level domain (e.g., reject "user@localhost") (default: false)
593
624
  - `allow_domain_literal`: Allow IP address literals like "user@[127.0.0.1]" (default: true)
594
625
  - `allow_display_text`: Allow display names like "Name <user@example.com>" (default: true)
595
626
  - `minimum_sub_domains`: Minimum number of domain segments required
596
627
 
597
628
  ## Error Handling
598
629
 
599
- `jsonschema` provides detailed validation errors through the `ValidationError` class:
630
+ A `ValidationError` carries the message, both locations and a `kind` with keyword-specific details:
600
631
 
601
632
  ```ruby
602
633
  schema = { "type" => "string", "maxLength" => 5 }
@@ -619,7 +650,7 @@ end
619
650
 
620
651
  ### Error Kind Properties
621
652
 
622
- Each error has a `kind` property with convenient accessors:
653
+ `kind` has generic accessors:
623
654
 
624
655
  ```ruby
625
656
  JSONSchema.each_error({ "minimum" => 5 }, 3).each do |error|
@@ -632,7 +663,7 @@ end
632
663
 
633
664
  ### Error Message Masking
634
665
 
635
- When working with sensitive data, you can mask instance values in error messages:
666
+ Pass `mask:` to replace instance values in error messages with a placeholder:
636
667
 
637
668
  ```ruby
638
669
  schema = {
@@ -657,19 +688,19 @@ end
657
688
 
658
689
  ### Exception Classes
659
690
 
660
- - **`JSONSchema::ValidationError`** - raised on validation failure
691
+ - **`JSONSchema::ValidationError`**: raised on validation failure
661
692
  - `message`, `verbose_message`, `instance_path`, `schema_path`, `evaluation_path`, `kind`, `instance`
662
693
  - JSON Pointer helpers: `instance_path_pointer`, `schema_path_pointer`, `evaluation_path_pointer`
663
- - **`JSONSchema::ReferencingError`** - raised when `$ref` cannot be resolved
694
+ - **`JSONSchema::ReferencingError`**: raised when a `$ref` cannot be resolved
664
695
 
665
696
  ## Options Reference
666
697
 
667
- One-off validation methods (`valid?`, `validate!`, `each_error`, `evaluate`) accept these keyword arguments:
698
+ The one-off methods `valid?`, `validate!` and `each_error` accept these keyword arguments:
668
699
 
669
700
  ```ruby
670
701
  JSONSchema.valid?(schema, instance,
671
702
  draft: :draft7, # Specific draft version (symbol)
672
- validate_formats: true, # Enable format validation (default: false)
703
+ validate_formats: true, # Check `format` (default: on up to Draft 7, off for 2019-09 and 2020-12)
673
704
  ignore_unknown_formats: true, # Don't error on unknown formats (default: true)
674
705
  base_uri: "https://example.com", # Base URI for reference resolution
675
706
  mask: "[REDACTED]", # Mask sensitive data in error messages
@@ -680,25 +711,26 @@ JSONSchema.valid?(schema, instance,
680
711
  vocabularies: ["https://..."], # Vocabularies implemented by custom keywords
681
712
  pattern_options: opts, # RegexOptions or FancyRegexOptions
682
713
  email_options: opts, # EmailOptions
683
- http_options: opts # HttpOptions
714
+ http_options: opts, # HttpOptions
715
+ offline: false # true refuses to fetch $refs; conflicts with retriever:
684
716
  )
685
717
  ```
686
718
 
687
719
  `evaluate` accepts the same options except `mask` (currently unsupported for evaluation output).
688
720
 
689
- `validator_for` accepts the same options except `draft:` — use draft-specific validators (`Draft7Validator.new`, etc.) to pin a draft version.
721
+ `validator_for` accepts the same options except `draft:`. To pin a draft, use a draft-specific class such as `Draft7Validator.new`.
690
722
 
691
723
  Valid draft symbols: `:draft4`, `:draft6`, `:draft7`, `:draft201909`, `:draft202012`.
692
724
 
693
725
  ## Performance
694
726
 
695
- `jsonschema` is designed for high performance, outperforming other Ruby JSON Schema validators in most scenarios:
727
+ Compared with other Ruby validators:
696
728
 
697
729
  - **28-148x** faster than `json_schemer` for complex schemas and large instances
698
730
  - **200-567x** faster than `json-schema` where supported
699
731
  - **7-130x** faster than `rj_schema` (RapidJSON/C++)
700
732
 
701
- For detailed benchmarks, see our [full performance comparison](https://github.com/Stranger6667/jsonschema/blob/master/crates/jsonschema-rb/BENCHMARKS.md).
733
+ Full results and methodology are in [BENCHMARKS.md](https://github.com/Stranger6667/jsonschema/blob/master/crates/jsonschema-rb/BENCHMARKS.md).
702
734
 
703
735
  ### Compile-Time Validators
704
736
 
@@ -714,15 +746,15 @@ A complete extension with its build and test commands lives in
714
746
 
715
747
  ## Acknowledgements
716
748
 
717
- This library draws API design inspiration from the Python [`jsonschema`](https://github.com/python-jsonschema/jsonschema) package. We're grateful to the Python `jsonschema` maintainers and contributors for their pioneering work in JSON Schema validation.
749
+ The API design draws on the Python [`jsonschema`](https://github.com/python-jsonschema/jsonschema) package. Thanks to its maintainers and contributors.
718
750
 
719
751
  ## Support
720
752
 
721
- If you have questions, need help, or want to suggest improvements, please use [GitHub Discussions](https://github.com/Stranger6667/jsonschema/discussions).
753
+ Ask questions and suggest improvements in [GitHub Discussions](https://github.com/Stranger6667/jsonschema/discussions).
722
754
 
723
755
  ## Sponsorship
724
756
 
725
- If you find `jsonschema` useful, please consider [sponsoring its development](https://github.com/sponsors/Stranger6667).
757
+ If you find `jsonschema_rs` useful, please consider [sponsoring its development](https://github.com/sponsors/Stranger6667).
726
758
 
727
759
  ## Contributing
728
760
 
Binary file
Binary file
Binary file
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSONSchema
4
- VERSION = "0.58.4"
4
+ VERSION = "0.58.5"
5
5
  end
data/sig/jsonschema.rbs CHANGED
@@ -391,7 +391,8 @@ module JSONSchema
391
391
  ?registry: Registry?,
392
392
  ?pattern_options: (RegexOptions | FancyRegexOptions)?,
393
393
  ?email_options: EmailOptions?,
394
- ?http_options: HttpOptions?
394
+ ?http_options: HttpOptions?,
395
+ ?offline: bool?
395
396
  ) -> Validator
396
397
 
397
398
  # Create a map of validators for all sub-schemas in a JSON Schema.
@@ -408,7 +409,8 @@ module JSONSchema
408
409
  ?keywords: ::Hash[::String, untyped]?,
409
410
  ?pattern_options: (RegexOptions | FancyRegexOptions)?,
410
411
  ?email_options: EmailOptions?,
411
- ?http_options: HttpOptions?
412
+ ?http_options: HttpOptions?,
413
+ ?offline: bool?
412
414
  ) -> ValidatorMap
413
415
 
414
416
  # Bundle a JSON Schema into a Compound Schema Document.
@@ -421,7 +423,8 @@ module JSONSchema
421
423
  ?draft: draft?,
422
424
  ?retriever: (^(String) -> untyped)?,
423
425
  ?registry: Registry?,
424
- ?base_uri: String?
426
+ ?base_uri: String?,
427
+ ?offline: bool?
425
428
  ) -> Hash[String, untyped]
426
429
 
427
430
  # Dereference a JSON Schema by recursively replacing all $ref values
@@ -431,7 +434,8 @@ module JSONSchema
431
434
  ?draft: draft?,
432
435
  ?retriever: (^(String) -> untyped)?,
433
436
  ?registry: Registry?,
434
- ?base_uri: String?
437
+ ?base_uri: String?,
438
+ ?offline: bool?
435
439
  ) -> untyped
436
440
 
437
441
  # Detect the JSON Schema draft for a schema and return the corresponding validator class.
@@ -454,7 +458,8 @@ module JSONSchema
454
458
  ?registry: Registry?,
455
459
  ?pattern_options: (RegexOptions | FancyRegexOptions)?,
456
460
  ?email_options: EmailOptions?,
457
- ?http_options: HttpOptions?
461
+ ?http_options: HttpOptions?,
462
+ ?offline: bool?
458
463
  ) -> bool
459
464
 
460
465
  # One-off validation raising on error.
@@ -473,7 +478,8 @@ module JSONSchema
473
478
  ?registry: Registry?,
474
479
  ?pattern_options: (RegexOptions | FancyRegexOptions)?,
475
480
  ?email_options: EmailOptions?,
476
- ?http_options: HttpOptions?
481
+ ?http_options: HttpOptions?,
482
+ ?offline: bool?
477
483
  ) -> nil
478
484
 
479
485
  # Iterate validation errors. Returns Array when no block given, nil when block given.
@@ -492,7 +498,8 @@ module JSONSchema
492
498
  ?registry: Registry?,
493
499
  ?pattern_options: (RegexOptions | FancyRegexOptions)?,
494
500
  ?email_options: EmailOptions?,
495
- ?http_options: HttpOptions?
501
+ ?http_options: HttpOptions?,
502
+ ?offline: bool?
496
503
  ) -> Array[ValidationError]
497
504
  | (
498
505
  untyped schema,
@@ -509,7 +516,8 @@ module JSONSchema
509
516
  ?registry: Registry?,
510
517
  ?pattern_options: (RegexOptions | FancyRegexOptions)?,
511
518
  ?email_options: EmailOptions?,
512
- ?http_options: HttpOptions?
519
+ ?http_options: HttpOptions?,
520
+ ?offline: bool?
513
521
  ) { (ValidationError) -> void } -> nil
514
522
 
515
523
  # One-off evaluation returning structured output.
@@ -527,7 +535,8 @@ module JSONSchema
527
535
  ?registry: Registry?,
528
536
  ?pattern_options: (RegexOptions | FancyRegexOptions)?,
529
537
  ?email_options: EmailOptions?,
530
- ?http_options: HttpOptions?
538
+ ?http_options: HttpOptions?,
539
+ ?offline: bool?
531
540
  ) -> Evaluation
532
541
 
533
542
  # Reusable JSON Schema validator.
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.58.4
4
+ version: 0.58.5
5
5
  platform: x86_64-linux
6
6
  authors:
7
7
  - Dmitry Dygalo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-10-01 00:00:00.000000000 Z
11
+ date: 2026-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bigdecimal
@@ -56,7 +56,7 @@ metadata:
56
56
  homepage_uri: https://github.com/Stranger6667/jsonschema/tree/master/crates/jsonschema-rb
57
57
  source_code_uri: https://github.com/Stranger6667/jsonschema
58
58
  changelog_uri: https://github.com/Stranger6667/jsonschema/blob/master/crates/jsonschema-rb/CHANGELOG.md
59
- documentation_uri: https://github.com/Stranger6667/jsonschema/tree/master/crates/jsonschema-rb#readme
59
+ documentation_uri: https://github.com/Stranger6667/jsonschema/blob/ruby-v0.58.5/crates/jsonschema-rb/README.md
60
60
  bug_tracker_uri: https://github.com/Stranger6667/jsonschema/issues
61
61
  funding_uri: https://github.com/sponsors/Stranger6667
62
62
  rubygems_mfa_required: 'true'