shrine 3.4.0 → 3.10.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.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +96 -0
  3. data/README.md +11 -11
  4. data/doc/advantages.md +1 -1
  5. data/doc/attacher.md +1 -1
  6. data/doc/carrierwave.md +2 -2
  7. data/doc/changing_derivatives.md +2 -1
  8. data/doc/changing_location.md +19 -6
  9. data/doc/design.md +4 -4
  10. data/doc/external/articles.md +16 -16
  11. data/doc/external/extensions.md +1 -1
  12. data/doc/getting_started.md +73 -30
  13. data/doc/multiple_files.md +57 -22
  14. data/doc/plugins/activerecord.md +91 -0
  15. data/doc/plugins/backgrounding.md +30 -4
  16. data/doc/plugins/data_uri.md +15 -0
  17. data/doc/plugins/derivation_endpoint.md +39 -1
  18. data/doc/plugins/derivatives.md +13 -2
  19. data/doc/plugins/download_endpoint.md +16 -4
  20. data/doc/plugins/dynamic_storage.md +15 -0
  21. data/doc/plugins/fallback_storage.md +90 -0
  22. data/doc/plugins/keep_files.md +6 -4
  23. data/doc/plugins/rack_response.md +9 -0
  24. data/doc/plugins/refresh_metadata.md +20 -0
  25. data/doc/plugins/sequel.md +57 -0
  26. data/doc/plugins/signature.md +8 -6
  27. data/doc/plugins/tempfile.md +14 -6
  28. data/doc/plugins/upload_options.md +12 -0
  29. data/doc/plugins/url_options.md +12 -0
  30. data/doc/plugins/validation_helpers.md +1 -1
  31. data/doc/processing.md +5 -3
  32. data/doc/refile.md +3 -3
  33. data/doc/release_notes/2.1.0.md +1 -1
  34. data/doc/release_notes/3.10.0.md +30 -0
  35. data/doc/release_notes/3.5.0.md +63 -0
  36. data/doc/release_notes/3.6.0.md +23 -0
  37. data/doc/release_notes/3.7.0.md +75 -0
  38. data/doc/release_notes/3.7.1.md +31 -0
  39. data/doc/release_notes/3.8.0.md +37 -0
  40. data/doc/release_notes/3.9.0.md +42 -0
  41. data/doc/retrieving_uploads.md +1 -1
  42. data/doc/storage/s3.md +10 -0
  43. data/doc/testing.md +45 -17
  44. data/doc/upgrading_to_3.md +3 -5
  45. data/lib/shrine/attacher.rb +41 -29
  46. data/lib/shrine/attachment.rb +2 -2
  47. data/lib/shrine/plugins/_persistence.rb +1 -1
  48. data/lib/shrine/plugins/_urlsafe_serialization.rb +4 -4
  49. data/lib/shrine/plugins/activerecord.rb +25 -4
  50. data/lib/shrine/plugins/add_metadata.rb +2 -4
  51. data/lib/shrine/plugins/atomic_helpers.rb +7 -7
  52. data/lib/shrine/plugins/backgrounding.rb +10 -10
  53. data/lib/shrine/plugins/column.rb +7 -5
  54. data/lib/shrine/plugins/data_uri.rb +28 -3
  55. data/lib/shrine/plugins/default_url.rb +4 -4
  56. data/lib/shrine/plugins/delete_raw.rb +2 -2
  57. data/lib/shrine/plugins/derivation_endpoint.rb +65 -59
  58. data/lib/shrine/plugins/derivatives.rb +35 -21
  59. data/lib/shrine/plugins/download_endpoint.rb +72 -11
  60. data/lib/shrine/plugins/entity.rb +15 -9
  61. data/lib/shrine/plugins/fallback_storage.rb +51 -0
  62. data/lib/shrine/plugins/infer_extension.rb +5 -1
  63. data/lib/shrine/plugins/instrumentation.rb +13 -9
  64. data/lib/shrine/plugins/metadata_attributes.rb +1 -1
  65. data/lib/shrine/plugins/mirroring.rb +10 -10
  66. data/lib/shrine/plugins/model.rb +12 -10
  67. data/lib/shrine/plugins/presign_endpoint.rb +13 -10
  68. data/lib/shrine/plugins/pretty_location.rb +2 -2
  69. data/lib/shrine/plugins/processing.rb +3 -3
  70. data/lib/shrine/plugins/rack_file.rb +2 -2
  71. data/lib/shrine/plugins/rack_response.rb +12 -6
  72. data/lib/shrine/plugins/refresh_metadata.rb +6 -6
  73. data/lib/shrine/plugins/remote_url.rb +4 -4
  74. data/lib/shrine/plugins/remove_attachment.rb +2 -0
  75. data/lib/shrine/plugins/remove_invalid.rb +4 -0
  76. data/lib/shrine/plugins/restore_cached_data.rb +3 -3
  77. data/lib/shrine/plugins/sequel.rb +15 -1
  78. data/lib/shrine/plugins/signature.rb +2 -2
  79. data/lib/shrine/plugins/store_dimensions.rb +2 -2
  80. data/lib/shrine/plugins/tempfile.rb +0 -2
  81. data/lib/shrine/plugins/upload_endpoint.rb +7 -5
  82. data/lib/shrine/plugins/upload_options.rb +18 -4
  83. data/lib/shrine/plugins/url_options.rb +17 -3
  84. data/lib/shrine/plugins/validation.rb +8 -8
  85. data/lib/shrine/plugins/validation_helpers.rb +2 -2
  86. data/lib/shrine/plugins/versions.rb +10 -10
  87. data/lib/shrine/plugins.rb +6 -14
  88. data/lib/shrine/storage/file_system.rb +15 -19
  89. data/lib/shrine/storage/linter.rb +8 -8
  90. data/lib/shrine/storage/memory.rb +1 -3
  91. data/lib/shrine/storage/s3.rb +60 -40
  92. data/lib/shrine/uploaded_file.rb +23 -19
  93. data/lib/shrine/version.rb +1 -1
  94. data/lib/shrine.rb +24 -20
  95. data/shrine.gemspec +10 -8
  96. metadata +52 -26
