activestorage 8.0.2.1 → 8.1.0.beta1

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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -54
  3. data/README.md +6 -3
  4. data/app/assets/javascripts/activestorage.esm.js +37 -1
  5. data/app/assets/javascripts/activestorage.js +37 -1
  6. data/app/controllers/active_storage/disk_controller.rb +2 -2
  7. data/app/javascript/activestorage/direct_upload_controller.js +48 -1
  8. data/app/models/active_storage/blob/representable.rb +66 -0
  9. data/app/models/active_storage/blob.rb +1 -1
  10. data/app/models/active_storage/filename.rb +1 -0
  11. data/app/models/active_storage/variant.rb +7 -7
  12. data/app/models/active_storage/variation.rb +1 -1
  13. data/lib/active_storage/analyzer/image_analyzer/image_magick.rb +7 -11
  14. data/lib/active_storage/analyzer/image_analyzer/vips.rb +10 -11
  15. data/lib/active_storage/analyzer/image_analyzer.rb +5 -0
  16. data/lib/active_storage/attached/model.rb +4 -4
  17. data/lib/active_storage/attached.rb +0 -1
  18. data/lib/active_storage/downloader.rb +1 -1
  19. data/lib/active_storage/engine.rb +48 -10
  20. data/lib/active_storage/fixture_set.rb +1 -1
  21. data/lib/active_storage/gem_version.rb +3 -3
  22. data/lib/active_storage/service/configurator.rb +6 -0
  23. data/lib/active_storage/service/disk_service.rb +1 -1
  24. data/lib/active_storage/service/gcs_service.rb +10 -2
  25. data/lib/active_storage/service/mirror_service.rb +1 -1
  26. data/lib/active_storage/service/registry.rb +6 -0
  27. data/lib/active_storage/service/s3_service.rb +19 -4
  28. data/lib/active_storage/service.rb +4 -1
  29. data/lib/active_storage/transformers/image_magick.rb +72 -0
  30. data/lib/active_storage/transformers/image_processing_transformer.rb +5 -67
  31. data/lib/active_storage/transformers/vips.rb +11 -0
  32. data/lib/active_storage.rb +13 -0
  33. metadata +14 -13
  34. data/lib/active_storage/service/azure_storage_service.rb +0 -201
@@ -12,8 +12,6 @@ require "active_storage/previewer/mupdf_previewer"
12
12
  require "active_storage/previewer/video_previewer"
13
13
 
14
14
  require "active_storage/analyzer/image_analyzer"
15
- require "active_storage/analyzer/image_analyzer/image_magick"
16
- require "active_storage/analyzer/image_analyzer/vips"
17
15
  require "active_storage/analyzer/video_analyzer"
18
16
  require "active_storage/analyzer/audio_analyzer"
19
17
 
@@ -27,7 +25,7 @@ module ActiveStorage
27
25
 
28
26
  config.active_storage = ActiveSupport::OrderedOptions.new
29
27
  config.active_storage.previewers = [ ActiveStorage::Previewer::PopplerPDFPreviewer, ActiveStorage::Previewer::MuPDFPreviewer, ActiveStorage::Previewer::VideoPreviewer ]
30
- config.active_storage.analyzers = [ ActiveStorage::Analyzer::ImageAnalyzer::Vips, ActiveStorage::Analyzer::ImageAnalyzer::ImageMagick, ActiveStorage::Analyzer::VideoAnalyzer, ActiveStorage::Analyzer::AudioAnalyzer ]
28
+ config.active_storage.analyzers = [ ActiveStorage::Analyzer::VideoAnalyzer, ActiveStorage::Analyzer::AudioAnalyzer ]
31
29
  config.active_storage.paths = ActiveSupport::OrderedOptions.new
32
30
  config.active_storage.queues = ActiveSupport::InheritableOptions.new
33
31
  config.active_storage.precompile_assets = true
@@ -84,11 +82,49 @@ module ActiveStorage
84
82
  end
