jsonschema_rs 0.51.0 → 0.52.0

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: 7cc0c8312d2b960d018cd1a8eda7e8db2ae74eee48bfd4328e3040e479db2a9d
4
- data.tar.gz: 9149b6d196c3c7ca1b27ed2d12c433b2cdcc46ab1f665aea3e04e3186e901ede
3
+ metadata.gz: 60286fc7bf517866e7429a90e42fa4505ea769ba9728c1d03fcd1dafe2ff63ce
4
+ data.tar.gz: 6aaea36a12a38414cac3ec8af674b2b944cfd451dcf682488525f62fe12ee98e
5
5
  SHA512:
6
- metadata.gz: c380d68065992826531bf42fa03d9a200fdf20cd2a43e5fd8f35212cdad2d88a4e4b3e67f806171c1a7dd6cc3b78eff2f2af19276ccb1bec91d6f0c658587e73
7
- data.tar.gz: 4f73fb65388571245b79a05cba80b74be5dafd2ef70073310aacbcbb76ce63dbe71abd5e6f90140752dffca4b32d0693723b7e94dc88c9371d168b734bfee6aa
6
+ metadata.gz: bb0c6f0d5db65db03bc05d11cd636d8fc37b9b61a33b3674da032de2ec1a31df43f595bc9c16964bace627362a699fb032e0d90f459d81a0f68222eb6e251f5d
7
+ data.tar.gz: 03a44cfe94869f6ccf039205ee42eedddf84cd11005b44f3d0b9db75efdaf2c63166a82d71332fc65e03cb41a959355737bbff7a9750c99a50ec061d0112ef1e
data/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.52.0] - 2026-08-27
6
+
7
+ ### Added
8
+
9
+ - The `offline:` keyword argument, refusing to fetch references outside `registry:`.
10
+
11
+ ### Fixed
12
+
13
+ - Canonicalization not idempotent where a `patternProperties` `$ref` matches a key `properties` names.
14
+ - The `draft:` keyword argument and the `Draft201909Validator` / `Draft202012Validator` classes gating keywords on the vocabularies of the `$schema` they override, so the validator accepted every instance.
15
+ - `valid?` disagreeing with `validate!`, `each_error`, and `evaluate` on a schema that reaches its own `$ref` twice, one of them under `not`.
16
+
5
17
  ## [0.51.0] - 2026-08-23
6
18
 
7
19
  ### Added
@@ -467,7 +479,8 @@
467
479
 
468
480
  - Initial public release
469
481
 
470
- [Unreleased]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.51.0...HEAD
482
+ [Unreleased]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.52.0...HEAD
483
+ [0.52.0]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.51.0...ruby-v0.52.0
471
484
  [0.51.0]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.50.1...ruby-v0.51.0
472
485
  [0.50.1]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.50.0...ruby-v0.50.1
473
486
  [0.50.0]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.9...ruby-v0.50.0
data/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "jsonschema-rb"
3
- version = "0.51.0"
3
+ version = "0.52.0"
4
4
  edition = "2021"
5
5
  authors = ["Dmitry Dygalo <dmitry@dygalo.dev>"]
6
6
  license = "MIT"
@@ -14,7 +14,7 @@ crate-type = ["cdylib"]
14
14
 
15
15
  [dependencies]
16
16
  strum = "0.28.0"
17
- jsonschema = { version = "0.51.0", default-features = false, features = ["magnus", "arbitrary-precision", "resolve-http", "resolve-file", "tls-ring", "macros"] }
17
+ jsonschema = { version = "0.52.0", default-features = false, features = ["magnus", "arbitrary-precision", "resolve-http", "resolve-file", "tls-ring", "macros", "idna"] }
18
18
  magnus = { version = "0.8", features = ["rb-sys"] }
19
19
  rb-sys = "0.9"
20
20
  serde = { workspace = true }
data/README.md CHANGED
@@ -49,7 +49,7 @@ end
49
49
  - 🌐 Remote reference fetching (network/file)
50
50
  - 🔧 Custom keywords and format validators
51
51
  - ✨ Meta-schema validation for schema documents
52
- - 📦 Schema bundling into Compound Schema Documents
52
+ - 📦 Schema bundling into Compound Schema Documents, and `$ref` dereferencing
53
53
  - 🧮 Experimental schema canonicalization
54
54
  - ♦️ Supports Ruby 3.2, 3.4 and 4.0
55
55
 
@@ -371,7 +371,7 @@ Compare a request schema new-against-old and a response schema old-against-new:
371
371
 
372
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`.
373
373
 
374
- ## Schema Bundling
374
+ ## Schema Bundling and Dereferencing
375
375
 
376
376
  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.
377
377
 
@@ -395,6 +395,12 @@ registry = JSONSchema::Registry.new([["https://example.com/address.json", addres
395
395
  bundled = JSONSchema.bundle(schema, registry: registry)
396
396
  ```
