schemurai 3.0.2 → 3.1.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: dd0769d236e3a91c31ef4e701b642fbcaf76946cb23a11e0a03c230d0f5982d2
4
- data.tar.gz: 7b05d25b9825801b5b79c7cdacf8c22bcdd3230dc81ef817e6098c140b1d4686
3
+ metadata.gz: 663b805a46f6c7bf28678bcc50b2ffae37d3337b3025710a75c0782a5d7c8182
4
+ data.tar.gz: 41a280754bfa72b41626e44176ef7cf0c983cc27a504aedf049759df005498b1
5
5
  SHA512:
6
- metadata.gz: 76972d14c8f9682d763e640879d6543effa89d53c6eb2e7b91bcf9cad955f5838e69260e5ec08791c27f582db3f7f90d54252d9c6f0c4f8db219a1ebac98ad67
7
- data.tar.gz: fc443ff0789f2f8e3ad95a70f51fc831187da07287c2fafed49cb6fa6999bdb68a1978773de3783b01a217ec39ba482b91ad6cf6d4f4785ac0e13d14a9874731
6
+ metadata.gz: 88be3ae2e41ce4d46cbb5c79dc66e9bfe7d9041d63619b17dc27dc7977384679435df13f0e234701033eca5f829f9d4e7321b9b08ad8e9b6fdfdf0fa5d64c03c
7
+ data.tar.gz: a0ea620a03a983a0ad22319c4a22727c316ced09711bd8565a716d8ebcf4c523bc827e957b347c0b19886d487f7529d305b425f63e1e0ffa4b3b7d8f1822e406
data/README.md CHANGED
@@ -288,9 +288,28 @@ scans use per-item evaluation so successful scans can poll.
288
288
  `Schemurai.backend`, `SchemaRegistry#backend`, and `Validator#backend` expose
289
289
  the selected backend. Pass `backend: :ruby` to force the Ruby oracle or
290
290
  `backend: :vm` to ahead-of-time compile schemas for the validator virtual machine.
291
- Pass `backend: :native` to use the experimental Rust VM extension. Building the
292
- native extension requires a C toolchain, Ruby development headers, and Rust
293
- 1.93 or newer. If cargo is absent, gem installation skips the optional native
291
+ Pass `backend: :native` to use the experimental Rust VM extension. Releases
292
+ include precompiled gems on RubyGems.org for CRuby 4.0 on these platforms:
293
+
294
+ | OS | CPU | libc | Gem platform |
295
+ | --- | --- | --- | --- |
296
+ | Linux | x64 | glibc 2.36+ | `x86_64-linux-gnu` |
297
+ | Linux | arm64 | glibc 2.36+ | `aarch64-linux-gnu` |
298
+ | Linux | x64 | musl (Alpine 3.23+) | `x86_64-linux-musl` |
299
+ | Linux | arm64 | musl (Alpine 3.23+) | `aarch64-linux-musl` |
300
+ | macOS 14+ | x64 | — | `x86_64-darwin` |
301
+ | macOS 14+ | arm64 | — | `arm64-darwin` |
302
+
303
+ RubyGems/Bundler selects the matching platform gem during normal installation;
304
+ these gems need no C compiler, Rust, or Ruby development headers. Each platform
305
+ gem bundles its supported Ruby minor ABIs and restricts `required_ruby_version`
306
+ to that range. Ruby patch releases share the same binary. To build from source,
307
+ use `gem install schemurai --platform ruby` or Bundler's `force_ruby_platform`.
308
+ See [native gem releases](docs/native-gem-releases.md) for the build matrix.
309
+
310
+ Building the native extension from source requires a C toolchain, Ruby
311
+ development headers, and Rust 1.93 or newer. If cargo is absent, installation of
312
+ the source gem skips the optional native
294
313
  extension and Ruby/VM remain available; explicitly selecting `:native` then
295
314
  raises `LoadError`. Native execution borrows Ruby values directly; its current coverage and
296
315
  remaining VM delegation are documented below.
@@ -67,6 +67,16 @@ dependencies = [
67
67
  "num-traits",
68
68
  ]
69
69
 