85
83
 
86
84
  initializer "active_storage.configs" do
85
+ config.before_initialize do |app|
86
+ ActiveStorage.touch_attachment_records = app.config.active_storage.touch_attachment_records != false
87
+ end
88
+
87
89
  config.after_initialize do |app|
88
90
  ActiveStorage.logger = app.config.active_storage.logger || Rails.logger
89
- ActiveStorage.variant_processor = app.config.active_storage.variant_processor || :mini_magick
91
+ ActiveStorage.variant_processor = app.config.active_storage.variant_processor
90
92
  ActiveStorage.previewers = app.config.active_storage.previewers || []
91
- ActiveStorage.analyzers = app.config.active_storage.analyzers || []
93
+
94
+ begin
95
+ analyzer, transformer =
96
+ case ActiveStorage.variant_processor
97
+ when :vips
98
+ [
99
+ ActiveStorage::Analyzer::ImageAnalyzer::Vips,
100
+ ActiveStorage::Transformers::Vips
101
+ ]
102
+ when :mini_magick
103
+ [
104
+ ActiveStorage::Analyzer::ImageAnalyzer::ImageMagick,
105
+ ActiveStorage::Transformers::ImageMagick
106
+ ]
107
+ end
108
+
109
+ ActiveStorage.analyzers = [analyzer].compact.concat(app.config.active_storage.analyzers || [])
110
+ ActiveStorage.variant_transformer = transformer
111
+ rescue LoadError => error
112
+ case error.message
113
+ when /libvips/
114
+ ActiveStorage.logger.warn <<~WARNING.squish
115
+ Using vips to process variants requires the libvips library.
116
+ Please install libvips using the instructions on the libvips website.
117
+ WARNING
118
+ when /image_processing/
119
+ ActiveStorage.logger.warn <<~WARNING.squish
120
+ Generating image variants require the image_processing gem.
121
+ Please add `gem 'image_processing', '~> 1.2'` to your Gemfile.
122
+ WARNING
123
+ else
124
+ raise
125
+ end
126
+ end
127
+
92
128
  ActiveStorage.paths = app.config.active_storage.paths || {}
93
129
  ActiveStorage.routes_prefix = app.config.active_storage.routes_prefix || "/rails/active_storage"
94
130
  ActiveStorage.draw_routes = app.config.active_storage.draw_routes != false
@@ -112,13 +148,15 @@ module ActiveStorage
112
148
  ActiveStorage.variable_content_types = app.config.active_storage.variable_content_types || []
113
149
  ActiveStorage.web_image_content_types = app.config.active_storage.web_image_content_types || []
114
150
  ActiveStorage.content_types_to_serve_as_binary = app.config.active_storage.content_types_to_serve_as_binary || []
115
- ActiveStorage.touch_attachment_records = app.config.active_storage.touch_attachment_records != false
116
151
  ActiveStorage.service_urls_expire_in = app.config.active_storage.service_urls_expire_in || 5.minutes
117
152
  ActiveStorage.urls_expire_in = app.config.active_storage.urls_expire_in
118
153
  ActiveStorage.content_types_allowed_inline = app.config.active_storage.content_types_allowed_inline || []
119
154
  ActiveStorage.binary_content_type = app.config.active_storage.binary_content_type || "application/octet-stream"
120
155
  ActiveStorage.video_preview_arguments = app.config.active_storage.video_preview_arguments || "-y -vframes 1 -f image2"
121
156
  ActiveStorage.track_variants = app.config.active_storage.track_variants || false
157
+ if app.config.active_storage.checksum_implementation
158
+ ActiveStorage.checksum_implementation = app.config.active_storage.checksum_implementation
159
+ end
122
160
  end
123
161
  end
124
162
 
@@ -136,9 +174,9 @@ module ActiveStorage
136
174
  end
137
175
  end
138
176
 
139
- initializer "active_storage.services" do
177
+ initializer "active_storage.services" do |app|
140
178
  ActiveSupport.on_load(:active_storage_blob) do
