roda 3.105.0 → 3.106.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: 4f6f16557b167cdca71f0005ed7b4e40c4465b6400874e05a8ece95e7dad7b68
4
- data.tar.gz: decd44332e836e46bc4bb2a6f93e7d40730fbf9f016c83b8a6ae99169c74efd3
3
+ metadata.gz: 90404574f8af3e952feb444cabe5bb01430e2d7c3658daee9f22f0c22e25d5f6
4
+ data.tar.gz: 347ba47cf4c3b9e280848ba717a1a4a9f57f8ac0712d2aaa8e5942020c22cb29
5
5
  SHA512:
6
- metadata.gz: 768134a23ee25d9f9d41641b1bf3dd5d499624b05adf9261f90300407a5dcd55d1535f080547d573b11e19d161c4563eb8538d998ee627d11329e6b59223db88
7
- data.tar.gz: 00aa1dfbbc81b5754a824fa668324886338f4a4827d27a2de6cfff5b6318c8e4aba1c8c93afb8e96f80b214b4ba6b96917b3df77108f1eaa60153fa5fc5add5e
6
+ metadata.gz: 00e03ccebd8d48c4c1576ae0da2929d85a30430114b9a292bd8b9029fba31b4a7fa10767d7fb59a643c4280fb659e9afa90dacde27c7a5bdbc98fc5ee1df40a6
7
+ data.tar.gz: 7867f8da5bad9db4102f09fc692158feee7605c8021b5d01bb07ebfe57d3a82ca0b18d7fc1341d6e5cdf9ff534736a6c9c3ce2420b2078abe96209ad423bce92
@@ -21,6 +21,8 @@ class Roda
21
21
  # have higher precedence than the render_locals plugin options, but lower precedence
22
22
  # than options you directly pass to the view/render methods.
23
23
  module BranchLocals
24
+ SCOPE_INSTANCE_VARIABLES = [:@_layout_locals, :@_view_locals].freeze
25
+
24
26
  # Load the render_locals plugin before this plugin, since this plugin
25
27
  # works by overriding methods in the render_locals plugin.
26
28
  def self.load_dependencies(app)
@@ -148,6 +148,8 @@ class Roda
148
148
  # method is not called until template rendering, the flash may not be
149
149
  # rotated.
150
150
  module Chunked
151
+ SCOPE_INSTANCE_VARIABLES = [:@_chunked, :@_each_chunk_args, :@_delays, :@_flusher].freeze
152
+
151
153
  # Depend on the render plugin
152
154
  def self.load_dependencies(app, opts=OPTS)
153
155
  app.plugin :render
@@ -215,7 +217,7 @@ class Roda
215
217
  # If chunking by default, call chunked if it hasn't yet been
216
218
  # called and chunking is not specifically disabled.
217
219
  def view(*a)
218
- if opts[:chunk_by_default] && !defined?(@_chunked) && !defined?(yield)
220
+ if opts[:chunk_by_default] && @_chunked != false && !defined?(yield)
219
221
  chunked(*a)
220
222
  else
221
223
  super
@@ -225,7 +227,7 @@ class Roda
225
227
  # Render a response to the user in chunks. See Chunked for
226
228
  # an overview. If a block is given, it is passed to #delay.
227
229
  def chunked(template, opts=OPTS, &block)
228
- unless defined?(@_chunked)
230
+ if @_chunked.nil?
229
231
  @_chunked = !self.opts[:force_chunked_encoding] || @_request.http_version == "HTTP/1.1"
230
232
  end
231
233
 
@@ -20,6 +20,8 @@ class Roda
20
20
  # plugin :common_logger, Logger.new('filename')
21
21
  # plugin :common_logger, Logger.new('filename'), method: :debug
22
22
  module CommonLogger
23
+ SCOPE_INSTANCE_VARIABLES = [:@_request_timer].freeze
24
+
23
25
  MUTATE_LINE = RUBY_VERSION < '2.3' || RUBY_VERSION >= '3'
24
26
  private_constant :MUTATE_LINE
25
27
 
@@ -55,6 +55,8 @@ class Roda
55
55
  #
56
56
  # plugin :content_for, append: false
57
57
  module ContentFor