@@ -22,6 +22,8 @@ class Shrine
22
22
  end
23
23
 
24
24
  module InstanceMethods
25
+ RFC2396_PARSER = URI::RFC2396_Parser.new
26
+
25
27
  # The location where the file was uploaded to the storage.
26
28
  attr_reader :id
27
29
 
@@ -50,8 +52,9 @@ class Shrine
50
52
  # The extension derived from #id if present, otherwise it's derived
51
53
  # from #original_filename.
52
54
  def extension
53
- result = File.extname(id)[1..-1] || File.extname(original_filename.to_s)[1..-1]
54
- result.sub!(/\?.+$/, "") if result && id =~ URI::regexp # strip query params for shrine-url
55
+ identifier = id =~ RFC2396_PARSER.make_regexp ? id.sub(/\?.+$/, "") : id # strip query params for shrine-url
56
+ result = File.extname(identifier)[1..-1]
57
+ result ||= File.extname(original_filename.to_s)[1..-1]
55
58
  result.downcase if result
56
59
  end
57
60
 
@@ -88,9 +91,9 @@ class Shrine
88
91
  # # or
89
92
  #
90
93
  # uploaded_file.open { |io| io.read } # the IO is automatically closed
91
- def open(**options)
94
+ def open(**)
92
95
  @io.close if @io
93
- @io = _open(**options)
96
+ @io = _open(**)
94
97
 
95
98
  return @io unless block_given?
96
99
 
@@ -117,9 +120,9 @@ class Shrine
117
120
  # # or
118
121
  #
119
122
  # uploaded_file.download { |tempfile| tempfile.read } # tempfile is deleted
120
- def download(**options)
123
+ def download(**)
121
124
  tempfile = Tempfile.new(["shrine", ".#{extension}"], binmode: true)
122
- stream(tempfile, **options)
125
+ stream(tempfile, **)
123
126
  tempfile.open
124
127
 
125
128
  block_given? ? yield(tempfile) : tempfile
@@ -138,19 +141,19 @@ class Shrine
138
141
  # uploaded_file.stream(StringIO.new)
139
142
  # # or
140
143
  # uploaded_file.stream("/path/to/destination")
141
- def stream(destination, **options)
144
+ def stream(destination, **)
142
145
  if opened?