141
- configs = Rails.configuration.active_storage.service_configurations ||=
179
+ configs = app.config.active_storage.service_configurations ||=
142
180
  begin
143
181
  config_file = Rails.root.join("config/storage/#{Rails.env}.yml")
144
182
  config_file = Rails.root.join("config/storage.yml") unless config_file.exist?
@@ -149,7 +187,7 @@ module ActiveStorage
149
187
 
150
188
  ActiveStorage::Blob.services = ActiveStorage::Service::Registry.new(configs)
151
189
 
152
- if config_choice = Rails.configuration.active_storage.service
190
+ if config_choice = app.config.active_storage.service
153
191
  ActiveStorage::Blob.service = ActiveStorage::Blob.services.fetch(config_choice)
154
192
  end
155
193
  end
@@ -171,7 +209,7 @@ module ActiveStorage
171
209
  initializer "action_view.configuration" do
172
210
  config.after_initialize do |app|
173
211
  ActiveSupport.on_load(:action_view) do
174
- multiple_file_field_include_hidden = app.config.active_storage.delete(:multiple_file_field_include_hidden)
212
+ multiple_file_field_include_hidden = app.config.active_storage.multiple_file_field_include_hidden
175
213
 
176
214
  unless multiple_file_field_include_hidden.nil?
177
215
  ActionView::Helpers::FormHelper.multiple_file_field_include_hidden = multiple_file_field_include_hidden
@@ -50,7 +50,7 @@ module ActiveStorage
50
50
  # by ActiveSupport::Testing::FileFixtures.file_fixture, and upload
51
51
  # the file to the Service
52
52
  #
53
- # === Examples
53
+ # ==== Examples
54
54
  #
55
55
  # # tests/fixtures/active_storage/blobs.yml
56
56
  # second_thumbnail_blob: <%= ActiveStorage::FixtureSet.blob(
@@ -8,9 +8,9 @@ module ActiveStorage
8
8
 
9
9
  module VERSION
10
10
  MAJOR = 8
11
- MINOR = 0
12
- TINY = 2
13
- PRE = "1"
11
+ MINOR = 1
12
+ TINY = 0
13
+ PRE = "beta1"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -19,6 +19,12 @@ module ActiveStorage
19
19
  )
20
20
  end
21
21
 
22
+ def inspect # :nodoc:
23
+ attrs = configurations.any? ?
24
+ " configurations=[#{configurations.keys.map(&:inspect).join(", ")}]" : ""
25
+ "#<#{self.class}#{attrs}>"
26
+ end
27
+
22
28
  private
23
29
  def config_for(name)
24
30
  configurations.fetch name do
@@ -161,7 +161,7 @@ module ActiveStorage
161
161
  end
162
162
 
163
163
  def ensure_integrity_of(key, checksum)
164
- unless OpenSSL::Digest::MD5.file(path_for(key)).base64digest == checksum
164
+ unless ActiveStorage.checksum_implementation.file(path_for(key)).base64digest == checksum
165
165
  delete key
166
166
  raise ActiveStorage::IntegrityError
167
167
  end
@@ -213,8 +213,16 @@ module ActiveStorage
213
213
  lambda do |string_to_sign|
214
214
  iam_client = Google::Apis::IamcredentialsV1::IAMCredentialsService.new
215
215
 
216
- scopes = ["https://www.googleapis.com/auth/iam"]
217
- iam_client.authorization = Google::Auth.get_application_default(scopes)
216
+ # We explicitly do not set iam_client.authorization so that it uses the
217
+ # credentials set by the application at Google::Apis::RequestOptions.default.authorization.
218
+ # If the application does not set it, the GCP libraries will automatically
219
+ # determine it on each call. This code previously explicitly set the
220
+ # authorization to Google::Auth.get_application_default which triggers
221
+ # an explicit call to the metadata server - given this lambda is called
222
+ # for a significant number of file operations, it can lead to considerable
223
+ # tail latencies and even metadata server overloads. Additionally, that
224
+ # prevented applications from being able to configure the credentials
225
+ # used to perform the signature operation.
218
226
 