397
397
 
398
+ `dereference` instead replaces each `$ref` with the schema it points to, for consumers that do not resolve references. Circular references are left in place.
399
+
400
+ ```ruby
401
+ dereferenced = JSONSchema.dereference(schema, registry: registry)
402
+ ```
403
+
398
404
  ## Meta-Schema Validation
399
405
 
400
406
  Validate that a JSON Schema document is itself valid:
@@ -269,9 +269,9 @@ dependencies = [
269
269
 
270
270
  [[package]]
271
271
  name = "fraction"
272
- version = "0.16.0"
272
+ version = "0.17.0"
273
273
  source = "registry+https://github.com/rust-lang/crates.io-index"
274
- checksum = "33fee0259ffdc3d7bd64438b6b08437884d4df5700f9cb8a23b079c3958ae578"
274
+ checksum = "e246562084dde8ebbcc943b261c406ce4f68e5032ec28029a251a47d6a295500"
275
275
  dependencies = [
276
276
  "num",
277
277
  "num-bigint",
@@ -693,9 +693,9 @@ dependencies = [
693
693
 
694
694
  [[package]]
695
695
  name = "jsonschema"
696
- version = "0.51.0"
696
+ version = "0.52.0"
697
697
  source = "registry+https://github.com/rust-lang/crates.io-index"
698
- checksum = "152999731bfbe0bb82d561550be73b0c31a9827d6ebe3fe96ad47563703b5328"
698
+ checksum = "0ee5867390f14ee43278d8d05d3af5f5314eeccb4684e6049033f2ba4ae3d4ae"
699
699
  dependencies = [
700
700
  "ahash",
701
701
  "bytecount",
@@ -726,9 +726,9 @@ dependencies = [
726
726
 
727
727
  [[package]]
728
728
  name = "jsonschema-macros"
729
- version = "0.51.0"
729
+ version = "0.52.0"
730
730
  source = "registry+https://github.com/rust-lang/crates.io-index"
731
- checksum = "b2b1d072fffb43f056f6749cfe86d5fd5853cd0b8b139a05a83f616549b9a98d"
731
+ checksum = "31552147ec28242b841ab069f8ba32b2548d2a3ff7c47b0085078c5bc84c49de"
732
732
  dependencies = [
733
733
  "jsonschema-macros-core",
734
734
  "proc-macro2",
@@ -736,9 +736,9 @@ dependencies = [
736
736
 
737
737
  [[package]]
738
738
  name = "jsonschema-macros-core"
739
- version = "0.51.0"
739
+ version = "0.52.0"
740
740
  source = "registry+https://github.com/rust-lang/crates.io-index"
741
- checksum = "9a710eb535fcbe18373b29254c6a9ca65de465c4228c04c3fdc7600d7b099651"
741
+ checksum = "fbdfa029e60c8f29b8069de429929f33b0da3109ad95f8428728a68bb6f2c0fc"
742
742
  dependencies = [
743
743
  "fancy-regex",
744
744
  "indexmap",
@@ -755,7 +755,7 @@ dependencies = [
755
755
 
756
756
  [[package]]
757
757
  name = "jsonschema-rb-ext"
758
- version = "0.51.0"
758
+ version = "0.52.0"
759
759
  dependencies = [
760
760
  "jsonschema",
761
761
  "magnus",
@@ -769,18 +769,18 @@ dependencies = [
769
769
 
770
770
  [[package]]
771
771
  name = "jsonschema-regex"
772
- version = "0.51.0"
772
+ version = "0.52.0"
773
773
  source = "registry+https://github.com/rust-lang/crates.io-index"
774
- checksum = "8cb2e614e1c610e31e947d53156e877340c718e053cfce0dfe9b9ce7beff4d31"
774
+ checksum = "1a7bbc0f53dcb425cf3bae539be26b406b7053e6995e34e4b04477091e600044"
775
775
  dependencies = [
776
776
  "regex-syntax",
777
777
  ]
778
778
 
779
779
  [[package]]
780
780
  name = "jsonschema-value"
781
- version = "0.51.0"
781
+ version = "0.52.0"
782
782
  source = "registry+https://github.com/rust-lang/crates.io-index"
783
- checksum = "24373bc85409cb935a46af0ffb41294c5372c08cf9b0709913d908154cd10582"
783
+ checksum = "0d3e24abcd5f7eff512eb6bb915ac67772f2e7142ae5b5ac67b4ac75bd417d46"
784
784
  dependencies = [
785
785
  "ahash",
786
786
  "bytecount",
@@ -1133,9 +1133,9 @@ dependencies = [
1133
1133
 
1134
1134
  [[package]]
1135
1135
  name = "referencing"
1136
- version = "0.51.0"
1136
+ version = "0.52.0"
1137
1137
  source = "registry+https://github.com/rust-lang/crates.io-index"
1138
- checksum = "0aff997fc7eecb671a947b0f73f5ce4bcb4ad3534fd5bff2dd752718a8107525"
1138
+ checksum = "b6326ce79629af4702ac033666390011ccc70fe82ffedd62824d061f133bd10b"
1139
1139
  dependencies = [
1140
1140
  "ahash",
1141
1141
  "fluent-uri",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "jsonschema-rb-ext"
3
- version = "0.51.0"
3
+ version = "0.52.0"
4
4
  edition = "2021"
5
5
  publish = false
6
6
 
@@ -10,10 +10,10 @@ name = "jsonschema_rb"
10
10
  path = "../../src/lib.rs"
11
11
 
12
12
  [dependencies]
13
- jsonschema = { version = "0.51.0", default-features = false, features = ["magnus", "arbitrary-precision", "resolve-http", "resolve-file", "tls-ring", "macros"] }
13
+ jsonschema = { version = "0.52.0", default-features = false, features = ["magnus", "arbitrary-precision", "resolve-http", "resolve-file", "tls-ring", "macros", "idna"] }
14
14
  magnus = { version = "0.8", features = ["rb-sys"] }
15
15
  rb-sys = "0.9"
16
- referencing = "0.51.0"
16
+ referencing = "0.52.0"
17
17
  serde = { version = "1", features = ["derive"] }
18
18
  serde_json = { version = "1", features = ["arbitrary_precision"] }
19
19
  strum = "0.28.0"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSONSchema
4
- VERSION = "0.51.0"
4
+ VERSION = "0.52.0"
5
5
  end
data/src/evaluation.rs CHANGED
@@ -26,7 +26,7 @@ impl Evaluation {
26
26
  }
27
27
 
28
28
  fn is_valid(&self) -> bool {
29
- self.inner.flag().valid
29
+ self.inner.is_valid()
30
30
  }
31
31
 
32
32
  /// Simplest output format — only a "valid" key.
@@ -95,10 +95,7 @@ impl Evaluation {
95
95
  }
96
96
 
97
97
  fn inspect(&self) -> String {
98
- format!(
99
- "#<JSONSchema::Evaluation valid={}>",
100
- self.inner.flag().valid
101
- )
98
+ format!("#<JSONSchema::Evaluation valid={}>", self.inner.is_valid())
102
99
  }
103
100
  }
104
101
 
data/src/lib.rs CHANGED
@@ -204,6 +204,7 @@ fn build_parsed_options(
204
204
  kw.pattern_options,
205
205
  kw.email_options,
206
206
  kw.http_options,
207
+ kw.offline,
207
208
  )
208
209
  }
209
210
 
data/src/options.rs CHANGED
@@ -37,6 +37,7 @@ define_rb_intern!(static KW_KEYWORDS: "keywords");
37
37
  define_rb_intern!(pub(crate) static KW_REGISTRY: "registry");
38
38
  // Extra kwarg names (extracted before get_kwargs)
39
39
  define_rb_intern!(static KW_VOCABULARIES: "vocabularies");
40
+ define_rb_intern!(static KW_OFFLINE: "offline");
40
41
  define_rb_intern!(static KW_PATTERN_OPTIONS: "pattern_options");
41
42
  define_rb_intern!(static KW_EMAIL_OPTIONS: "email_options");
42
43
  define_rb_intern!(static KW_HTTP_OPTIONS: "http_options");
@@ -229,6 +230,7 @@ pub struct ExtractedKwargs {
229
230
  pub pattern_options: Option<Value>,
230
231
  pub email_options: Option<Value>,
231
232
  pub http_options: Option<Value>,
233
+ pub offline: Option<bool>,
232
234
  }
233
235
 
234
236
  pub fn extract_kwargs(_ruby: &Ruby, kw: RHash) -> Result<ExtractedKwargs, Error> {
@@ -236,6 +238,7 @@ pub fn extract_kwargs(_ruby: &Ruby, kw: RHash) -> Result<ExtractedKwargs, Error>
236
238
  let pattern_options = extract_and_delete(&kw, *KW_PATTERN_OPTIONS)?;
237
239
  let email_options = extract_and_delete(&kw, *KW_EMAIL_OPTIONS)?;
238
240
  let http_options = extract_and_delete(&kw, *KW_HTTP_OPTIONS)?;
241
+ let offline = extract_offline(&kw)?;
239
242
 
240
243
  let ids = base_option_ids();
241
244
  let base_kw: KwArgs<(), BaseKwargs, ()> = get_kwargs(kw, &[], &ids)?;
@@ -246,6 +249,7 @@ pub fn extract_kwargs(_ruby: &Ruby, kw: RHash) -> Result<ExtractedKwargs, Error>
246
249
  pattern_options,
247
250
  email_options,
248
251
  http_options,
252
+ offline,
249
253
  })
250
254
  }
251
255
 
@@ -254,6 +258,7 @@ pub fn extract_evaluate_kwargs(_ruby: &Ruby, kw: RHash) -> Result<ExtractedKwarg
254
258
  let pattern_options = extract_and_delete(&kw, *KW_PATTERN_OPTIONS)?;
255
259
  let email_options = extract_and_delete(&kw, *KW_EMAIL_OPTIONS)?;
256
260
  let http_options = extract_and_delete(&kw, *KW_HTTP_OPTIONS)?;
261
+ let offline = extract_offline(&kw)?;
257
262
 
258
263
  let ids = base_option_ids_no_mask();
259
264
  let base_kw: KwArgs<(), BaseKwargsNoMask, ()> = get_kwargs(kw, &[], &ids)?;
@@ -284,6 +289,7 @@ pub fn extract_evaluate_kwargs(_ruby: &Ruby, kw: RHash) -> Result<ExtractedKwarg
284
289
  pattern_options,
285
290
  email_options,
286
291
  http_options,
292
+ offline,
287
293
  })
288
294
  }
289
295
 
@@ -292,6 +298,7 @@ pub fn extract_kwargs_no_draft(_ruby: &Ruby, kw: RHash) -> Result<ExtractedKwarg
292
298
  let pattern_options = extract_and_delete(&kw, *KW_PATTERN_OPTIONS)?;
293
299
  let email_options = extract_and_delete(&kw, *KW_EMAIL_OPTIONS)?;
294
300
  let http_options = extract_and_delete(&kw, *KW_HTTP_OPTIONS)?;
301
+ let offline = extract_offline(&kw)?;
295
302
 
296
303
  let ids = base_option_ids_no_draft();
297
304
  let base_kw: KwArgs<(), BaseKwargsNoDraft, ()> = get_kwargs(kw, &[], &ids)?;
@@ -322,9 +329,16 @@ pub fn extract_kwargs_no_draft(_ruby: &Ruby, kw: RHash) -> Result<ExtractedKwarg
322
329
  pattern_options,
323
330
  email_options,
324
331
  http_options,
332
+ offline,
325
333
  })
326
334
  }
327
335
 
336
+ fn extract_offline(kw: &RHash) -> Result<Option<bool>, Error> {
337
+ extract_and_delete(kw, *KW_OFFLINE)?
338
+ .map(TryConvert::try_convert)
339
+ .transpose()
340
+ }
341
+
328
342
  fn extract_vocabularies(kw: &RHash) -> Result<Option<Vec<String>>, Error> {
329
343
  extract_and_delete(kw, *KW_VOCABULARIES)?
330
344
  .map(TryConvert::try_convert)
@@ -500,7 +514,15 @@ pub fn make_options_from_kwargs(
500
514
  pattern_options_val: Option<Value>,
501
515
  email_options_val: Option<Value>,
502
516
  http_options_val: Option<Value>,
517
+ offline: Option<bool>,
503
518
  ) -> Result<ParsedOptions<'_>, Error> {
519
+ let offline = offline.unwrap_or(false);
520
+ if offline && retriever_val.is_some() {
521
+ return Err(Error::new(
522
+ ruby.exception_arg_error(),
523
+ "`offline` cannot be used together with `retriever`",
524
+ ));
525
+ }
504
526
  let mut opts = jsonschema::options_for::<Magnus>();
505
527
  let mut registry = None;
506
528
  let mut retriever = None;
@@ -560,7 +582,7 @@ pub fn make_options_from_kwargs(
560
582
  })?;
561
583
  registry = Some(reg.inner.as_ref());
562
584
 
563
- if !retriever_was_provided && retriever.is_none() {
585
+ if !retriever_was_provided && retriever.is_none() && !offline {
564
586
  if let Some(registry_retriever_value) = reg.retriever_value(ruby) {
565
587
  if let Some(ret) = make_retriever(ruby, registry_retriever_value)? {
566
588
  compilation_roots
@@ -822,6 +844,10 @@ pub fn make_options_from_kwargs(
822
844
  .map_err(|e| Error::new(ruby.exception_arg_error(), e.to_string()))?;
823
845
  }
824
846
 
847
+ if offline {
848
+ opts = opts.offline();
849
+ }
850
+
825
851
  Ok(ParsedOptions {
826
852
  mask,
827
853
  options: opts,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonschema_rs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.51.0
4
+ version: 0.52.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Dygalo