143
146
  IO.copy_stream(io, destination)
144
147
  io.rewind
145
148
  else
146
- open(**options) { |io| IO.copy_stream(io, destination) }
149
+ open(**) { |io| IO.copy_stream(io, destination) }
147
150
  end
148
151
  end
149
152
 
150
153
  # Part of complying to the IO interface. It delegates to the internally
151
154
  # opened IO object.
152
- def read(*args)
153
- io.read(*args)
155
+ def read(*)
156
+ io.read(*)
154
157
  end
155
158
 
156
159
  # Part of complying to the IO interface. It delegates to the internally
@@ -169,6 +172,7 @@ class Shrine
169
172
  # opened IO object.
170
173
  def close
171
174
  io.close if opened?
175
+ @io = nil
172
176
  end
173
177
 
174
178
  # Returns whether the file has already been opened.
@@ -177,8 +181,8 @@ class Shrine
177
181
  end
178
182
 
179
183
  # Calls `#url` on the storage, forwarding any given URL options.
180
- def url(**options)
181
- storage.url(id, **options)
184
+ def url(**)
185
+ storage.url(id, **)
182
186
  end
183
187
 
184
188
  # Calls `#exists?` on the storage, which checks whether the file exists
@@ -188,8 +192,8 @@ class Shrine
188
192
  end
189
193
 
190
194
  # Uploads a new file to this file's location and returns it.
191
- def replace(io, **options)
192
- uploader.upload(io, **options, location: id)
195
+ def replace(io, **)
196
+ uploader.upload(io, **, location: id)
193
197
  end
194
198
 
195
199
  # Calls `#delete` on the storage, which deletes the file from the
@@ -205,12 +209,12 @@ class Shrine
205
209
 
206
210
  # Returns the data hash in the JSON format. Suitable for storing in a
207
211
  # database column or passing to a background job.
208
- def to_json(*args)
209
- data.to_json(*args)
212
+ def to_json(*)
213
+ data.to_json(*)
210
214
  end
211
215
 
212
216
  # Conform to ActiveSupport's JSON interface.
213
- def as_json(*args)
217
+ def as_json(*)
214
218
  data
215
219
  end
216
220
 
@@ -261,8 +265,8 @@ class Shrine
261
265
  @io ||= _open
262
266
  end
263
267
 
264
- def _open(**options)
265
- storage.open(id, **options)
268
+ def _open(**)
269
+ storage.open(id, **)
266
270
  end
267
271
  end
268
272
 
@@ -7,7 +7,7 @@ class Shrine
7
7
 
8
8
  module VERSION
9
9
  MAJOR = 3
10
- MINOR = 4
10
+ MINOR = 10
11
11
  TINY = 0
12
12
  PRE = nil
13
13
 
data/lib/shrine.rb CHANGED
@@ -28,6 +28,10 @@ class Shrine
28
28
  class FileNotFound < Error
29
29
  end
30
30
 
31
+ # Raised by Shrine.find_storage when the storage isn't registered.
32
+ class MissingStorage < Error
33
+ end
34
+
31
35
  @opts = {}
32
36
  @storages = {}
33
37
  @logger = Logger.new(STDOUT)
@@ -68,9 +72,9 @@ class Shrine
68
72
  #
69
73
  # Shrine.plugin MyPlugin
70
74
  # Shrine.plugin :my_plugin
71
- def plugin(plugin, *args, **kwargs, &block)
75
+ def plugin(plugin, ...)
72
76
  plugin = Plugins.load_plugin(plugin) if plugin.is_a?(Symbol)
73
- Plugins.load_dependencies(plugin, self, *args, **kwargs, &block)
77
+ Plugins.load_dependencies(plugin, self, ...)
74
78
  self.include(plugin::InstanceMethods) if defined?(plugin::InstanceMethods)
75
79
  self.extend(plugin::ClassMethods) if defined?(plugin::ClassMethods)
76
80
  self::UploadedFile.include(plugin::FileMethods) if defined?(plugin::FileMethods)
@@ -79,14 +83,14 @@ class Shrine
79
83
  self::Attachment.extend(plugin::AttachmentClassMethods) if defined?(plugin::AttachmentClassMethods)
80
84
  self::Attacher.include(plugin::AttacherMethods) if defined?(plugin::AttacherMethods)
81
85
  self::Attacher.extend(plugin::AttacherClassMethods) if defined?(plugin::AttacherClassMethods)
82
- Plugins.configure(plugin, self, *args, **kwargs, &block)
86
+ Plugins.configure(plugin, self, ...)
83
87
  plugin
84
88
  end
85
89
 
86
90
  # Retrieves the storage under the given identifier (can be a Symbol or
87
91
  # a String), raising Shrine::Error if the storage is missing.
88
92
  def find_storage(name)
89
- storages[name.to_sym] || storages[name.to_s] or fail Error, "storage #{name.inspect} isn't registered on #{self}"
93
+ storages[name.to_sym] || storages[name.to_s] or fail MissingStorage, "storage #{name.inspect} isn't registered on #{self}"
90
94
  end
91
95
 
92
96
  # Generates an instance of Shrine::Attachment to be included in the
@@ -95,8 +99,8 @@ class Shrine
95
99
  # class Photo
96
100
  # include Shrine::Attachment(:image) # creates a Shrine::Attachment object
97
101
  # end
98
- def Attachment(name, **args)
99
- self::Attachment.new(name, **args)
102
+ def Attachment(name, **)
103
+ self::Attachment.new(name, **)
100
104
  end
101
105
  alias attachment Attachment
102
106
  alias [] Attachment
@@ -104,8 +108,8 @@ class Shrine
104
108
  # Uploads the file to the specified storage. It delegates to `Shrine#upload`.
105
109
  #
106
110
  # Shrine.upload(io, :store) #=> #<Shrine::UploadedFile>
107
- def upload(io, storage, **options)
108
- new(storage).upload(io, **options)
111
+ def upload(io, storage, **)
112
+ new(storage).upload(io, **)
109
113
  end
110
114
 
111
115
  # Instantiates a Shrine::UploadedFile from a hash, and optionally
@@ -201,13 +205,13 @@ class Shrine
201
205
  # uploader.upload(io, metadata: { "foo" => "bar" }) # add metadata
202
206
  # uploader.upload(io, location: "path/to/file") # specify location
203
207
  # uploader.upload(io, upload_options: { acl: "public-read" }) # add upload options
204
- def upload(io, **options)
208
+ def upload(io, **)
205
209
  _enforce_io(io)
206
210
 
207
- metadata = get_metadata(io, **options)
208
- location = get_location(io, **options, metadata: metadata)
211
+ metadata = get_metadata(io, **)
212
+ location = get_location(io, **, metadata:)
209
213
 
210
- _upload(io, **options, location: location, metadata: metadata)
214
+ _upload(io, **, location:, metadata:)
211
215
 