219
227
  request = Google::Apis::IamcredentialsV1::SignBlobRequest.new(
220
228
  payload: string_to_sign
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/module/delegation"
4
3
 
5
4
  module ActiveStorage
6
5
  # = Active Storage Mirror \Service
@@ -31,6 +30,7 @@ module ActiveStorage
31
30
  def initialize(primary:, mirrors:)
32
31
  @primary, @mirrors = primary, mirrors
33
32
  @executor = Concurrent::ThreadPoolExecutor.new(
33
+ name: "ActiveStorage-mirror-service",
34
34
  min_threads: 1,
35
35
  max_threads: mirrors.size,
36
36
  max_queue: 0,
@@ -22,6 +22,12 @@ module ActiveStorage
22
22
  end
23
23
  end
24
24
 
25
+ def inspect # :nodoc:
26
+ attrs = configurations.any? ?
27
+ " configurations=[#{configurations.keys.map(&:inspect).join(", ")}]" : ""
28
+ "#<#{self.class}#{attrs}>"
29
+ end
30
+
25
31
  private
26
32
  attr_reader :configurations, :services
27
33
 
@@ -16,6 +16,7 @@ module ActiveStorage
16
16
 
17
17
  def initialize(bucket:, upload: {}, public: false, **options)
18
18
  @client = Aws::S3::Resource.new(**options)
19
+ @transfer_manager = Aws::S3::TransferManager.new(client: @client.client) if defined?(Aws::S3::TransferManager)
19
20
  @bucket = @client.bucket(bucket)
20
21
 
21
22
  @multipart_upload_threshold = upload.delete(:multipart_threshold) || 100.megabytes
@@ -100,7 +101,8 @@ module ActiveStorage
100
101
  def compose(source_keys, destination_key, filename: nil, content_type: nil, disposition: nil, custom_metadata: {})
101
102
  content_disposition = content_disposition_with(type: disposition, filename: filename) if disposition && filename
102
103
 
103
- object_for(destination_key).upload_stream(
104
+ upload_stream(
105
+ key: destination_key,
104
106
  content_type: content_type,
105
107
  content_disposition: content_disposition,
106
108
  part_size: MINIMUM_UPLOAD_PART_SIZE,
@@ -116,6 +118,14 @@ module ActiveStorage
116
118
  end
117
119
 
118
120
  private
121
+ def upload_stream(key:, **options, &block)
122
+ if @transfer_manager
123
+ @transfer_manager.upload_stream(key: key, bucket: bucket.name, **options, &block)
124
+ else
125
+ object_for(key).upload_stream(**options, &block)
126
+ end
127
+ end
128
+
119
129
  def private_url(key, expires_in:, filename:, disposition:, content_type:, **client_opts)
120
130
  object_for(key).presigned_url :get, expires_in: expires_in.to_i,
121
131
  response_content_disposition: content_disposition_with(type: disposition, filename: filename),
@@ -126,7 +136,6 @@ module ActiveStorage
126
136
  object_for(key).public_url(**client_opts)
127
137
  end
128
138
 
129
-
130
139
  MAXIMUM_UPLOAD_PARTS_COUNT = 10000
131
140
  MINIMUM_UPLOAD_PART_SIZE = 5.megabytes
132
141
 
@@ -139,12 +148,18 @@ module ActiveStorage
139
148
  def upload_with_multipart(key, io, content_type: nil, content_disposition: nil, custom_metadata: {})
140
149
  part_size = [ io.size.fdiv(MAXIMUM_UPLOAD_PARTS_COUNT).ceil, MINIMUM_UPLOAD_PART_SIZE ].max
141
150
 
142
- object_for(key).upload_stream(content_type: content_type, content_disposition: content_disposition, part_size: part_size, metadata: custom_metadata, **upload_options) do |out|
151
+ upload_stream(
152
+ key: key,
153
+ content_type: content_type,
154
+ content_disposition: content_disposition,
155
+ part_size: part_size,
156
+ metadata: custom_metadata,
157
+ **upload_options
158
+ ) do |out|
143
159
  IO.copy_stream(io, out)
144
160
  end
145
161
  end
146
162
 
147
-
148
163
  def object_for(key)
149
164
  bucket.object(key)
150
165
  end
@@ -15,7 +15,6 @@ module ActiveStorage
15
15
  # * +Disk+, to manage attachments saved directly on the hard drive.
16
16
  # * +GCS+, to manage attachments through Google Cloud Storage.
17
17
  # * +S3+, to manage attachments through Amazon S3.
18
- # * +AzureStorage+, to manage attachments through Microsoft Azure Storage.
19
18
  # * +Mirror+, to be able to use several services to manage attachments.
20
19
  #
21
20
  # Inside a \Rails application, you can set-up your services through the
@@ -148,6 +147,10 @@ module ActiveStorage
148
147
  @public
149
148
  end
150
149
 
150
+ def inspect # :nodoc:
151
+ "#<#{self.class}#{name.present? ? " name=#{name.inspect}" : ""}>"
152
+ end
153
+
151
154
  private
152
155
  def private_url(key, expires_in:, filename:, disposition:, content_type:, **)
153
156
  raise NotImplementedError
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveStorage
4
+ module Transformers
5
+ class ImageMagick < ImageProcessingTransformer
6
+ private
7
+ def processor
8
+ ImageProcessing::MiniMagick
9
+ end
10
+
11
+ def validate_transformation(name, argument)
12
+ method_name = name.to_s.tr("-", "_")
13
+
14
+ unless ActiveStorage.supported_image_processing_methods.include?(method_name)
15
+ raise UnsupportedImageProcessingMethod, <<~ERROR.squish
16
+ The provided transformation method is not supported: #{method_name}.
17
+ ERROR
18
+ end
19
+
20
+ if argument.present?
21
+ if argument.is_a?(String) || argument.is_a?(Symbol)
22
+ validate_arg_string(argument)
23
+ elsif argument.is_a?(Array)
24
+ validate_arg_array(argument)
25
+ elsif argument.is_a?(Hash)
26
+ validate_arg_hash(argument)
27
+ end
28
+ end
29
+
30
+ super
31
+ end
32
+
33
+ def validate_arg_string(argument)
34
+ unsupported_arguments = ActiveStorage.unsupported_image_processing_arguments.any? do |bad_arg|
35
+ argument.to_s.downcase.include?(bad_arg)
36
+ end
37
+
38
+ raise UnsupportedImageProcessingArgument if unsupported_arguments
39
+ end
40
+
41
+ def validate_arg_array(argument)
42
+ argument.each do |arg|
43
+ if arg.is_a?(Integer) || arg.is_a?(Float)
44
+ next
45
+ elsif arg.is_a?(String) || arg.is_a?(Symbol)
46
+ validate_arg_string(arg)
47
+ elsif arg.is_a?(Array)
48
+ validate_arg_array(arg)
49
+ elsif arg.is_a?(Hash)
50
+ validate_arg_hash(arg)
51
+ end
52
+ end
53
+ end
54
+
55
+ def validate_arg_hash(argument)
56
+ argument.each do |key, value|
57
+ validate_arg_string(key)
58
+
59
+ if value.is_a?(Integer) || value.is_a?(Float)
60
+ next
61
+ elsif value.is_a?(String) || value.is_a?(Symbol)
62
+ validate_arg_string(value)
63
+ elsif value.is_a?(Array)
64
+ validate_arg_array(value)
65
+ elsif value.is_a?(Hash)
66
+ validate_arg_hash(value)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -25,22 +25,9 @@ module ActiveStorage
25
25
  call
26
26
  end
27
27
 
28
- def processor
29
- ImageProcessing.const_get(ActiveStorage.variant_processor.to_s.camelize)
30
- end
31
-
32
28
  def operations
33
29
  transformations.each_with_object([]) do |(name, argument), list|
34
- if ActiveStorage.variant_processor == :mini_magick
35
- validate_transformation(name, argument)
36
- end
37
-
38
- if name.to_s == "combine_options"
39
- raise ArgumentError, <<~ERROR.squish
40
- Active Storage's ImageProcessing transformer doesn't support :combine_options,
41
- as it always generates a single command.
42
- ERROR
43
- end
30
+ validate_transformation(name, argument)
44
31
 
45
32
  if argument.present?
46
33
  list << [ name, argument ]
@@ -49,61 +36,12 @@ module ActiveStorage
49
36
  end
50
37
 
51
38
  def validate_transformation(name, argument)
52
- method_name = name.to_s.tr("-", "_")
53
-
54
- unless ActiveStorage.supported_image_processing_methods.any? { |method| method_name == method }
55
- raise UnsupportedImageProcessingMethod, <<~ERROR.squish
56
- One or more of the provided transformation methods is not supported.
39
+ if name.to_s == "combine_options"
40
+ raise ArgumentError, <<~ERROR.squish
41
+ Active Storage's ImageProcessing transformer doesn't support :combine_options,
42
+ as it always generates a single command.
57
43
  ERROR
58
44
  end
59
-
60
- if argument.present?
61
- if argument.is_a?(String) || argument.is_a?(Symbol)
62
- validate_arg_string(argument)
63
- elsif argument.is_a?(Array)
64
- validate_arg_array(argument)
65
- elsif argument.is_a?(Hash)
66
- validate_arg_hash(argument)
67
- end
68
- end
69
- end
70
-
71
- def validate_arg_string(argument)
72
- unsupported_arguments = ActiveStorage.unsupported_image_processing_arguments.any? do |bad_arg|
73
- argument.to_s.downcase.include?(bad_arg)
74
- end
75
-
76
- raise UnsupportedImageProcessingArgument if unsupported_arguments
77
- end
78
-
79
- def validate_arg_array(argument)
80
- argument.each do |arg|
81
- if arg.is_a?(Integer) || arg.is_a?(Float)
82
- next
83
- elsif arg.is_a?(String) || arg.is_a?(Symbol)
84
- validate_arg_string(arg)
85
- elsif arg.is_a?(Array)
86
- validate_arg_array(arg)
87
- elsif arg.is_a?(Hash)
88
- validate_arg_hash(arg)
89
- end
90
- end
91
- end
92
-
93
- def validate_arg_hash(argument)
94
- argument.each do |key, value|
95
- validate_arg_string(key)
96
-
97
- if value.is_a?(Integer) || value.is_a?(Float)
98
- next
99
- elsif value.is_a?(String) || value.is_a?(Symbol)
100
- validate_arg_string(value)
101
- elsif value.is_a?(Array)
102
- validate_arg_array(value)
103
- elsif value.is_a?(Hash)
104
- validate_arg_hash(value)
105
- end
106
- end
107
45
  end
108
46
  end
109
47
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveStorage
4
+ module Transformers
5
+ class Vips < ImageProcessingTransformer
6
+ def processor
7
+ ImageProcessing::Vips
8
+ end
9
+ end
10
+ end
11
+ end
@@ -49,6 +49,8 @@ module ActiveStorage
49
49
  mattr_accessor :verifier
50
50
  mattr_accessor :variant_processor, default: :mini_magick
51
51
 
52
+ mattr_accessor :variant_transformer
53
+
52
54
  mattr_accessor :queues, default: {}
53
55
 
54
56
  mattr_accessor :previewers, default: []
@@ -360,6 +362,15 @@ module ActiveStorage
360
362
 
361
363
  mattr_accessor :track_variants, default: false
362
364
 
365
+ singleton_class.attr_accessor :checksum_implementation
366
+ @checksum_implementation = OpenSSL::Digest::MD5
367
+ begin
368
+ @checksum_implementation.hexdigest("test")
369
+ rescue # OpenSSL may have MD5 disabled
370
+ require "digest/md5"
371
+ @checksum_implementation = Digest::MD5
372
+ end
373
+
363
374
  mattr_accessor :video_preview_arguments, default: "-y -vframes 1 -f image2"
364
375
 
365
376
  module Transformers
@@ -367,5 +378,7 @@ module ActiveStorage
367
378
 
368
379
  autoload :Transformer
369
380
  autoload :ImageProcessingTransformer
381
+ autoload :Vips
382
+ autoload :ImageMagick
370
383
  end
371
384
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activestorage
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.0.2.1
4
+ version: 8.1.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
@@ -15,56 +15,56 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 8.0.2.1
18
+ version: 8.1.0.beta1
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 8.0.2.1
25
+ version: 8.1.0.beta1
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: actionpack
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - '='
31
31
  - !ruby/object:Gem::Version
32
- version: 8.0.2.1
32
+ version: 8.1.0.beta1
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - '='
38
38
  - !ruby/object:Gem::Version
39
- version: 8.0.2.1
39
+ version: 8.1.0.beta1
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: activejob
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - '='
45
45
  - !ruby/object:Gem::Version
46
- version: 8.0.2.1
46
+ version: 8.1.0.beta1
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - '='
52
52
  - !ruby/object:Gem::Version
53
- version: 8.0.2.1
53
+ version: 8.1.0.beta1
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: activerecord
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - '='
59
59
  - !ruby/object:Gem::Version
60
- version: 8.0.2.1
60
+ version: 8.1.0.beta1
61
61
  type: :runtime
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - '='
66
66
  - !ruby/object:Gem::Version
67
- version: 8.0.2.1
67
+ version: 8.1.0.beta1
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: marcel
70
70
  requirement: !ruby/object:Gem::Requirement
@@ -173,15 +173,16 @@ files:
173
173
  - lib/active_storage/previewer/video_previewer.rb
174
174
  - lib/active_storage/reflection.rb
175
175
  - lib/active_storage/service.rb
176
- - lib/active_storage/service/azure_storage_service.rb
177
176
  - lib/active_storage/service/configurator.rb
178
177
  - lib/active_storage/service/disk_service.rb
179
178
  - lib/active_storage/service/gcs_service.rb
180
179
  - lib/active_storage/service/mirror_service.rb
181
180
  - lib/active_storage/service/registry.rb
182
181
  - lib/active_storage/service/s3_service.rb
182
+ - lib/active_storage/transformers/image_magick.rb
183
183
  - lib/active_storage/transformers/image_processing_transformer.rb
184
184
  - lib/active_storage/transformers/transformer.rb
185
+ - lib/active_storage/transformers/vips.rb
185
186
  - lib/active_storage/version.rb
186
187
  - lib/tasks/activestorage.rake
187
188
  homepage: https://rubyonrails.org
@@ -189,10 +190,10 @@ licenses:
189
190
  - MIT
190
191
  metadata:
191
192
  bug_tracker_uri: https://github.com/rails/rails/issues
192
- changelog_uri: https://github.com/rails/rails/blob/v8.0.2.1/activestorage/CHANGELOG.md
193
- documentation_uri: https://api.rubyonrails.org/v8.0.2.1/
193
+ changelog_uri: https://github.com/rails/rails/blob/v8.1.0.beta1/activestorage/CHANGELOG.md
194
+ documentation_uri: https://api.rubyonrails.org/v8.1.0.beta1/
194
195
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
195
- source_code_uri: https://github.com/rails/rails/tree/v8.0.2.1/activestorage
196
+ source_code_uri: https://github.com/rails/rails/tree/v8.1.0.beta1/activestorage
196
197
  rubygems_mfa_required: 'true'
197
198
  rdoc_options: []
198
199
  require_paths: