roda 3.61.0 → 3.63.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 337e7cc074ffe0c300a4dbf9a14f72552caa5b9446fdf0ca04b9f22d9117c9c7
4
- data.tar.gz: 53a8b4ec124df8ef0efdc7efcc7bec3e0e7ea7d13fa60fb5d6adf06f50ed081e
3
+ metadata.gz: 6e19674abcd02c79572ada44fe13fc8188a4cc91b780a3fbaa39da206cf7457f
4
+ data.tar.gz: ffd0e850b4aab5e82b3f5cf307145853df9d420389ff8eb6170ec53d3e29ca57
5
5
  SHA512:
6
- metadata.gz: 78671d90145cf431a7deff333e6b75ad681252cae159b5ff09dfaba70d4b3fc17ec1f7362c52454c3f8e94e2343bd4b4d419a5c23738a6b525e9fdd79dc8846c
7
- data.tar.gz: 55b5bc0be878d58d66e0834110b47313f522e1f109b95c23348b2cb09430b01383595197db8f8db6587f10d3d9e4a7a353a2d70fb1ed4a099573309a5aabcae6
6
+ metadata.gz: d91087a996b037de3c0ecc3ca5e029f6b4bb40c5da1618048d70c0aa42ac5dcc581b6ed67e55cd9236da5463c3c224c62b09f85797daeffcb9a8fb98a16bca03
7
+ data.tar.gz: 62d2e2fdb0efa867299a764d4f7b36fc1a1e680147d32703d29451e29d2e3090a0f337c2c87ac46929a5a504b6461f92d18b50a14c62f422de4c114e43892c91
data/CHANGELOG CHANGED
@@ -1,3 +1,21 @@
1
+ = 3.63.0 (2022-12-16)
2
+
3
+ * Make mailer plugin set configured content type for body part for emails with attachments when using mail 2.8+ (jeremyevans)
4
+
5
+ * Add autoload_hash_branches plugin for autoloading file for a hash branch when there is a request for that branch (jeremyevans)
6
+
7
+ * Add mailer plugin :terminal option to make r.mail use a terminal match when provided arguments (jeremyevans)
8
+
9
+ = 3.62.0 (2022-11-14)
10
+
11
+ * Add typecast_params_sized_integers plugin for converting parameters to sized integers (jeremyevans)
12
+
13
+ * Add Integer_matcher_max plugin for setting maximum integer value matched by the Integer matcher (jeremyevans)
14
+
15
+ * Allow class matchers in the class_matchers plugin to skip matching based on regexp match values (jeremyevans)
16
+
17
+ * Fix RodaRequest#matched_path when using unescape_path plugin (jeremyevans) (#286)
18
+
1
19
  = 3.61.0 (2022-10-12)
2
20
 
3
21
  * Make Integer matcher limit integer segments to 100 characters by default (jeremyevans)
@@ -0,0 +1,41 @@
1
+ = New Features
2
+
3
+ * An Integer_matcher_max plugin has been added for setting the
4
+ maximum value matched by the Integer matcher (the minimum is
5
+ always 0, since the Integer matcher does not match negative
6
+ integers). The default maximum value when using the plugin
7
+ is 2**63-1, the maximum value for a signed 64-bit integer.
8
+ You can specify a different maximum value by passing an argument
9
+ when loading the plugin.
10
+
11
+ * A typecast_params_sized_integers plugin has been added for
12
+ converting parameters to integers only if the integer is within a
13
+ specific size. By default, the plugin supports 8-bit, 16-bit,
14
+ 32-bit, and 64-bit signed and unsigned integer types, with the
15
+ following typecast_params methods added by the plugin:
16
+
17
+ * int8, uint8, pos_int8, pos_uint8, Integer8, Integeru8
18
+ * int16, uint16, pos_int16, pos_uint16, Integer16, Integeru16
19
+ * int32, uint32, pos_int32, pos_uint32, Integer32, Integeru32
20
+ * int64, uint64, pos_int64, pos_uint64, Integer64, Integeru64
21
+
22
+ You can override what sizes are added by default by using the
23
+ :sizes option. You can also specify a :default_size option,
24
+ in which case the default int, pos_int, and Integer conversions
25
+ will use the given size. So if you want to change the default
26
+ typecast_params integer conversion behavior to only support
27
+ integer values that can fit in 64-bit signed integers, you can
28
+ use:
29
+
30
+ plugin :typecast_params_sized_integers, sizes: [64],
31
+ default_size: 64
32
+
33
+ = Other Improvements
34
+
35
+ * The block passed to the class_matcher method in the class_matchers
36
+ plugin can now return nil/false to signal that it should not match.
37
+ This is useful when the regexp argument provided matches segments
38
+ not valid for the class.
39
+
40
+ * RodaRequest#matched_path now works correctly when using the
41
+ unescape_path plugin.
@@ -0,0 +1,36 @@
1
+ = New Features
2
+
3
+ * An autoload_hash_branches plugin has been added for autoloading
4
+ route files for each hash branch, instead of requiring the route
5
+ files be loaded up front. For example, to automatically load a
6
+ route file for a hash branch on the first request to that branch:
7
+
8
+ plugin :autoload_hash_branches
9
+ autoload_hash_branch('branch_name', '/path/to/file')
10
+ autoload_hash_branch('namespace', 'branch_name', '/path/to/file')
11
+
12
+ The route file loaded should define the expected hash branch.
13
+
14
+ It is common to have route files stored in a directory, with the
15
+ file name matching the branch name. In that case, you can set
16
+ autoloading for all route files in a given directory:
17
+
18
+ plugin :autoload_hash_branches
19
+ autoload_hash_branch_dir('/path/to/dir')
20
+ autoload_hash_branch_dir('namespace', '/path/to/dir')
21
+
22
+ Note that autoloading hash branches does not work if the application
23
+ is frozen. This plugin should only be used in development mode for
24
+ faster startup, or when running tests on a subset of the application
25
+ in order to avoid loading parts of the application unrelated to what
26
+ is being tested.
27
+
28
+ * The mailer plugin now supports a :terminal plugin option to make
29
+ the r.mail method force a terminal match, similar to how r.get
30
+ and other HTTP verb methods work in standard Roda. This behavior
31
+ will become the default in Roda 4.
32
+
33
+ = Other Improvements
34
+
35
+ * The mailer plugin now correctly sets the content_type of the body
36
+ for emails with attachments when using mail 2.8.0+.
@@ -0,0 +1,54 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The Integer_matcher_max plugin sets the maximum integer value
7
+ # value that the Integer class matcher will match by default.
8
+ # By default, loading this plugin sets the maximum value to
9
+ # 2**63-1, the largest signed 64-bit integer value:
10
+ #
11
+ # plugin :Integer_matcher_max
12
+ # route do |r|
13
+ # r.is Integer do
14
+ # # Matches /9223372036854775807
15
+ # # Does not match /9223372036854775808
16
+ # end
17
+ # end
18
+ #
19
+ # To specify a different maximum value, you can pass a different
20
+ # maximum value when loading the plugin:
21
+ #
22
+ # plugin :Integer_matcher_max, 2**64-1
23
+ module IntegerMatcherMax
24
+ def self.configure(app, max=nil)
25
+ if max
26
+ app::RodaRequest.class_eval do
27
+ define_method(:_match_class_max_Integer){max}
28
+ alias_method :_match_class_max_Integer, :_match_class_max_Integer
29
+ private :_match_class_max_Integer
30
+ end
31
+ end
32
+ end
33
+
34
+ module RequestMethods
35
+ private
36
+
37
+ # Do not have the Integer matcher max when over the maximum
38
+ # configured Integer value.
39
+ def _match_class_convert_Integer(value)
40
+ value = super
41
+ value if value <= _match_class_max_Integer
42
+ end
43
+
44
+ # Use 2**63-1 as the default maximum value for the Integer
45
+ # matcher.
46
+ def _match_class_max_Integer
47
+ 9223372036854775807
48
+ end
49
+ end
50
+ end
51
+
52
+ register_plugin(:Integer_matcher_max, IntegerMatcherMax)
53
+ end
54
+ end
@@ -52,9 +52,9 @@ class Roda
52
52
  end
53
53
  end
54
54
  elsif matcher == Integer
55
- if matchdata = /\A\/(\d{1,100})(?=\/|\z)/.match(@remaining_path)
55
+ if (matchdata = /\A\/(\d{1,100})(?=\/|\z)/.match(@remaining_path)) && (value = _match_class_convert_Integer(matchdata[1]))
56
56
  @remaining_path = matchdata.post_match
57
- always{yield(matchdata[1].to_i)}
57
+ always{yield(value)}
58
58
  end
59
59
  else
60
60
  path = @remaining_path
@@ -151,9 +151,9 @@ class Roda
151
151
  always{yield rp[1, len]}
152
152
  end
153
153
  elsif matcher == Integer
154
- if matchdata = /\A\/(\d{1,100})\z/.match(@remaining_path)
154
+ if (matchdata = /\A\/(\d{1,100})\z/.match(@remaining_path)) && (value = _match_class_convert_Integer(matchdata[1]))
155
155
  @remaining_path = ''
156
- always{yield(matchdata[1].to_i)}
156
+ always{yield(value)}
157
157
  end
158
158
  else
159
159
  path = @remaining_path
@@ -0,0 +1,67 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The autoload_hash_branches plugin builds on the hash_branches plugin and allows for
7
+ # delaying loading of a file containing a hash branch for an application until there
8
+ # is a request that uses the hash branch. This can be useful in development
9
+ # to improvement startup time by not loading all branches up front. It can also be
10
+ # useful in testing subsets of an application by only loading the hash branches being
11
+ # tested.
12
+ #
13
+ # You can specify a single hash branch for autoloading:
14
+ #
15
+ # plugin :autoload_hash_branches
16
+ # autoload_hash_branch('branch_name', '/path/to/file')
17
+ # autoload_hash_branch('namespace', 'branch_name', '/path/to/file')
18
+ #
19
+ # You can also set the plugin to autoload load all hash branch files in a given directory.
20
+ # This will look at each .rb file in the directory, and add an autoload for it, using the
21
+ # filename without the .rb as the branch name:
22
+ #
23
+ # autoload_hash_branch_dir('/path/to/dir')
24
+ # autoload_hash_branch_dir('namespace', '/path/to/dir')
25
+ #
26
+ # In both cases, when the autoloaded file is required, it should redefine the same
27
+ # hash branch. If it does not, requests to the hash branch will result in a 404 error.
28
+ #
29
+ # This plugin will not work correctly when freezing applications, because it requires
30
+ # modifying the class at runtime as hash branches are autoloaded.
31
+ module AutoloadHashBranches
32
+ def self.load_dependencies(app)
33
+ app.plugin :hash_branches
34
+ end
35
+
36
+ module ClassMethods
37
+ # Autoload the given file when there is request for the hash branch.
38
+ # The given file should configure the hash branch specified.
39
+ def autoload_hash_branch(namespace='', segment, file)
40
+ segment = "/#{segment}"
41
+ routes = opts[:hash_branches][namespace] ||= {}
42
+ meth = routes[segment] = define_roda_method(routes[segment] || "hash_branch_#{namespace}_#{segment}", 1) do |r|
43
+ loc = method(routes[segment]).source_location
44
+ require file
45
+ # Avoid infinite loop in case method is not overridden
46
+ if method(meth).source_location != loc
47
+ send(meth, r)
48
+ end
49
+ end
50
+ nil
51
+ end
52
+
53
+ # For each .rb file in the given directory, add an autoloaded hash branch
54
+ # based on the file name.
55
+ def autoload_hash_branch_dir(namespace='', dir)
56
+ Dir.new(dir).entries.each do |file|
57
+ if file =~ /\.rb\z/i
58
+ autoload_hash_branch(namespace, file.sub(/\.rb\z/i, ''), File.join(dir, file))
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ register_plugin(:autoload_hash_branches, AutoloadHashBranches)
66
+ end
67
+ end
@@ -28,6 +28,18 @@ class Roda
28
28
  # This is useful to DRY up code if you are using the same type of pattern and
29
29
  # type conversion in multiple places in your application.
30
30
  #
31
+ # If you have a segment match the passed regexp, but decide during block
32
+ # processing that you do not want to treat it as a match, you can have the
33
+ # block return nil or false. This is useful if you want to make sure you
34
+ # are using valid data:
35
+ #
36
+ # class_matcher(Date, /(\dd\d)-(\d\d)-(\d\d)/) do |y, m, d|
37
+ # y = y.to_i
38
+ # m = m.to_i
39
+ # d = d.to_i
40
+ # [Date.new(y, m, d)] if Date.valid_date?(y, m, d)
41
+ # end
42
+ #
31
43
  # This plugin does not work with the params_capturing plugin, as it does not
32
44
  # offer the ability to associate block arguments with named keys.
33
45
  module ClassMatchers
@@ -56,7 +56,7 @@ class Roda
56
56
  # r.halt(:template) if r.params['a']
57
57
  #
58
58
  # # symbol_views plugin, specifying status code, headers, and template file to render as body
59
- # r.halt(500, 'header=>'value', :other_template) if r.params['c']
59
+ # r.halt(500, {'header'=>'value'}, :other_template) if r.params['c']
60
60
  #
61
61
  # # json plugin, specifying status code and JSON body
62
62
  # r.halt(500, [{'error'=>'foo'}]) if r.params['b']
@@ -115,6 +115,11 @@ class Roda
115
115
  #
116
116
  # plugin :mailer, content_type: 'text/html'
117
117
  #
118
+ # For backwards compatibility reasons, the +r.mail+ method does not do
119
+ # a terminal match by default if provided arguments (unlike +r.get+ and
120
+ # +r.post+). You can pass the :terminal option to make +r.mail+ enforce
121
+ # a terminal match if provided arguments.
122
+ #
118
123
  # The mailer plugin does support being used inside a Roda application
119
124
  # that is handling web requests, where the routing block for mails and
120
125
  # web requests is shared. However, it's recommended that you create a
@@ -163,7 +168,8 @@ class Roda
163
168
  # any arguments passed to the +mail+ or +sendmail+ Roda class methods.
164
169
  def mail(*args)
165
170
  if @env["REQUEST_METHOD"] == "MAIL"
166
- if_match(args) do |*vs|
171
+ # RODA4: Make terminal match the default
172
+ send(roda_class.opts[:mailer][:terminal] ? :_verb : :if_match, args) do |*vs|
167
173
  yield(*(vs + @env['roda.mail_args']))
168
174
  end
169
175
  end
@@ -190,9 +196,9 @@ class Roda
190
196
 
191
197
  if content_type = header_content_type || roda_class.opts[:mailer][:content_type]
192
198
  if mail.multipart?
193
- if mail.content_type =~ /multipart\/mixed/ &&
199
+ if /multipart\/mixed/ =~ mail.content_type &&
194
200
  mail.parts.length >= 2 &&
195
- (part = mail.parts.find{|p| !p.attachment && p.content_type == "text/plain"})
201
+ (part = mail.parts.find{|p| !p.attachment && (p.encoded; /text\/plain/ =~ p.content_type)})
196
202
  part.content_type = content_type
197
203
  end
198
204
  else
@@ -526,9 +526,10 @@ class Roda
526
526
  handle_type(:int, :max_input_bytesize=>100) do |v|
527
527
  string_or_numeric!(v) && v.to_i
528
528
  end
529
+ alias base_convert_int convert_int
529
530
 
530
531
  handle_type(:pos_int, :max_input_bytesize=>100) do |v|
531
- if (v = convert_int(v)) && v > 0
532
+ if (v = base_convert_int(v)) && v > 0
532
533
  v
533
534
  end
534
535
  end
@@ -547,6 +548,7 @@ class Roda
547
548
  end
548
549
  end
549
550
  end
551
+ alias base_convert_Integer convert_Integer
550
552
 
551
553
  handle_type(:float, :max_input_bytesize=>1000) do |v|
552
554
  string_or_numeric!(v) && v.to_f
@@ -0,0 +1,107 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The typecast_params_sized_integers plugin adds sized integer conversion
7
+ # methods to typecast_params:
8
+ #
9
+ # * int8, uint8, pos_int8, pos_uint8, Integer8, Integeru8
10
+ # * int16, uint16, pos_int16, pos_uint16, Integer16, Integeru16
11
+ # * int32, uint32, pos_int32, pos_uint32, Integer32, Integeru32
12
+ # * int64, uint64, pos_int64, pos_uint64, Integer64, Integeru64
13
+ #
14
+ # The int*, pos_int*, and Integer* methods operate the same as the
15
+ # standard int, pos_int, and Integer methods in typecast_params,
16
+ # except that they will only handle parameter values in the given
17
+ # range for the signed integer type. The uint*, pos_int*, and
18
+ # Integeru* methods are similar to the int*, pos_int*, and
19
+ # Integer* methods, except they use the range of the unsigned
20
+ # integer type instead of the range of the signed integer type.
21
+ #
22
+ # Here are the signed and unsigned integer type ranges:
23
+ # 8 :: [-128, 127], [0, 255]
24
+ # 16 :: [-32768, 32767], [0, 65535]
25
+ # 32 :: [-2147483648, 2147483647], [0, 4294967295]
26
+ # 64 :: [-9223372036854775808, 9223372036854775807], [0, 18446744073709551615]
27
+ #
28
+ # To only create methods for certain integer sizes, you can pass a
29
+ # :sizes option when loading the plugin, and it will only create
30
+ # methods for the sizes you specify.
31
+ #
32
+ # You can provide a :default_size option when loading the plugin,
33
+ # in which case the int, uint, pos_int, pos_uint, Integer, and Integeru,
34
+ # typecast_params conversion methods will be aliases to the conversion
35
+ # methods for the given sized type:
36
+ #
37
+ # plugin :typecast_params_sized_integers, default_size: 64
38
+ #
39
+ # route do |r|
40
+ # # Returns nil unless param.to_i > 0 && param.to_i <= 9223372036854775807
41
+ # typecast_params.pos_int('param_name')
42
+ # end
43
+ module TypecastParamsSizedIntegers
44
+ def self.load_dependencies(app, opts=OPTS)
45
+ app.plugin :typecast_params do
46
+ (opts[:sizes] || [8, 16, 32, 64]).each do |i|
47
+ # Avoid defining the same methods more than once
48
+ next if method_defined?(:"pos_int#{i}")
49
+
50
+ min_signed = -(2**(i-1))
51
+ max_signed = 2**(i-1)-1
52
+ max_unsigned = 2**i-1
53
+
54
+ handle_type(:"int#{i}", :max_input_bytesize=>100) do |v|
55
+ if (v = base_convert_int(v)) && v >= min_signed && v <= max_signed
56
+ v
57
+ end
58
+ end
59
+
60
+ handle_type(:"uint#{i}", :max_input_bytesize=>100) do |v|
61
+ if (v = base_convert_int(v)) && v >= 0 && v <= max_unsigned
62
+ v
63
+ end
64
+ end
65
+
66
+ handle_type(:"pos_int#{i}", :max_input_bytesize=>100) do |v|
67
+ if (v = base_convert_int(v)) && v > 0 && v <= max_signed
68
+ v
69
+ end
70
+ end
71
+
72
+ handle_type(:"pos_uint#{i}", :max_input_bytesize=>100) do |v|
73
+ if (v = base_convert_int(v)) && v > 0 && v <= max_unsigned
74
+ v
75
+ end
76
+ end
77
+
78
+ handle_type(:"Integer#{i}", :max_input_bytesize=>100) do |v|
79
+ if (v = base_convert_Integer(v)) && v >= min_signed && v <= max_signed
80
+ v
81
+ end
82
+ end
83
+
84
+ handle_type(:"Integeru#{i}", :max_input_bytesize=>100) do |v|
85
+ if (v = base_convert_Integer(v)) && v >= 0 && v <= max_unsigned
86
+ v
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ if default = opts[:default_size]
93
+ app::TypecastParams.class_eval do
94
+ %w[int uint pos_int pos_uint Integer Integeru].each do |type|
95
+ ['', 'convert_', '_convert_array_', '_max_input_bytesize_for_'].each do |prefix|
96
+ alias_method :"#{prefix}#{type}", :"#{prefix}#{type}#{default}"
97
+ end
98
+ alias_method :"#{type}!", :"#{type}#{default}!"
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ register_plugin(:typecast_params_sized_integers, TypecastParamsSizedIntegers)
106
+ end
107
+ end
@@ -20,6 +20,13 @@ class Roda
20
20
  # end
21
21
  module UnescapePath
22
22
  module RequestMethods
23
+ # Make sure the matched path calculation handles the unescaping
24
+ # of the remaining path.
25
+ def matched_path
26
+ e = @env
27
+ Rack::Utils.unescape(e["SCRIPT_NAME"] + e["PATH_INFO"]).chomp(@remaining_path)
28
+ end
29
+
23
30
  private
24
31
 
25
32
  # Unescape the path.
data/lib/roda/request.rb CHANGED
@@ -443,7 +443,16 @@ class Roda
443
443
  # Match integer segment of up to 100 decimal characters, and yield resulting value as an
444
444
  # integer.
445
445
  def _match_class_Integer