212
216
  self.class::UploadedFile.new(
213
217
  id: location,
@@ -219,13 +223,13 @@ class Shrine
219
223
  # Generates a unique location for the uploaded file, preserving the
220
224
  # file extension. Can be overriden in uploaders for generating custom
221
225
  # location.
222
- def generate_location(io, metadata: {}, **options)
223
- basic_location(io, metadata: metadata)
226
+ def generate_location(io, metadata: {}, **)
227
+ basic_location(io, metadata:)
224
228
  end
225
229
 
226
230
  # Extracts filename, size and MIME type from the file, which is later
227
231
  # accessible through UploadedFile#metadata.
228
- def extract_metadata(io, **options)
232
+ def extract_metadata(io, **)
229
233
  {
230
234
  "filename" => extract_filename(io),
231
235
  "size" => extract_size(io),
@@ -252,7 +256,7 @@ class Shrine
252
256
  def extract_filename(io)
253
257
  if io.respond_to?(:original_filename)
254
258
  io.original_filename
255
- elsif io.respond_to?(:path)
259
+ elsif io.respond_to?(:path) && io.path
256
260
  File.basename(io.path)
257
261
  end
258
262
  end
@@ -281,11 +285,11 @@ class Shrine
281
285
 
282
286
  # If the IO object is a Shrine::UploadedFile, it simply copies over its
283
287
  # metadata, otherwise it calls #extract_metadata.
284
- def get_metadata(io, metadata: nil, **options)
288
+ def get_metadata(io, metadata: nil, **)
285
289
  if io.is_a?(UploadedFile) && metadata != true
286
290
  result = io.metadata.dup
287
291
  elsif metadata != false
288
- result = extract_metadata(io, **options)
292
+ result = extract_metadata(io, **)
289
293
  else
290
294
  result = {}
291
295
  end
@@ -296,8 +300,8 @@ class Shrine
296
300
 
297
301
  # Retrieves the location for the given IO and context. First it looks
298
302
  # for the `:location` option, otherwise it calls #generate_location.
299
- def get_location(io, location: nil, **options)
300
- location ||= generate_location(io, **options)
303
+ def get_location(io, location: nil, **)
304
+ location ||= generate_location(io, **)
301
305
  location or fail Error, "location generated for #{io.inspect} was nil"
302
306
  end
303
307
 
data/shrine.gemspec CHANGED
@@ -4,7 +4,7 @@ Gem::Specification.new do |gem|
4
4
  gem.name = "shrine"
5
5
  gem.version = Shrine.version
6
6
 
7
- gem.required_ruby_version = ">= 2.3"
7
+ gem.required_ruby_version = ">= 3.2"
8
8
 
9
9
  gem.summary = "Toolkit for file attachments in Ruby applications"
10
10
  gem.description = <<-END
@@ -36,15 +36,17 @@ direct uploads for fully asynchronous user experience.
36
36
  gem.add_dependency "down", "~> 5.1"
37
37
  gem.add_dependency "content_disposition", "~> 1.0"
38
38
 
39
+ gem.add_development_dependency "rdoc", "~> 8.0" unless RUBY_ENGINE == "jruby"
40
+
39
41
  # general testing helpers
40
42
  gem.add_development_dependency "rake", ">= 11.1"
41
- gem.add_development_dependency "minitest", "~> 5.8"
43
+ gem.add_development_dependency "minitest", "~> 6.0"
42
44
  gem.add_development_dependency "mocha", "~> 1.11"
43
45
 
44
46
  # for endpoint plugins
45
- gem.add_development_dependency "rack", "~> 2.0"
47
+ gem.add_development_dependency "rack", ">= 2", "< 4"
46
48
  gem.add_development_dependency "http-form_data", "~> 2.2"
47
- gem.add_development_dependency "rack-test_app"
49
+ gem.add_development_dependency "rack-test", "~> 2.1"
48
50
 
49
51
  # for determine_mime_type plugin
50
52
  gem.add_development_dependency "mimemagic", ">= 0.3.2"
@@ -57,7 +59,7 @@ direct uploads for fully asynchronous user experience.
57
59
 
58
60
  # for store_dimensions plugin
59
61
  gem.add_development_dependency "fastimage"
60
- gem.add_development_dependency "mini_magick", "~> 4.0" unless ENV["CI"]
62
+ gem.add_development_dependency "mini_magick", "~> 5.0" unless ENV["CI"]
61
63
  gem.add_development_dependency "ruby-vips", "~> 2.0" unless ENV["CI"]
62
64
 
63
65
  # for S3 storage
@@ -67,10 +69,10 @@ direct uploads for fully asynchronous user experience.
67
69
 
68
70
  # for instrumentation plugin
69
71
  gem.add_development_dependency "dry-monitor"
70
- gem.add_development_dependency "activesupport", RUBY_VERSION >= "2.5" ? "~> 6.0" : "~> 5.2"
72
+ gem.add_development_dependency "activesupport", RUBY_ENGINE == "jruby" ? "~> 8.0.0" : "~> 8.1"
71
73
 
72
74
  # for ORM plugins
73
75
  gem.add_development_dependency "sequel"
74
- gem.add_development_dependency "activerecord", RUBY_VERSION >= "2.5" ? "~> 6.0" : "~> 5.2"
75
- gem.add_development_dependency "sqlite3", "~> 1.4" unless RUBY_ENGINE == "jruby"
76
+ gem.add_development_dependency "activerecord", RUBY_ENGINE == "jruby" ? "~> 8.0.0" : "~> 8.1"
77
+ gem.add_development_dependency "sqlite3", "~> 2.1" unless RUBY_ENGINE == "jruby"
76
78
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shrine
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.0
4
+ version: 3.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Janko Marohnić
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2021-06-14 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: down
@@ -38,6 +37,20 @@ dependencies:
38
37
  - - "~>"
39
38
  - !ruby/object:Gem::Version
40
39
  version: '1.0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rdoc
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '8.0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '8.0'
41
54
  - !ruby/object:Gem::Dependency
42
55
  name: rake
43
56
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +71,14 @@ dependencies:
58
71
  requirements:
59
72
  - - "~>"
60
73
  - !ruby/object:Gem::Version
61
- version: '5.8'
74
+ version: '6.0'
62
75
  type: :development
63
76
  prerelease: false
64
77
  version_requirements: !ruby/object:Gem::Requirement
65
78
  requirements:
66
79
  - - "~>"
67
80
  - !ruby/object:Gem::Version
68
- version: '5.8'
81
+ version: '6.0'
69
82
  - !ruby/object:Gem::Dependency
70
83
  name: mocha
71
84
  requirement: !ruby/object:Gem::Requirement
@@ -84,16 +97,22 @@ dependencies:
84
97
  name: rack
85
98
  requirement: !ruby/object:Gem::Requirement
86
99
  requirements:
87
- - - "~>"
100
+ - - ">="
88
101
  - !ruby/object:Gem::Version
89
- version: '2.0'
102
+ version: '2'
103
+ - - "<"
104
+ - !ruby/object:Gem::Version
105
+ version: '4'
90
106
  type: :development
91
107
  prerelease: false
92
108
  version_requirements: !ruby/object:Gem::Requirement
93
109
  requirements:
94
- - - "~>"
110
+ - - ">="
95
111
  - !ruby/object:Gem::Version
96
- version: '2.0'
112
+ version: '2'
113
+ - - "<"
114
+ - !ruby/object:Gem::Version
115
+ version: '4'
97
116
  - !ruby/object:Gem::Dependency
98
117
  name: http-form_data
99
118
  requirement: !ruby/object:Gem::Requirement
@@ -109,19 +128,19 @@ dependencies:
109
128
  - !ruby/object:Gem::Version
110
129
  version: '2.2'
111
130
  - !ruby/object:Gem::Dependency
112
- name: rack-test_app
131
+ name: rack-test
113
132
  requirement: !ruby/object:Gem::Requirement
114
133
  requirements:
115
- - - ">="
134
+ - - "~>"
116
135
  - !ruby/object:Gem::Version
117
- version: '0'
136
+ version: '2.1'
118
137
  type: :development
119
138
  prerelease: false
120
139
  version_requirements: !ruby/object:Gem::Requirement
121
140
  requirements:
122
- - - ">="
141
+ - - "~>"
123
142
  - !ruby/object:Gem::Version
124
- version: '0'
143
+ version: '2.1'
125
144
  - !ruby/object:Gem::Dependency
126
145
  name: mimemagic
127
146
  requirement: !ruby/object:Gem::Requirement
@@ -212,14 +231,14 @@ dependencies:
212
231
  requirements:
213
232
  - - "~>"
214
233
  - !ruby/object:Gem::Version
215
- version: '4.0'
234
+ version: '5.0'
216
235
  type: :development
217
236
  prerelease: false
218
237
  version_requirements: !ruby/object:Gem::Requirement
219
238
  requirements:
220
239
  - - "~>"
221
240
  - !ruby/object:Gem::Version
222
- version: '4.0'
241
+ version: '5.0'
223
242
  - !ruby/object:Gem::Dependency
224
243
  name: ruby-vips
225
244
  requirement: !ruby/object:Gem::Requirement
@@ -296,14 +315,14 @@ dependencies:
296
315
  requirements:
297
316
  - - "~>"
298
317
  - !ruby/object:Gem::Version
299
- version: '6.0'
318
+ version: '8.1'
300
319
  type: :development
301
320
  prerelease: false
302
321
  version_requirements: !ruby/object:Gem::Requirement
303
322
  requirements:
304
323
  - - "~>"
305
324
  - !ruby/object:Gem::Version
306
- version: '6.0'
325
+ version: '8.1'
307
326
  - !ruby/object:Gem::Dependency
308
327
  name: sequel
309
328
  requirement: !ruby/object:Gem::Requirement
@@ -324,28 +343,28 @@ dependencies:
324
343
  requirements:
325
344
  - - "~>"
326
345
  - !ruby/object:Gem::Version
327
- version: '6.0'
346
+ version: '8.1'
328
347
  type: :development
329
348
  prerelease: false
330
349
  version_requirements: !ruby/object:Gem::Requirement
331
350
  requirements:
332
351
  - - "~>"
333
352
  - !ruby/object:Gem::Version
334
- version: '6.0'
353
+ version: '8.1'
335
354
  - !ruby/object:Gem::Dependency
336
355
  name: sqlite3
337
356
  requirement: !ruby/object:Gem::Requirement
338
357
  requirements:
339
358
  - - "~>"
340
359
  - !ruby/object:Gem::Version
341
- version: '1.4'
360
+ version: '2.1'
342
361
  type: :development
343
362
  prerelease: false
344
363
  version_requirements: !ruby/object:Gem::Requirement
345
364
  requirements:
346
365
  - - "~>"
347
366
  - !ruby/object:Gem::Version
348
- version: '1.4'
367
+ version: '2.1'
349
368
  description: |
350
369
  Shrine is a toolkit for file attachments in Ruby applications. It supports
351
370
  uploading, downloading, processing and deleting IO objects, backed by various
@@ -398,6 +417,7 @@ files:
398
417
  - doc/plugins/download_endpoint.md
399
418
  - doc/plugins/dynamic_storage.md
400
419
  - doc/plugins/entity.md
420
+ - doc/plugins/fallback_storage.md
401
421
  - doc/plugins/form_assign.md
402
422
  - doc/plugins/included.md
403
423
  - doc/plugins/infer_extension.md
@@ -469,11 +489,18 @@ files:
469
489
  - doc/release_notes/3.0.0.md
470
490
  - doc/release_notes/3.0.1.md
471
491
  - doc/release_notes/3.1.0.md
492
+ - doc/release_notes/3.10.0.md
472
493
  - doc/release_notes/3.2.0.md
473
494
  - doc/release_notes/3.2.1.md
474
495
  - doc/release_notes/3.2.2.md
475
496
  - doc/release_notes/3.3.0.md
476
497
  - doc/release_notes/3.4.0.md
498
+ - doc/release_notes/3.5.0.md
499
+ - doc/release_notes/3.6.0.md
500
+ - doc/release_notes/3.7.0.md
501
+ - doc/release_notes/3.7.1.md
502
+ - doc/release_notes/3.8.0.md
503
+ - doc/release_notes/3.9.0.md
477
504
  - doc/retrieving_uploads.md
478
505
  - doc/securing_uploads.md
479
506
  - doc/storage/file_system.md
@@ -505,6 +532,7 @@ files:
505
532
  - lib/shrine/plugins/download_endpoint.rb
506
533
  - lib/shrine/plugins/dynamic_storage.rb
507
534
  - lib/shrine/plugins/entity.rb
535
+ - lib/shrine/plugins/fallback_storage.rb
508
536
  - lib/shrine/plugins/form_assign.rb
509
537
  - lib/shrine/plugins/included.rb
510
538
  - lib/shrine/plugins/infer_extension.rb
@@ -553,7 +581,6 @@ metadata:
553
581
  documentation_uri: https://shrinerb.com
554
582
  mailing_list_uri: https://discourse.shrinerb.com
555
583
  source_code_uri: https://github.com/shrinerb/shrine
556
- post_install_message:
557
584
  rdoc_options: []
558
585
  require_paths:
559
586
  - lib
@@ -561,15 +588,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
561
588
  requirements:
562
589
  - - ">="
563
590
  - !ruby/object:Gem::Version
564
- version: '2.3'
591
+ version: '3.2'
565
592
  required_rubygems_version: !ruby/object:Gem::Requirement
566
593
  requirements:
567
594
  - - ">="
568
595
  - !ruby/object:Gem::Version
569
596
  version: '0'
570
597
  requirements: []
571
- rubygems_version: 3.2.15
572
- signing_key:
598
+ rubygems_version: 4.0.13
573
599
  specification_version: 4
574
600
  summary: Toolkit for file attachments in Ruby applications
575
601
  test_files: []