70
+ [[package]]
71
+ name = "num-bigint"
72
+ version = "0.5.1"
73
+ source = "registry+https://github.com/rust-lang/crates.io-index"
74
+ checksum = "93e7820bc0a80a0238e650327316f929ba18d5be054b647490a3a6a339f3e7c0"
75
+ dependencies = [
76
+ "num-integer",
77
+ "num-traits",
78
+ ]
79
+
70
80
  [[package]]
71
81
  name = "num-integer"
72
82
  version = "0.1.47"
@@ -82,7 +92,7 @@ version = "0.4.2"
82
92
  source = "registry+https://github.com/rust-lang/crates.io-index"
83
93
  checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
84
94
  dependencies = [
85
- "num-bigint",
95
+ "num-bigint 0.4.8",
86
96
  "num-integer",
87
97
  "num-traits",
88
98
  ]
@@ -127,13 +137,14 @@ checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
127
137
 
128
138
  [[package]]
129
139
  name = "schemurai-native"
130
- version = "3.0.2"
140
+ version = "3.1.0"
131
141
  dependencies = [
132
142
  "base64-simd",
133
143
  "base64-turbo",
134
144
  "memchr",
135
- "num-bigint",
145
+ "num-bigint 0.5.1",
136
146
  "num-rational",
147
+ "num-traits",
137
148
  "regex-automata",
138
149
  "regex-syntax",
139
150
  "ryu",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "schemurai-native"
3
- version = "3.0.2"
3
+ version = "3.1.0"
4
4
  edition = "2024"
5
5
  rust-version = "1.93"
6
6
  publish = false
@@ -9,8 +9,9 @@ publish = false
9
9
  base64-simd = "0.8.0"
10
10
  base64-turbo = "0.5.0"
11
11
  memchr = "2.8.3"
12
- num-bigint = "0.4.8"
13
- num-rational = "0.4.2"
12
+ num-bigint = "0.5.1"
13
+ num-rational = { version = "0.4.2", default-features = false, features = ["std"] }
14
+ num-traits = "0.2.19"
14
15
  regex-automata = "0.4.18"
15
16
  regex-syntax = "0.8.11"
16
17
  ryu = "1.0.23"
@@ -2,6 +2,10 @@
2
2
 
3
3
  require "mkmf"
4
4
 
5
+ # Platform gems resolve Ruby symbols from the running interpreter so the same
6
+ # binary also works with Rubies built without a shared libruby.
7
+ $LIBRUBYARG = "" unless enable_config("link-ruby", true) # rubocop:disable Style/GlobalVars -- mkmf build configuration.
8
+
5
9
  unless find_executable("cargo")
6
10
  warn "cargo was not found; skipping the optional native backend (Ruby and VM remain available)"
7
11
  File.write("Makefile", dummy_makefile(".").join)
@@ -713,6 +713,75 @@ impl Execution<'_> {
713
713
  if !self.budget.checkpoint() {
714
714
  return Err(Unsupported);
715
715
  }
716
+ // Container entry policy is shared; child traversal stays specific
717
+ // to each container's paths, assertions and annotation coverage.
718
+ let container = match op {
719
+ Op::Array(required, rules) => {
720
+ Some((*required, &rules.header, rules.header_only(), TYPE_ARRAY))
721
+ }
722
+ Op::Object(required, rules) => {
723
+ Some((*required, &rules.header, rules.header_only(), TYPE_OBJECT))
724
+ }
725
+ _ => None,
726
+ };
727
+ if let Some((required, header, header_only, expected_kind)) = container {
728
+ if self.caches.report_continuations_allowed()
729
+ && !header_only
730
+ && (kind == TYPE_UNSUPPORTED
731
+ || self.caches.dynamic_calls()
732
+ || prior.has_runtime_properties())
733
+ {
734
+ let result = self.caches.container_report(
735
+ node,
736
+ value,
737
+ (source.1, required, expected_kind == TYPE_OBJECT),
738
+ report,
739
+ &prior,
740
+ tracked,
741
+ )?;
742
+ if tracked {
743
+ prior.merge_diagnostics(self, result)?;
744
+ }
745
+ if report.silent && report.failed {
746
+ break;
747
+ }
748
+ continue;
749
+ }
750
+ if header_only && header.runtime_required(self.caches, kind) {
751
+ if report.collect_header(self.caches, header, required, value, source)? {
752
+ break;
753
+ }
754
+ continue;
755
+ }
756
+ if kind == expected_kind && !self.budget.checkpoint() {
757
+ return Err(Unsupported);
758
+ }
759
+ if required != 0 && kind != expected_kind {
760
+ report.add(self.caches, "type", source, value, 0)?;
761
+ }
762
+ if kind != expected_kind {
763
+ continue;
764
+ }
765
+ if report.silent {
766
+ let status = match op {
767
+ Op::Array(_, rules) => {
768
+ self.array_tracked(rules, value, depth + 1, active, &mut prior)
769
+ }
770
+ Op::Object(_, rules) => {
771
+ self.object_tracked(rules, value, depth + 1, active, &mut prior)
772
+ }
773
+ _ => unreachable!("container entry"),
774
+ };
775
+ if status == Unsupported {
776
+ return Err(Unsupported);
777
+ }
778
+ report.failed |= status == Invalid;
779
+ if report.failed {
780
+ break;
781
+ }
782
+ continue;
783
+ }
784
+ }
716
785
  match op {
717
786
  Op::Unsupported => return Err(Unsupported),
718
787
  Op::UnresolvedRef(message) => {
@@ -842,62 +911,7 @@ impl Execution<'_> {
842
911
  }
843
912
  }
844
913
  }