446
- consume(/\A\/(\d{1,100})(?=\/|\z)/){|i| [i.to_i]}
446
+ consume(/\A\/(\d{1,100})(?=\/|\z)/) do |i|
447
+ if i = _match_class_convert_Integer(i)
448
+ [i]
449
+ end
450
+ end
451
+ end
452
+
453
+ # Convert the segment matched by the Integer matcher to an integer.
454
+ def _match_class_convert_Integer(value)
455
+ value.to_i
447
456
  end
448
457
 
449
458
  # Match only if all of the arguments in the given array match.
@@ -548,9 +557,11 @@ class Roda
548
557
  # path from PATH_INFO, and updates captures with any regex captures.
549
558
  def consume(pattern)
550
559
  if matchdata = pattern.match(@remaining_path)
551
- @remaining_path = matchdata.post_match
552
560
  captures = matchdata.captures
553
- captures = yield(*captures) if defined?(yield)
561
+ if defined?(yield)
562
+ return unless captures = yield(*captures)
563
+ end
564
+ @remaining_path = matchdata.post_match
554
565
  @captures.concat(captures)
555
566
  end
556
567
  end
data/lib/roda/version.rb CHANGED
@@ -4,7 +4,7 @@ class Roda
4
4
  RodaMajorVersion = 3
5
5
 
6
6
  # The minor version of Roda, updated for new feature releases of Roda.
7
- RodaMinorVersion = 61
7
+ RodaMinorVersion = 63
8
8
 
9
9
  # The patch version of Roda, updated only for bug fixes from the last
10
10
  # feature release.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roda
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.61.0
4
+ version: 3.63.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-12 00:00:00.000000000 Z
11
+ date: 2022-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -234,6 +234,8 @@ extra_rdoc_files:
234
234
  - doc/release_notes/3.6.0.txt
235
235
  - doc/release_notes/3.60.0.txt
236
236
  - doc/release_notes/3.61.0.txt
237
+ - doc/release_notes/3.62.0.txt
238
+ - doc/release_notes/3.63.0.txt
237
239
  - doc/release_notes/3.7.0.txt
238
240
  - doc/release_notes/3.8.0.txt
239
241
  - doc/release_notes/3.9.0.txt
@@ -302,12 +304,15 @@ files:
302
304
  - doc/release_notes/3.6.0.txt
303
305
  - doc/release_notes/3.60.0.txt
304
306
  - doc/release_notes/3.61.0.txt
307
+ - doc/release_notes/3.62.0.txt
308
+ - doc/release_notes/3.63.0.txt
305
309
  - doc/release_notes/3.7.0.txt
306
310
  - doc/release_notes/3.8.0.txt
307
311
  - doc/release_notes/3.9.0.txt
308
312
  - lib/roda.rb
309
313
  - lib/roda/cache.rb
310
314
  - lib/roda/plugins.rb
315
+ - lib/roda/plugins/Integer_matcher_max.rb
311
316
  - lib/roda/plugins/_after_hook.rb
312
317
  - lib/roda/plugins/_before_hook.rb
313
318
  - lib/roda/plugins/_optimized_matching.rb
@@ -317,6 +322,7 @@ files:
317
322
  - lib/roda/plugins/all_verbs.rb
318
323
  - lib/roda/plugins/assets.rb
319
324
  - lib/roda/plugins/assets_preloading.rb
325
+ - lib/roda/plugins/autoload_hash_branches.rb
320
326
  - lib/roda/plugins/backtracking_array.rb
321
327
  - lib/roda/plugins/branch_locals.rb
322
328
  - lib/roda/plugins/caching.rb
@@ -423,6 +429,7 @@ files:
423
429
  - lib/roda/plugins/timestamp_public.rb
424
430
  - lib/roda/plugins/type_routing.rb
425
431
  - lib/roda/plugins/typecast_params.rb
432
+ - lib/roda/plugins/typecast_params_sized_integers.rb
426
433
  - lib/roda/plugins/unescape_path.rb
427
434
  - lib/roda/plugins/view_options.rb
428
435
  - lib/roda/request.rb
@@ -453,7 +460,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
453
460
  - !ruby/object:Gem::Version
454
461
  version: '0'
455
462
  requirements: []
456
- rubygems_version: 3.3.7
463
+ rubygems_version: 3.3.26
457
464
  signing_key:
458
465
  specification_version: 4
459
466
  summary: Routing tree web toolkit