58
+ SCOPE_INSTANCE_VARIABLES = [:@_content_for].freeze
59
+
58
60
  # Depend on the capture_erb plugin, since it uses capture_erb
59
61
  # to capture the content.
60
62
  def self.load_dependencies(app, _opts = OPTS)
@@ -111,6 +111,8 @@ class Roda
111
111
  # is given. Also, there is a +report_only?+ method for returning whether report only
112
112
  # mode is enabled.
113
113
  module ContentSecurityPolicy
114
+ RESPONSE_INSTANCE_VARIABLES = [:@content_security_policy, :@skip_content_security_policy].freeze
115
+
114
116
  # Represents a content security policy.
115
117
  class Policy
116
118
  '
@@ -192,6 +194,8 @@ class Roda
192
194
  # Clear all settings, useful to remove any inherited settings.
193
195
  def clear
194
196
  @opts = {}
197
+ @report_only = nil
198
+ @header_value = nil
195
199
  end
196
200
 
197
201
  # Do not allow future modifications to any settings.
@@ -36,6 +36,8 @@ class Roda
36
36
  # flash['a'] # = >'b'
37
37
  # end
38
38
  module Flash
39
+ SCOPE_INSTANCE_VARIABLES = [:@_flash].freeze
40
+
39
41
  # Simple flash hash, where assiging to the hash updates the flash
40
42
  # used in the following request.
41
43
  class FlashHash < DelegateClass(Hash)
@@ -71,6 +71,8 @@ class Roda
71
71
  # This plugin uses the host method on the request to get the hostname (this method
72
72
  # is defined by Rack).
73
73
  module HostRouting
74
+ REQUEST_INSTANCE_VARIABLES = [:@_host_routing_host].freeze
75
+
74
76
  # Setup the host routing support. The block yields an object used to
75
77
  # configure the plugin. Options:
76
78
  #
@@ -110,6 +112,8 @@ class Roda
110
112
  def initialize
111
113
  @hosts = []
112
114
  @host_hash = {}
115
+ @default_host = nil
116
+ @default_block = nil
113
117
  end
114
118
 
115
119
  # Run the DSL for the given block.
@@ -39,6 +39,8 @@ class Roda
39
39
  # it affects all rack applications instead of just the Roda app that
40
40
  # you load the plugin into.
41
41
  module IndifferentParams
42
+ SCOPE_INSTANCE_VARIABLES = [:@_params].freeze
43
+
42
44
  INDIFFERENT_PROC = lambda{|h,k| h[k.to_s] if k.is_a?(Symbol)}
43
45
 
44
46
  if Rack.release > '2'
@@ -127,6 +127,8 @@ class Roda
127
127
  # Roda application if you want your helper methods to automatically be
128
128
  # available in your email views.
129
129
  module Mailer
130
+ RESPONSE_INSTANCE_VARIABLES = [:@mail, :@mail_attachments].freeze
131
+
130
132
  # Error raised when the using the mail class method, but the routing
131
133
  # tree doesn't return the mail object.
132
134
  class Error < ::Roda::RodaError; end
@@ -68,6 +68,8 @@ class Roda
68
68
  #
69
69
  # This plugin depends on the all_verbs plugin.
70
70
  module NotAllowed
71
+ REQUEST_INSTANCE_VARIABLES = [:@_is_verbs].freeze
72
+
71
73
  # Depend on the all_verbs plugin, as this plugin overrides methods
72
74
  # defined by it and calls super.
73
75
  def self.load_dependencies(app)
@@ -55,6 +55,8 @@ class Roda
55
55
  # the symbol_matchers plugin with custom symbol matching and are using
56
56
  # symbols that capture multiple values or no values.
57
57
  module ParamsCapturing
58
+ REQUEST_INSTANCE_VARIABLES = [:@_params_captures].freeze
59
+
58
60
  module RequestMethods
59
61
  # Lazily initialize captures entry when params is called.
60
62
  def params
@@ -104,6 +104,8 @@ class Roda
104
104
  # setting a policy. This is faster than calling +permissions_policy.clear+, since
105
105
  # it does not duplicate the default policy.
106
106
  module PermissionsPolicy
107
+ RESPONSE_INSTANCE_VARIABLES = [:@permissions_policy, :@skip_permissions_policy].freeze
108
+
107
109
  SUPPORTED_SETTINGS = %w'
108
110
  accelerometer
109
111
  ambient-light-sensor
@@ -180,6 +182,8 @@ class Roda
180
182
  # Clear all settings, useful to remove any inherited settings.
181
183
  def clear
182
184
  @opts = {}
185
+ @report_only = nil
186
+ @header_value = nil
183
187
  end
184
188
 
185
189
  # Do not allow future modifications to any settings.
@@ -31,6 +31,8 @@ class Roda
31
31
  # This plugin is mostly designed for applications using Roda as a static
32
32
  # site generator, where the generated site can be hosted at any subpath.
33
33
  module RelativePath
34
+ SCOPE_INSTANCE_VARIABLES = [:@_relative_prefix].freeze
35
+
34
36
  module InstanceMethods
35
37
  # Return a relative path for the absolute path based on the current path
36
38
  # of the request by adding the appropriate prefix.
@@ -25,6 +25,8 @@ class Roda
25
25
  #
26
26
  # plugin :request_headers
27
27
  module RequestHeaders
28
+ REQUEST_INSTANCE_VARIABLES = [:@request_headers].freeze
29
+
28
30
  module RequestMethods
29
31
  # Provide access to the request headers while normalizing indexes.
30
32
  def headers
@@ -10,6 +10,13 @@ class Roda
10
10
  #
11
11
  # plugin :response_request
12
12
  module ResponseRequest
13
+ # This isn't set because it breaks usage with the error_handler/class_level_routing
14
+ # plugins and the shape_friendly plugin, due to those calling RodaResponse#initialize,
15
+ # which would reset @request to nil. It isn't strictly necessary to set this for
16
+ # shape friendliness, as the Roda#initialize sets it directly after creating the
17
+ # RodaRequest, so in normal use, the instance variable will already be set.
18
+ # RESPONSE_INSTANCE_VARIABLES = [:@request].freeze
19
+
13
20
  module InstanceMethods
14
21
  # Set the response's request to the current request.
15
22
  def initialize(env)