845
- Op::Array(required, rules) => {
846
- if self.caches.report_continuations_allowed()
847
- && !rules.header_only()
848
- && (kind == TYPE_UNSUPPORTED
849
- || self.caches.dynamic_calls()
850
- || prior.has_runtime_properties())
851
- {
852
- let result = self.caches.container_report(
853
- node,
854
- value,
855
- (source.1, *required, false),
856
- report,
857
- &prior,
858
- tracked,
859
- )?;
860
- if tracked {
861
- prior.merge_diagnostics(self, result)?;
862
- }
863
- if report.silent && report.failed {
864
- break;
865
- }
866
- continue;
867
- }
868
- if rules.header_only() && rules.header.runtime_required(self.caches, kind) {
869
- if report.collect_header(
870
- self.caches,
871
- &rules.header,
872
- *required,
873
- value,
874
- source,
875
- )? {
876
- break;
877
- }
878
- continue;
879
- }
880
- if kind == TYPE_ARRAY && !self.budget.checkpoint() {
881
- return Err(Unsupported);
882
- }
883
- if *required != 0 && kind != TYPE_ARRAY {
884
- report.add(self.caches, "type", source, value, 0)?;
885
- }
886
- if kind != TYPE_ARRAY {
887
- continue;
888
- }
889
- if report.silent {
890
- let status =
891
- self.array_tracked(rules, value, depth + 1, active, &mut prior);
892
- if status == Unsupported {
893
- return Err(Unsupported);
894
- }
895
- report.failed |= status == Invalid;
896
- if report.failed {
897
- break;
898
- }
899
- continue;
900
- }
914
+ Op::Array(_, rules) => {
901
915
  let mut coverage = Tracked::new(Valid);
902
916
  let len = unsafe { sn_len(value) };
903
917
  if rules.max.is_some_and(|max| len > max) {
@@ -1168,62 +1182,7 @@ impl Execution<'_> {
1168
1182
  prior.merge_diagnostics(self, coverage)?;
1169
1183
  }
1170
1184
  }
1171
- Op::Object(required, rules) => {
1172
- if self.caches.report_continuations_allowed()
1173
- && !rules.header_only()
1174
- && (kind == TYPE_UNSUPPORTED
1175
- || self.caches.dynamic_calls()
1176
- || prior.has_runtime_properties())
1177
- {
1178
- let result = self.caches.container_report(
1179
- node,
1180
- value,
1181
- (source.1, *required, true),
1182
- report,
1183
- &prior,
1184
- tracked,
1185
- )?;
1186
- if tracked {
1187
- prior.merge_diagnostics(self, result)?;
1188
- }
1189
- if report.silent && report.failed {
1190
- break;
1191
- }
1192
- continue;
1193
- }
1194
- if rules.header_only() && rules.header.runtime_required(self.caches, kind) {
1195
- if report.collect_header(
1196
- self.caches,
1197
- &rules.header,
1198
- *required,
1199
- value,
1200
- source,
1201
- )? {
1202
- break;
1203
- }
1204
- continue;
1205
- }
1206
- if kind == TYPE_OBJECT && !self.budget.checkpoint() {
1207
- return Err(Unsupported);
1208
- }
1209
- if *required != 0 && kind != TYPE_OBJECT {
1210
- report.add(self.caches, "type", source, value, 0)?;
1211
- }
1212
- if kind != TYPE_OBJECT {
1213
- continue;
1214
- }
1215
- if report.silent {
1216
- let status =
1217
- self.object_tracked(rules, value, depth + 1, active, &mut prior);
1218
- if status == Unsupported {
1219
- return Err(Unsupported);
1220
- }
1221
- report.failed |= status == Invalid;
1222
- if report.failed {
1223
- break;
1224
- }
1225
- continue;
1226
- }
1185
+ Op::Object(_, rules) => {
1227
1186
  let mut coverage = Tracked::new(Valid);
1228
1187
  let len = unsafe { sn_len(value) };
1229
1188
  if rules.max.is_some_and(|max| len > max) {
@@ -3,8 +3,28 @@
3
3
  //! method dispatch can invalidate the evaluator's borrowed instance storage.
4
4
  use super::*;
5
5
  use num_bigint::{BigInt, Sign};
6
+ use num_traits::float::FloatCore;
6
7
  use std::borrow::Cow;
7
8
 
9
+ // Use the application's BigInt version rather than num-rational's optional one.
10
+ pub(super) type BigRational = num_rational::Ratio<BigInt>;
11
+
12
+ fn binary_float(value: f64) -> Option<BigRational> {
13
+ if !value.is_finite() {
14
+ return None;
15
+ }
16
+ let (mantissa, exponent, sign) = value.integer_decode();
17
+ let numerator = BigInt::from(mantissa) * BigInt::from(sign);
18
+ Some(if exponent < 0 {
19
+ BigRational::new(
20
+ numerator,
21
+ BigInt::from(1) << exponent.unsigned_abs() as usize,
22
+ )
23
+ } else {
24
+ BigRational::from_integer(numerator << exponent as usize)
25
+ })
26
+ }
27
+
8
28
  fn integer(value: Value) -> BigInt {
9
29
  if unsafe { sn_fixnum(value) } != 0 {
10
30
  return BigInt::from(unsafe { sn_integer(value) });
@@ -98,7 +118,7 @@ impl Rules {
98
118
  // in binary, but rounds Rational bounds to Float. With multipleOf,
99
119
  // Ruby first converts the instance's decimal spelling to a Rational.
100
120
  let binary = if actual.is_none() && self.limits.iter().any(|(_, limit)| limit.integer) {
101
- BigRational::from_float(n)
121
+ binary_float(n)
102
122
  } else {
103
123
  None
104
124
  };
@@ -152,3 +172,39 @@ impl Rules {
152
172
  Ok(bits)
153
173
  }
154
174
  }
175
+
176
+ #[cfg(test)]
177
+ mod tests {
178
+ use super::*;
179
+
180
+ #[test]
181
+ fn binary_float_preserves_exact_values() {
182
+ let cases = [
183
+ (0.0, BigRational::from_integer(BigInt::from(0))),
184
+ (-0.0, BigRational::from_integer(BigInt::from(0))),
185
+ (
186
+ 0.1,
187
+ BigRational::new(BigInt::from(3602879701896397_u64), BigInt::from(1) << 55),
188
+ ),
189
+ (
190
+ f64::from_bits(1),
191
+ BigRational::new(BigInt::from(1), BigInt::from(1) << 1074),
192
+ ),
193
+ (
194
+ f64::MIN_POSITIVE,
195
+ BigRational::new(BigInt::from(1), BigInt::from(1) << 1022),
196
+ ),
197
+ (
198
+ f64::MAX,
199
+ BigRational::from_integer(BigInt::from((1_u64 << 53) - 1) << 971),
200
+ ),
201
+ ];
202
+ for (value, expected) in cases {
203
+ assert_eq!(binary_float(value), Some(expected.clone()), "{value}");
204
+ assert_eq!(binary_float(-value), Some(-expected), "{}", -value);
205
+ }
206
+ for value in [f64::NAN, f64::INFINITY, f64::NEG_INFINITY] {
207
+ assert_eq!(binary_float(value), None);
208
+ }
209
+ }
210
+ }
@@ -2,7 +2,7 @@
2
2
  //! multipleOf semantics. All evaluation helpers operate under the GVL and
3
3
  //! allocate no Ruby objects; unsupported magnitudes retain VM compatibility.
4
4
  use super::*;
5
- use num_rational::BigRational;
5
+ use arbitrary::BigRational;
6
6
  use std::cmp::Ordering;
7
7
  mod arbitrary;
8
8
 
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "limit_budget"
4
+
5
+ module Schemurai
6
+ module Internal
7
+ # Limit policy shared by evaluators; error storage and scalar state stay local.
8
+ module EvaluationLimits
9
+ def validate(instance, max_errors: nil, timeout: nil, budget: nil)
10
+ with_budget(max_errors, timeout, budget) { super(instance) }
11
+ end
12
+
13
+ def valid?(instance, max_errors: nil, timeout: nil, budget: nil)
14
+ with_budget(max_errors, timeout, budget) { super(instance) }
15
+ end
16
+
17
+ private def with_budget(max_errors, timeout, budget)
18
+ @budget = budget || LimitBudget.new(max_errors: max_errors, timeout: timeout)
19
+ result = yield
20
+ @budget.check_deadline!
21
+ result
22
+ ensure
23
+ @budget = nil
24
+ end
25
+
26
+ private def evaluate(node, instance)
27
+ @budget.checkpoint
28
+ super
29
+ end
30
+
31
+ private def evaluate_valid(node, instance)
32
+ @budget.checkpoint
33
+ super
34
+ end
35
+
36
+ private def valid_string?(node, value)
37
+ @budget.check_deadline!
38
+ result = super
39
+ @budget.check_deadline!
40
+ result
41
+ end
42
+
43
+ private def check_string(node, value)
44
+ @budget.check_deadline!
45
+ result = super
46
+ @budget.check_deadline!
47
+ result
48
+ end
49
+
50
+ private def valid_content?(schema, value)
51
+ @budget.check_deadline!
52
+ result = super
53
+ @budget.check_deadline!
54
+ result
55
+ end
56
+
57
+ private def check_content(schema, value)
58
+ @budget.check_deadline!
59
+ result = super
60
+ @budget.check_deadline!
61
+ result
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,63 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "limit_exceeded"
4
- require_relative "limit_budget"
4
+ require_relative "evaluation_limits"
5
5
  require_relative "evaluator"
6
6
 
7
7
  module Schemurai
8
8
  module Internal
9
9
  # Ruby evaluation with invocation-local limits.
10
10
  class LimitedEvaluator < Evaluator
11
- def validate(instance, max_errors: nil, timeout: nil, budget: nil)
12
- @budget = budget || LimitBudget.new(max_errors: max_errors, timeout: timeout)
13
- errors = []
14
- each_error(instance) do |error|
15
- errors << error
16
- end
17
- @budget.check_deadline!
18
- Result.new(errors)
19
- ensure
20
- @budget = nil
21
- end
22
-
23
- def valid?(instance, max_errors: nil, timeout: nil, budget: nil)
24
- @budget = budget || LimitBudget.new(max_errors: max_errors, timeout: timeout)
25
- result = super(instance)
26
- @budget.check_deadline!
27
- result
28
- ensure
29
- @budget = nil
30
- end
31
-
32
- private def evaluate(node, instance)
33
- @budget.checkpoint
34
- super
35
- end
36
-
37
- private def evaluate_valid(node, instance)
38
- @budget.checkpoint
39
- super
40
- end
11
+ include EvaluationLimits
41
12
 
42
13
  private def add_error(keyword, message = nil, append_keyword: true, &block)
43
14
  @budget.reserve_error if @error_callback
44
15
  super
45
16
  end
46
17
 
47
- private def valid_string?(node, value)
48
- @budget.check_deadline!
49
- result = super
50
- @budget.check_deadline!
51
- result
52
- end
53
-
54
- private def check_string(node, value)
55
- @budget.check_deadline!
56
- result = super
57
- @budget.check_deadline!
58
- result
59
- end
60
-
61
18
  private def decimal(value)
62
19
  @budget.check_deadline!
63
20
  result = super
@@ -72,20 +29,6 @@ module Schemurai
72
29
  result
73
30
  end
74
31
 
75
- private def valid_content?(schema, value)
76
- @budget.check_deadline!
77
- result = super
78
- @budget.check_deadline!
79
- result
80
- end
81
-
82
- private def check_content(schema, value)
83
- @budget.check_deadline!
84
- result = super
85
- @budget.check_deadline!
86
- result
87
- end
88
-
89
32
  private def json_equal?(left, right)
90
33
  @budget.checkpoint
91
34
  super
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Schemurai
4
4
  # The installed Schemurai version.
5
- VERSION = "3.0.2"
5
+ VERSION = "3.1.0"
6
6
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "../limit_exceeded"
4
- require_relative "../limit_budget"
4
+ require_relative "../evaluation_limits"
5
5
  require_relative "evaluator"
6
6
 
7
7
  module Schemurai
@@ -10,73 +10,18 @@ module Schemurai
10
10
  class LimitedEvaluator < Evaluator
11
11
  include Internal::ValueEquality::Checkpoints
12
12
  include Internal::StringChecks::TimedRegexps
13
-
14
- def validate(instance, max_errors: nil, timeout: nil, budget: nil)
15
- @budget = budget || Internal::LimitBudget.new(max_errors: max_errors, timeout: timeout)
16
- result = super(instance)
17
- @budget.check_deadline!
18
- result
19
- ensure
20
- @budget = nil
21
- end
22
-
23
- def valid?(instance, max_errors: nil, timeout: nil, budget: nil)
24
- @budget = budget || Internal::LimitBudget.new(max_errors: max_errors, timeout: timeout)
25
- result = super(instance)
26
- @budget.check_deadline!
27
- result
28
- ensure
29
- @budget = nil
30
- end
31
-
32
- private def evaluate(node, instance)
33
- @budget.checkpoint
34
- super
35
- end
36
-
37
- private def evaluate_valid(node, instance)
38
- @budget.checkpoint
39
- super
40
- end
13
+ include Internal::EvaluationLimits
41
14
 
42
15
  private def add_error(keyword, message = nil, append_keyword: true, &block)
43
16
  @budget.reserve_error if @errors
44
17
  super
45
18
  end
46
19
 
47
- private def valid_string?(node, value)
48
- @budget.check_deadline!
49
- result = super
50
- @budget.check_deadline!
51
- result
52
- end
53
-
54
- private def check_string(node, value)
55
- @budget.check_deadline!
56
- result = super
57
- @budget.check_deadline!
58
- result
59
- end
60
-
61
20
  private def number_state
62
21
  state = super
63
22
  state.budget = @budget
64
23
  state
65
24
  end
66
-
67
- private def valid_content?(schema, value)
68
- @budget.check_deadline!
69
- result = super
70
- @budget.check_deadline!
71
- result
72
- end
73
-
74
- private def check_content(schema, value)
75
- @budget.check_deadline!
76
- result = super
77
- @budget.check_deadline!
78
- result
79
- end
80
25
  end
81
26
  end
82
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schemurai
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.2
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kuya KOHARA (oakcask)
@@ -84,6 +84,7 @@ files:
84
84
  - lib/schemurai/ecma_regexp.rb
85
85
  - lib/schemurai/error_message.rb
86
86
  - lib/schemurai/evaluation.rb
87
+ - lib/schemurai/evaluation_limits.rb
87
88
  - lib/schemurai/evaluation_pool.rb
88
89
  - lib/schemurai/evaluator.rb
89
90
  - lib/schemurai/formats.rb
@@ -117,7 +118,7 @@ licenses:
117
118
  metadata:
118
119
  homepage_uri: https://github.com/oakcask/schemurai
119
120
  source_code_uri: https://github.com/oakcask/schemurai/tree/main
120
- documentation_uri: https://rubydoc.info/gems/schemurai/3.0.2
121
+ documentation_uri: https://rubydoc.info/gems/schemurai/3.1.0
121
122
  rubygems_mfa_required: 'true'
122
123
  rdoc_options:
123
124
  - "--main"