@@ -0,0 +1,232 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The shape_friendly plugin makes the scope, request, and response objects
7
+ # used by Roda friendly to object shapes, which can result in better
8
+ # performance on modern versions of Ruby, especially when the JIT compiler
9
+ # is enabled. All plugins shipped with Roda integrate with this plugin.
10
+ #
11
+ # In order for this behavior to be beneficial for your application, you
12
+ # need to either avoid setting instance variables inside your routing
13
+ # tree, or you need to register each instance variable used, to ensure
14
+ # that all instances have the same shape.
15
+ #
16
+ # If you want to avoid using instance variables in your routing tree, you
17
+ # can switch to using local variables. If using the render plugin, you can
18
+ # pass data from your routing tree to your views using the +:locals+ option.
19
+ # When passing data from your routing tree to other routing trees, such as
20
+ # when using the hash_branches plugin, you can use the shared_vars plugin,
21
+ # which stores the data in the Rack environment.
22
+ #
23
+ # To register instance variables set in your applications routing tree,
24
+ # use a +:scope_instance_variables+ option when loading the plugin,
25
+ # listing the instance variable symbols you are setting in the route
26
+ # block scope:
27
+ #
28
+ # class MyApp < Roda
29
+ # plugin :shape_friendly, scope_instance_variables: [:@var1, @:var2]
30
+ #
31
+ # route do |r|
32
+ # r.root do
33
+ # @var1 = "a"
34
+ # @var1.inspect
35
+ # end
36
+ #
37
+ # @var2 = "b"
38
+ # @var2.inspect
39
+ # end
40
+ # end
41
+ #
42
+ # When developing external plugins, you can set one of three constants in
43
+ # the plugin module to integrate with this plugin to support shape friendly
44
+ # behavior:
45
+ #
46
+ # * +SCOPE_INSTANCE_VARIABLES+: For instance variables set in +InstanceMethods+.
47
+ # * +REQUEST_INSTANCE_VARIABLES+: For instance variables set in +RequestMethods+.
48
+ # * +RESPONSE_INSTANCE_VARIABLES+: For instance variables set in +ResponseMethods+.
49
+ #
50
+ # These constants are set in the plugin module, not in the plugin's
51
+ # +InstanceMethods+, +RequestMethods+, or +ResponseMethods+ modules, to
52
+ # avoid pollution of the related namespaces in the class loading the plugin.
53
+ module ShapeFriendly
54
+ # This is used by the base support and not by this plugin.
55
+ RESPONSE_INSTANCE_VARIABLES = [:@status].freeze
56
+
57
+ # Set the Roda application to create the private
58
+ # _initialize_nil_instance_variables for the plugin to use.
59
+ def self.configure(app, opts=OPTS)
60
+ if scope_ivs = opts[:scope_instance_variables]
61
+ app.opts[:shape_friendly_scope_instance_variables] = Array(scope_ivs).dup.freeze
62
+ end
63
+
64
+ app.instance_exec do
65
+ def_initialize_nil_instance_variables(app, :SCOPE_INSTANCE_VARIABLES)
66
+ def_initialize_nil_instance_variables(app::RodaRequest, :REQUEST_INSTANCE_VARIABLES)
67
+ def_initialize_nil_instance_variables(app::RodaResponse, :RESPONSE_INSTANCE_VARIABLES)
68
+
69
+ # Avoid overhead of super call if possible
70
+ include(instance_method(:initialize).owner == Roda::RodaPlugins::Base::InstanceMethods ? OptimizedInstanceMethods : UnoptimizedInstanceMethods)
71
+ app::RodaRequest.send(:include, app::RodaRequest.instance_method(:initialize).owner == Roda::RodaPlugins::Base::RequestMethods ? OptimizedRequestMethods : UnoptimizedRequestMethods)
72
+ app::RodaResponse.send(:include, app::RodaResponse.instance_method(:initialize).owner == Roda::RodaPlugins::Base::ResponseMethods ? OptimizedResponseMethods : UnoptimizedResponseMethods)
73
+ end
74
+ end
75
+
76
+ module ClassMethods
77
+ # Automatically refresh the instance variables used if the plugin
78
+ # sets instance variables.
79
+ def plugin(plugin, *args, &block)
80
+ super
81
+ plugin = RodaPlugins.load_plugin(plugin) if plugin.is_a?(Symbol)
82
+ [
83
+ [self, :SCOPE_INSTANCE_VARIABLES],
84
+ [self::RodaRequest, :REQUEST_INSTANCE_VARIABLES],
85
+ [self::RodaResponse, :RESPONSE_INSTANCE_VARIABLES],
86
+ ].each do |klass, ivs_const|
87
+ if plugin.const_defined?(ivs_const)
88
+ def_initialize_nil_instance_variables(klass, ivs_const)
89
+ end
90
+ end
91
+ nil
92
+ end
93
+ # :nocov:
94
+ ruby2_keywords(:plugin) if respond_to?(:ruby2_keywords, true)
95
+ # :nocov:
96
+
97
+ private
98
+
99
+ # If there are any intance variables configured in one of the plugins
100
+ # (looking for the +const+ constant in the plugin), override the
101
+ # private _initialize_nil_instance_variables method for the class,
102
+ # and have it initialize each instance variable to nil.
103
+ def def_initialize_nil_instance_variables(klass, const)
104
+ ivs = []
105
+
106
+ plugins.each do |mod|
107
+ ivs.concat(mod.const_get(const)) if mod.const_defined?(const)
108
+ end
109
+
110
+ if const == :SCOPE_INSTANCE_VARIABLES && (scope_ivs = opts[:shape_friendly_scope_instance_variables])
111
+ ivs.concat(scope_ivs)
112
+ end
113
+
114
+ ivs.each do |iv|
115
+ unless /\A@[a-z_][a-z0-9_]*\z/.match(iv)
116
+ raise RodaError, "invalid scope instance variable used"
117
+ end
118
+ end
119
+
120
+ unless ivs.empty?
121
+ ivs.uniq!
122
+
123
+ klass.class_eval(<<-RUBY, __FILE__, __LINE__+1)
124
+ def _initialize_nil_instance_variables
125
+ #{ivs.reverse.join(" = ")} = nil
126
+ end
127
+ private :_initialize_nil_instance_variables
128
+ alias _initialize_nil_instance_variables _initialize_nil_instance_variables
129
+ RUBY
130
+ nil
131
+ end
132
+ end
133
+ end
134
+
135
+ # :nocov:
136
+ if RUBY_VERSION >= '4.0'
137
+ # :nocov:
138
+ module InstanceMethods
139
+ private
140
+
141
+ def instance_variables_to_inspect
142
+ instance_variables.reject{|v| instance_variable_get(v).nil?}
143
+ end
144
+ end
145
+ end
146
+
147
+ module OptimizedInstanceMethods
148
+ # Initialize configured instance variables to nil.
149
+ def initialize(env)
150
+ _initialize_nil_instance_variables
151
+ klass = self.class
152
+ @_request = klass::RodaRequest.new(self, env)
153
+ @_response = klass::RodaResponse.new
154
+ end
155
+
156
+ private
157
+
158
+ def _initialize_nil_instance_variables
159
+ nil
160
+ end
161
+ end
162
+
163
+ module UnoptimizedInstanceMethods
164
+ # Initialize configured instance variables to nil.
165
+ def initialize(env)
166
+ _initialize_nil_instance_variables
167
+ super
168
+ end
169
+
170
+ private
171
+
172
+ def _initialize_nil_instance_variables
173
+ nil
174
+ end
175
+ end
176
+
177
+ module OptimizedRequestMethods
178
+ # Initialize configured instance variables to nil.
179
+ def initialize(scope, env)
180
+ _initialize_nil_instance_variables
181
+ @scope = scope
182
+ @captures = []
183
+ @remaining_path = _remaining_path(env)
184
+ @env = env
185
+ end
186
+
187
+ private
188
+
189
+ def _initialize_nil_instance_variables
190
+ nil
191
+ end
192
+ end
193
+
194
+ module UnoptimizedRequestMethods
195
+ # Initialize configured instance variables to nil.
196
+ def initialize(scope, env)
197
+ _initialize_nil_instance_variables
198
+ super
199
+ end
200
+
201
+ private
202
+
203
+ def _initialize_nil_instance_variables
204
+ nil
205
+ end
206
+ end
207
+
208
+ module OptimizedResponseMethods
209
+ def initialize
210
+ _initialize_nil_instance_variables
211
+ @headers = _initialize_headers
212
+ @body = []
213
+ @length = 0
214
+ end
215
+ end
216
+
217
+ module UnoptimizedResponseMethods
218
+ # Initialize configured instance variables to nil.
219
+ def initialize
220
+ _initialize_nil_instance_variables
221
+ super
222
+ end
223
+ end
224
+
225
+ # For response methods, there is no default definition for
226
+ # _initialize_nil_instance_variables, as the plugin will always
227
+ # define a method in the class it is loaded into.
228
+ end
229
+
230
+ register_plugin(:shape_friendly, ShapeFriendly)
231
+ end
232
+ end
@@ -213,6 +213,7 @@ class Roda
213
213
  # called until the body is needed.
214
214
  def initialize(&block)
215
215
  @block = block
216
+ @value = nil
216
217
  end
217
218
 
218
219
  # If the body is a String, yield it, otherwise yield each string
@@ -89,6 +89,8 @@ class Roda
89
89
  # :use_header :: Whether to take the +Accept+ header into account.
90
90
  # Default is +true+.
91
91
  module TypeRouting
92
+ REQUEST_INSTANCE_VARIABLES = [:@requested_type, :@type_routing_extension].freeze
93
+
92
94
  CONFIGURATION = {
93
95
  :mimes => {
94
96
  'text/json' => :json,
@@ -158,7 +160,7 @@ class Roda
158
160
 
159
161
  # Returns the data type the client requests.
160
162
  def requested_type
161
- return @requested_type if defined?(@requested_type)
163
+ return @requested_type if @requested_type
162
164
 
163
165
  opts = @scope.opts[:type_routing]
164
166
  @requested_type = accept_response_type if opts[:use_header]
@@ -168,7 +170,7 @@ class Roda
168
170
  # Append the type routing extension back to the path if it was
169
171
  # removed before routing.
170
172
  def real_remaining_path
171
- if defined?(@type_routing_extension)
173
+ if @type_routing_extension
172
174
  "#{super}.#{@type_routing_extension}"
173
175
  else
174
176
  super
@@ -307,6 +307,8 @@ class Roda
307
307
  # By design, typecast_params only deals with string keys, it is not possible to use
308
308
  # symbol keys as arguments to the conversion methods and have them converted.
309
309
  module TypecastParams
310
+ SCOPE_INSTANCE_VARIABLES = [:@_typecast_params, :@_typecast_query_params, :@_typecast_body_params].freeze
311
+
310
312
  # Sentinal value for whether to raise exception during #process
311
313
  CHECK_NIL = Object.new.freeze
312
314
 
@@ -80,6 +80,8 @@ class Roda
80
80
  # end
81
81
  # end
82
82
  module ViewOptions
83
+ SCOPE_INSTANCE_VARIABLES = [:@_view_subdir, :@_view_options, :@_layout_options].freeze
84
+
83
85
  # Load the render plugin before this plugin, since this plugin
84
86
  # works by overriding methods in the render plugin.
85
87
  def self.load_dependencies(app)
@@ -29,6 +29,7 @@ class RodaSessionMiddleware
29
29
 
30
30
  def initialize(req)
31
31
  @req = req
32
+ @data = nil
32
33
  end
33
34
 
34
35
  # The Roda sessions plugin options used by the middleware for this
@@ -124,7 +125,7 @@ class RodaSessionMiddleware
124
125
 
125
126
  # Whether the session has already been loaded from the cookie yet.
126
127
  def loaded?
127
- !!defined?(@data)
128
+ !!@data
128
129
  end
129
130
 
130
131
  def empty?
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 = 105
7
+ RodaMinorVersion = 106
8
8
 
9
9
  # The patch version of Roda, updated only for bug fixes from the last
10
10
  # feature release.
data/lib/roda.rb CHANGED
@@ -17,6 +17,7 @@ class Roda
17
17
  @app = nil
18
18
  @inherit_middleware = true
19
19
  @middleware = []
20
+ @plugins = []
20
21
  @opts = {}
21
22
  @raw_route_block = nil
22
23
  @route_block = nil
@@ -42,6 +43,9 @@ class Roda
42
43
  # The settings/options hash for the current class.
43
44
  attr_reader :opts
44
45
 
46
+ # The plugins loaded into the current class.
47
+ attr_reader :plugins
48
+
45
49
  # The route block that this class uses.
46
50
  attr_reader :route_block
47
51
 
@@ -224,6 +228,7 @@ class Roda
224
228
 
225
229
  build_rack_app
226
230
  @opts.freeze
231
+ @plugins.freeze
227
232
  @middleware.freeze
228
233
 
229
234
  super
@@ -250,6 +255,7 @@ class Roda
250
255
  super
251
256
  subclass.instance_variable_set(:@inherit_middleware, @inherit_middleware)
252
257
  subclass.instance_variable_set(:@middleware, @inherit_middleware ? @middleware.dup : [])
258
+ subclass.instance_variable_set(:@plugins, @plugins.dup)
253
259
  subclass.instance_variable_set(:@opts, opts.dup)
254
260
  subclass.opts.delete(:subclassed)
255
261
  subclass.opts.to_a.each do |k,v|
@@ -291,6 +297,7 @@ class Roda
291
297
  end
292
298
 
293
299
  plugin.load_dependencies(self, *args, &block) if plugin.respond_to?(:load_dependencies)
300
+ @plugins << plugin unless @plugins.include?(plugin)
294
301
  include(plugin::InstanceMethods) if defined?(plugin::InstanceMethods)
295
302
  extend(plugin::ClassMethods) if defined?(plugin::ClassMethods)
296
303
  self::RodaRequest.send(:include, plugin::RequestMethods) if defined?(plugin::RequestMethods)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roda
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.105.0
4
+ version: 3.106.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
@@ -292,6 +292,7 @@ files:
292
292
  - lib/roda/plugins/sec_fetch_site_csrf.rb
293
293
  - lib/roda/plugins/send_file.rb
294
294
  - lib/roda/plugins/sessions.rb
295
+ - lib/roda/plugins/shape_friendly.rb
295
296
  - lib/roda/plugins/shared_vars.rb
296
297
  - lib/roda/plugins/sinatra_helpers.rb
297
298
  - lib/roda/plugins/slash_path_empty.rb