activestorage 7.0.8.7 → 7.2.2.1

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +49 -390
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +6 -6
  5. data/app/assets/javascripts/activestorage.esm.js +11 -7
  6. data/app/assets/javascripts/activestorage.js +12 -6
  7. data/app/controllers/active_storage/disk_controller.rb +4 -2
  8. data/app/controllers/active_storage/representations/proxy_controller.rb +1 -1
  9. data/app/controllers/concerns/active_storage/file_server.rb +4 -1
  10. data/app/javascript/activestorage/blob_record.js +4 -1
  11. data/app/javascript/activestorage/direct_upload.js +3 -2
  12. data/app/javascript/activestorage/index.js +3 -1
  13. data/app/javascript/activestorage/ujs.js +3 -3
  14. data/app/jobs/active_storage/analyze_job.rb +1 -1
  15. data/app/jobs/active_storage/mirror_job.rb +1 -1
  16. data/app/jobs/active_storage/preview_image_job.rb +16 -0
  17. data/app/jobs/active_storage/purge_job.rb +1 -1
  18. data/app/jobs/active_storage/transform_job.rb +12 -0
  19. data/app/models/active_storage/attachment.rb +101 -16
  20. data/app/models/active_storage/blob/analyzable.rb +4 -3
  21. data/app/models/active_storage/blob/identifiable.rb +1 -0
  22. data/app/models/active_storage/blob/representable.rb +15 -3
  23. data/app/models/active_storage/blob/servable.rb +22 -0
  24. data/app/models/active_storage/blob.rb +59 -72
  25. data/app/models/active_storage/current.rb +0 -10
  26. data/app/models/active_storage/filename.rb +2 -4
  27. data/app/models/active_storage/named_variant.rb +21 -0
  28. data/app/models/active_storage/preview.rb +23 -8
  29. data/app/models/active_storage/variant.rb +10 -7
  30. data/app/models/active_storage/variant_record.rb +0 -2
  31. data/app/models/active_storage/variant_with_record.rb +21 -7
  32. data/app/models/active_storage/variation.rb +5 -3
  33. data/config/routes.rb +6 -4
  34. data/db/migrate/20170806125915_create_active_storage_tables.rb +2 -2
  35. data/lib/active_storage/analyzer/audio_analyzer.rb +16 -4
  36. data/lib/active_storage/analyzer/image_analyzer/vips.rb +5 -9
  37. data/lib/active_storage/analyzer/image_analyzer.rb +2 -0
  38. data/lib/active_storage/analyzer/video_analyzer.rb +9 -3
  39. data/lib/active_storage/analyzer.rb +2 -0
  40. data/lib/active_storage/attached/changes/create_many.rb +8 -3
  41. data/lib/active_storage/attached/changes/create_one.rb +51 -4
  42. data/lib/active_storage/attached/changes/create_one_of_many.rb +5 -1
  43. data/lib/active_storage/attached/many.rb +5 -4
  44. data/lib/active_storage/attached/model.rb +96 -60
  45. data/lib/active_storage/attached/one.rb +5 -4
  46. data/lib/active_storage/attached.rb +2 -0
  47. data/lib/active_storage/deprecator.rb +7 -0
  48. data/lib/active_storage/engine.rb +7 -9
  49. data/lib/active_storage/fixture_set.rb +7 -1
  50. data/lib/active_storage/gem_version.rb +4 -4
  51. data/lib/active_storage/log_subscriber.rb +12 -0
  52. data/lib/active_storage/previewer/mupdf_previewer.rb +6 -2
  53. data/lib/active_storage/previewer/poppler_pdf_previewer.rb +6 -2
  54. data/lib/active_storage/previewer/video_previewer.rb +1 -1
  55. data/lib/active_storage/previewer.rb +8 -1
  56. data/lib/active_storage/reflection.rb +3 -3
  57. data/lib/active_storage/service/azure_storage_service.rb +2 -0
  58. data/lib/active_storage/service/disk_service.rb +2 -0
  59. data/lib/active_storage/service/gcs_service.rb +11 -20
  60. data/lib/active_storage/service/mirror_service.rb +10 -5
  61. data/lib/active_storage/service/s3_service.rb +2 -0
  62. data/lib/active_storage/service.rb +4 -2
  63. data/lib/active_storage/transformers/image_processing_transformer.rb +1 -1
  64. data/lib/active_storage/transformers/transformer.rb +2 -0
  65. data/lib/active_storage/version.rb +1 -1
  66. data/lib/active_storage.rb +5 -4
  67. metadata +18 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 50bf70255abe1ec8cf3f32f475e5254b74b716ef51f1bcfc278e5a4223111e9b
4
- data.tar.gz: da4e1b0d79c79cad1487ae17881a86540ea34bd71baf70fd58d5ce2739ea905d
3
+ metadata.gz: 19f4fa25c348a39b38b18a049dd123c5a0c6f80d70e05cdfc4790c7e0dbf96d1
4
+ data.tar.gz: 48ba490e74129a1495ed0b3249730bfeba7b12f916e787849e7cfa4f81235bf9
5
5
  SHA512:
6
- metadata.gz: 508a95a72b3676706a199e0bc5c346f4641e879fc87f20cd199b9777f3d42570e7d1f12c5598786d278e82f1fce6436f60f377b41144b2137460f7b5db72e814
7
- data.tar.gz: 1c589a8d5e617d8a5a535a467465ced51ede3b547db515c622963cd37df9e42733f9276b4eaccbb1c7705439017ae7eb1434dc7995b8fd9c91da20f1d871e1ab
6
+ metadata.gz: 6656a5f10b464e63d86f0e4fc60984735e522d56789f93ce4f0d6ec4684b0b7e6a449f14af01a92e5929b1a4854f283b0bf89b37fe67ecb5d8cc207430b81c71
7
+ data.tar.gz: a8fe146a25f52b241de32978f344a2303ad5221f05306a57776337194ba67aa2691c715790131056dec44dfe21cb26b7df1fe33fef5d09efba3ff5f226b83e58
data/CHANGELOG.md CHANGED
@@ -1,444 +1,103 @@
1
- ## Rails 7.0.8.7 (December 10, 2024) ##
1
+ ## Rails 7.2.2.1 (December 10, 2024) ##
2
2
 
3
3
  * No changes.
4
4
 
5
5
 
6
- ## Rails 7.0.8.6 (October 23, 2024) ##
6
+ ## Rails 7.2.2 (October 30, 2024) ##
7
7
 
8
8
  * No changes.
9
9
 
10
10
 
11
- ## Rails 7.0.8.5 (October 15, 2024) ##
11
+ ## Rails 7.2.1.2 (October 23, 2024) ##
12
12
 
13
13
  * No changes.
14
14
 
15
15
 
16
- ## Rails 7.0.8.4 (June 04, 2024) ##
16
+ ## Rails 7.2.1.1 (October 15, 2024) ##
17
17
 
18
18
  * No changes.
19
19
 
20
20
 
21
- ## Rails 7.0.8.3 (May 17, 2024) ##
21
+ ## Rails 7.2.1 (August 22, 2024) ##
22
22
 
23
23
  * No changes.
24
24
 
25
25
 
26
- ## Rails 7.0.8.2 (May 16, 2024) ##
26
+ ## Rails 7.2.0 (August 09, 2024) ##
27
27
 
28
- * No changes.
29
-
30
-
31
- ## Rails 7.0.8.1 (February 21, 2024) ##
32
-
33
- * Disables the session in `ActiveStorage::Blobs::ProxyController`
34
- and `ActiveStorage::Representations::ProxyController`
35
- in order to allow caching by default in some CDNs as CloudFlare
36
-
37
- Fixes #44136
38
-
39
- *Bruno Prieto*
40
-
41
- ## Rails 7.0.8 (September 09, 2023) ##
42
-
43
- * No changes.
44
-
45
-
46
- ## Rails 7.0.7.2 (August 22, 2023) ##
47
-
48
- * No changes.
49
-
50
-
51
- ## Rails 7.0.7.1 (August 22, 2023) ##
52
-
53
- * No changes.
54
-
55
-
56
- ## Rails 7.0.7 (August 09, 2023) ##
57
-
58
- * No changes.
59
-
60
-
61
- ## Rails 7.0.6 (June 29, 2023) ##
62
-
63
- * Fix retrieving rotation value from FFmpeg on version 5.0+.
64
-
65
- In FFmpeg version 5.0+ the rotation value has been removed from tags.
66
- Instead the value can be found in side_data_list. Along with
67
- this update it's possible to have values of -90, -270 to denote the video
68
- has been rotated.
69
-
70
- *Haroon Ahmed*
71
-
72
-
73
- ## Rails 7.0.5.1 (June 26, 2023) ##
74
-
75
- * No changes.
76
-
77
-
78
- ## Rails 7.0.5 (May 24, 2023) ##
79
-
80
- * No changes.
81
-
82
-
83
- ## Rails 7.0.4.3 (March 13, 2023) ##
84
-
85
- * No changes.
86
-
87
-
88
- ## Rails 7.0.4.2 (January 24, 2023) ##
89
-
90
- * No changes.
91
-
92
-
93
- ## Rails 7.0.4.1 (January 17, 2023) ##
94
-
95
- * No changes.
96
-
97
-
98
- ## Rails 7.0.4 (September 09, 2022) ##
99
-
100
- * Fixes proxy downloads of files over 5MiB
101
-
102
- Previously, trying to view and/or download files larger than 5mb stored in
103
- services like S3 via proxy mode could return corrupted files at around
104
- 5.2mb or cause random halts in the download. Now,
105
- `ActiveStorage::Blobs::ProxyController` correctly handles streaming these
106
- larger files from the service to the client without any issues.
107
-
108
- Fixes #44679
109
-
110
- *Felipe Raul*
111
-
112
- ## Rails 7.0.3.1 (July 12, 2022) ##
113
-
114
- * No changes.
115
-
116
-
117
- ## Rails 7.0.3 (May 09, 2022) ##
118
-
119
- * Don't stream responses in redirect mode
120
-
121
- Previously, both redirect mode and proxy mode streamed their
122
- responses which caused a new thread to be created, and could end
123
- up leaking connections in the connection pool. But since redirect
124
- mode doesn't actually send any data, it doesn't need to be
125
- streamed.
126
-
127
- *Luke Lau*
128
-
129
- ## Rails 7.0.2.4 (April 26, 2022) ##
130
-
131
- * No changes.
132
-
133
-
134
- ## Rails 7.0.2.3 (March 08, 2022) ##
135
-
136
- * Added image transformation validation via configurable allow-list.
137
-
138
- Variant now offers a configurable allow-list for
139
- transformation methods in addition to a configurable deny-list for arguments.
140
-
141
- [CVE-2022-21831]
142
-
143
-
144
- ## Rails 7.0.2.2 (February 11, 2022) ##
145
-
146
- * No changes.
147
-
148
- ## Rails 7.0.2.1 (February 11, 2022) ##
149
-
150
- * No changes.
151
-
152
-
153
- ## Rails 7.0.2 (February 08, 2022) ##
154
-
155
- * Revert the ability to pass `service_name` param to `DirectUploadsController` which was introduced
156
- in 7.0.0.
157
-
158
- That change caused a lot of problems to upgrade Rails applications so we decided to remove it
159
- while in work in a more backwards compatible implementation.
160
-
161
- *Gannon McGibbon*
162
-
163
- * Allow applications to opt out of precompiling Active Storage JavaScript assets.
164
-
165
- *jlestavel*
166
-
167
-
168
- ## Rails 7.0.1 (January 06, 2022) ##
28
+ * Remove deprecated `config.active_storage.silence_invalid_content_types_warning`.
169
29
 
170
- * No changes.
171
-
172
-
173
- ## Rails 7.0.0 (December 15, 2021) ##
174
-
175
- * Support transforming empty-ish `has_many_attached` value into `[]` (e.g. `[""]`).
176
-
177
- ```ruby
178
- @user.highlights = [""]
179
- @user.highlights # => []
180
- ```
181
-
182
- *Sean Doyle*
183
-
184
-
185
- ## Rails 7.0.0.rc3 (December 14, 2021) ##
186
-
187
- * No changes.
188
-
189
-
190
- ## Rails 7.0.0.rc2 (December 14, 2021) ##
191
-
192
- * No changes.
193
-
194
- ## Rails 7.0.0.rc1 (December 06, 2021) ##
195
-
196
- * `Add ActiveStorage::Blob.compose` to concatenate multiple blobs.
197
-
198
- *Gannon McGibbon*
199
-
200
- * Setting custom metadata on blobs are now persisted to remote storage.
201
-
202
- *joshuamsager*
203
-
204
- * Support direct uploads to multiple services.
205
-
206
- *Dmitry Tsepelev*
207
-
208
- * Invalid default content types are deprecated
209
-
210
- Blobs created with content_type `image/jpg`, `image/pjpeg`, `image/bmp`, `text/javascript` will now produce
211
- a deprecation warning, since these are not valid content types.
212
-
213
- These content types will be removed from the defaults in Rails 7.1.
214
-
215
- You can set `config.active_storage.silence_invalid_content_types_warning = true` to dismiss the warning.
216
-
217
- *Alex Ghiculescu*
218
-
219
- ## Rails 7.0.0.alpha2 (September 15, 2021) ##
220
-
221
- * No changes.
222
-
223
-
224
- ## Rails 7.0.0.alpha1 (September 15, 2021) ##
225
-
226
- * Emit Active Support instrumentation events from Active Storage analyzers.
227
-
228
- Fixes #42930
229
-
230
- *Shouichi Kamiya*
231
-
232
- * Add support for byte range requests
233
-
234
- *Tom Prats*
235
-
236
- * Attachments can be deleted after their association is no longer defined.
237
-
238
- Fixes #42514
239
-
240
- *Don Sisco*
241
-
242
- * Make `vips` the default variant processor for new apps.
243
-
244
- See the upgrade guide for instructions on converting from `mini_magick` to `vips`. `mini_magick` is
245
- not deprecated, existing apps can keep using it.
246
-
247
- *Breno Gazzola*
30
+ *Rafael Mendonça França*
248
31
 
249
- * Deprecate `ActiveStorage::Current.host` in favor of `ActiveStorage::Current.url_options` which accepts
250
- a host, protocol and port.
32
+ * Remove deprecated `config.active_storage.replace_on_assign_to_many`.
251
33
 
252
- *Santiago Bartesaghi*
34
+ *Rafael Mendonça França*
253
35
 
254
- * Allow using [IAM](https://cloud.google.com/storage/docs/access-control/signed-urls) when signing URLs with GCS.
36
+ * Add support for custom `key` in `ActiveStorage::Blob#compose`.
255
37
 
256
- ```yaml
257
- gcs:
258
- service: GCS
259
- ...
260
- iam: true
261
- ```
38
+ *Elvin Efendiev*
262
39
 
263
- *RRethy*
40
+ * Add `image/webp` to `config.active_storage.web_image_content_types` when `load_defaults "7.2"`
41
+ is set.
264
42
 
265
- * OpenSSL constants are now used for Digest computations.
43
+ *Lewis Buckley*
266
44
 
267
- *Dirkjan Bussink*
45
+ * Fix JSON-encoding of `ActiveStorage::Filename` instances.
268
46
 
269
- * Deprecate `config.active_storage.replace_on_assign_to_many`. Future versions of Rails
270
- will behave the same way as when the config is set to `true`.
47
+ *Jonathan del Strother*
271
48
 
272
- *Santiago Bartesaghi*
49
+ * Fix N+1 query when fetching preview images for non-image assets.
273
50
 
274
- * Remove deprecated methods: `build_after_upload`, `create_after_upload!` in favor of `create_and_upload!`,
275
- and `service_url` in favor of `url`.
51
+ *Aaron Patterson & Justin Searls*
276
52
 
277
- *Santiago Bartesaghi*
53
+ * Fix all Active Storage database related models to respect
54
+ `ActiveRecord::Base.table_name_prefix` configuration.
278
55
 
279
- * Add support of `strict_loading_by_default` to `ActiveStorage::Representations` controllers.
56
+ *Chedli Bourguiba*
280
57
 
281
- *Anton Topchii*, *Andrew White*
58
+ * Fix `ActiveStorage::Representations::ProxyController` not returning the proper
59
+ preview image variant for previewable files.
282
60
 
283
- * Allow to detach an attachment when record is not persisted.
61
+ *Chedli Bourguiba*
284
62
 
285
- *Jacopo Beschi*
63
+ * Fix `ActiveStorage::Representations::ProxyController` to proxy untracked
64
+ variants.
286
65
 
287
- * Use libvips instead of ImageMagick to analyze images when `active_storage.variant_processor = vips`.
66
+ *Chedli Bourguiba*
288
67
 
289
- *Breno Gazzola*
68
+ * When using the `preprocessed: true` option, avoid enqueuing transform jobs
69
+ for blobs that are not representable.
290
70
 
291
- * Add metadata value for presence of video channel in video blobs.
71
+ *Chedli Bourguiba*
292
72
 
293
- The `metadata` attribute of video blobs has a new boolean key named `video` that is set to
294
- `true` if the file has an video channel and `false` if it doesn't.
73
+ * Prevent `ActiveStorage::Blob#preview` to generate a variant if an empty variation is passed.
295
74
 
296
- *Breno Gazzola*
75
+ Calls to `#url`, `#key` or `#download` will now use the original preview
76
+ image instead of generating a variant with the exact same dimensions.
297
77
 
298
- * Deprecate usage of `purge` and `purge_later` from the association extension.
78
+ *Chedli Bourguiba*
299
79
 
300
- *Jacopo Beschi*
80
+ * Process preview image variant when calling `ActiveStorage::Preview#processed`.
301
81
 
302
- * Passing extra parameters in `ActiveStorage::Blob#url` to S3 Client.
82
+ For example, `attached_pdf.preview(:thumb).processed` will now immediately
83
+ generate the full-sized preview image and the `:thumb` variant of it.
84
+ Previously, the `:thumb` variant would not be generated until a further call
85
+ to e.g. `processed.url`.
303
86
 
304
- This allows calls of `ActiveStorage::Blob#url` to have more interaction with
305
- the S3 Presigner, enabling, amongst other options, custom S3 domain URL
306
- Generation.
87
+ *Chedli Bourguiba* and *Jonathan Hefner*
307
88
 
308
- ```ruby
309
- blob = ActiveStorage::Blob.last
310
-
311
- blob.url # => https://<bucket-name>.s3.<region>.amazonaws.com/<key>
312
- blob.url(virtual_host: true) # => # => https://<bucket-name>/<key>
313
- ```
314
-
315
- *josegomezr*
316
-
317
- * Allow setting a `Cache-Control` on files uploaded to GCS.
318
-
319
- ```yaml
320
- gcs:
321
- service: GCS
322
- ...
323
- cache_control: "public, max-age=3600"
324
- ```
325
-
326
- *maleblond*
327
-
328
- * The parameters sent to `ffmpeg` for generating a video preview image are now
329
- configurable under `config.active_storage.video_preview_arguments`.
330
-
331
- *Brendon Muir*
332
-
333
- * The ActiveStorage video previewer will now use scene change detection to generate
334
- better preview images (rather than the previous default of using the first frame
335
- of the video). This change requires FFmpeg v3.4+.
89
+ * Prevent `ActiveRecord::StrictLoadingViolationError` when strict loading is
90
+ enabled and the variant of an Active Storage preview has already been
91
+ processed (for example, by calling `ActiveStorage::Preview#url`).
336
92
 
337
93
  *Jonathan Hefner*
338
94
 
339
- * Add support for ActiveStorage expiring URLs.
340
-
341
- ```ruby
342
- rails_blob_path(user.avatar, disposition: "attachment", expires_in: 30.minutes)
343
-
344
- <%= image_tag rails_blob_path(user.avatar.variant(resize: "100x100"), expires_in: 30.minutes) %>
345
- ```
346
-
347
- If you want to set default expiration time for ActiveStorage URLs throughout your application, set `config.active_storage.urls_expire_in`.
348
-
349
- *aki77*
350
-
351
- * Allow to purge an attachment when record is not persisted for `has_many_attached`.
352
-
353
- *Jacopo Beschi*
354
-
355
- * Add `with_all_variant_records` method to eager load all variant records on an attachment at once.
356
- `with_attached_image` scope now eager loads variant records if using variant tracking.
357
-
358
- *Alex Ghiculescu*
359
-
360
- * Add metadata value for presence of audio channel in video blobs.
361
-
362
- The `metadata` attribute of video blobs has a new boolean key named `audio` that is set to
363
- `true` if the file has an audio channel and `false` if it doesn't.
364
-
365
- *Breno Gazzola*
366
-
367
- * Adds analyzer for audio files.
368
-
369
- *Breno Gazzola*
370
-
371
- * Respect Active Record's primary_key_type in Active Storage migrations.
372
-
373
- *fatkodima*
374
-
375
- * Allow `expires_in` for ActiveStorage signed ids.
376
-
377
- *aki77*
378
-
379
- * Allow to purge an attachment when record is not persisted for `has_one_attached`.
380
-
381
- *Jacopo Beschi*
382
-
383
- * Add a load hook called `active_storage_variant_record` (providing `ActiveStorage::VariantRecord`)
384
- to allow for overriding aspects of the `ActiveStorage::VariantRecord` class. This makes
385
- `ActiveStorage::VariantRecord` consistent with `ActiveStorage::Blob` and `ActiveStorage::Attachment`
386
- that already have load hooks.
387
-
388
- *Brendon Muir*
389
-
390
- * `ActiveStorage::PreviewError` is raised when a previewer is unable to generate a preview image.
391
-
392
- *Alex Robbin*
393
-
394
- * Add `ActiveStorage::Streaming` module that can be included in a controller to get access to `#send_blob_stream`,
395
- which wraps the new `ActionController::Base#send_stream` method to stream a blob from cloud storage:
396
-
397
- ```ruby
398
- class MyPublicBlobsController < ApplicationController
399
- include ActiveStorage::SetBlob, ActiveStorage::Streaming
400
-
401
- def show
402
- http_cache_forever(public: true) do
403
- send_blob_stream @blob, disposition: params[:disposition]
404
- end
405
- end
406
- end
407
- ```
408
-
409
- *DHH*
410
-
411
- * Add ability to use pre-defined variants.
412
-
413
- ```ruby
414
- class User < ActiveRecord::Base
415
- has_one_attached :avatar do |attachable|
416
- attachable.variant :thumb, resize: "100x100"
417
- attachable.variant :medium, resize: "300x300", monochrome: true
418
- end
419
- end
420
-
421
- class Gallery < ActiveRecord::Base
422
- has_many_attached :photos do |attachable|
423
- attachable.variant :thumb, resize: "100x100"
424
- attachable.variant :medium, resize: "300x300", monochrome: true
425
- end
426
- end
427
-
428
- <%= image_tag user.avatar.variant(:thumb) %>
429
- ```
430
-
431
- *fatkodima*
432
-
433
- * After setting `config.active_storage.resolve_model_to_route = :rails_storage_proxy`
434
- `rails_blob_path` and `rails_representation_path` will generate proxy URLs by default.
435
-
436
- *Ali Ismayilov*
95
+ * Fix `preprocessed: true` option for named variants of previewable files.
437
96
 
438
- * Declare `ActiveStorage::FixtureSet` and `ActiveStorage::FixtureSet.blob` to
439
- improve fixture integration.
97
+ *Nico Wenterodt*
440
98
 
441
- *Sean Doyle*
99
+ * Allow accepting `service` as a proc as well in `has_one_attached` and `has_many_attached`.
442
100
 
101
+ *Yogesh Khater*
443
102
 
444
- Please check [6-1-stable](https://github.com/rails/rails/blob/6-1-stable/activestorage/CHANGELOG.md) for previous changes.
103
+ Please check [7-1-stable](https://github.com/rails/rails/blob/7-1-stable/activestorage/CHANGELOG.md) for previous changes.
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2017-2022 David Heinemeier Hansson, Basecamp
1
+ Copyright (c) David Heinemeier Hansson, 37signals LLC
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -6,11 +6,11 @@ Files can be uploaded from the server to the cloud or directly from the client t
6
6
 
7
7
  Image files can furthermore be transformed using on-demand variants for quality, aspect ratio, size, or any other [MiniMagick](https://github.com/minimagick/minimagick) or [Vips](https://www.rubydoc.info/gems/ruby-vips/Vips/Image) supported transformation.
8
8
 
9
- You can read more about Active Storage in the [Active Storage Overview](https://edgeguides.rubyonrails.org/active_storage_overview.html) guide.
9
+ You can read more about Active Storage in the [Active Storage Overview](https://guides.rubyonrails.org/active_storage_overview.html) guide.
10
10
 
11
11
  ## Compared to other storage solutions
12
12
 
13
- A key difference to how Active Storage works compared to other attachment solutions in Rails is through the use of built-in [Blob](https://github.com/rails/rails/blob/main/activestorage/app/models/active_storage/blob.rb) and [Attachment](https://github.com/rails/rails/blob/main/activestorage/app/models/active_storage/attachment.rb) models (backed by Active Record). This means existing application models do not need to be modified with additional columns to associate with files. Active Storage uses polymorphic associations via the `Attachment` join model, which then connects to the actual `Blob`.
13
+ A key difference to how Active Storage works compared to other attachment solutions in \Rails is through the use of built-in [Blob](https://github.com/rails/rails/blob/main/activestorage/app/models/active_storage/blob.rb) and [Attachment](https://github.com/rails/rails/blob/main/activestorage/app/models/active_storage/attachment.rb) models (backed by Active Record). This means existing application models do not need to be modified with additional columns to associate with files. Active Storage uses polymorphic associations via the `Attachment` join model, which then connects to the actual `Blob`.
14
14
 
15
15
  `Blob` models store attachment metadata (filename, content-type, etc.), and their identifier key in the storage service. Blob models do not store the actual binary data. They are intended to be immutable in spirit. One file, one blob. You can associate the same blob with multiple application models as well. And if you want to do transformations of a given `Blob`, the idea is that you'll simply create a new one, rather than attempt to mutate the existing one (though of course you can delete the previous version later if you don't need it).
16
16
 
@@ -144,11 +144,11 @@ Active Storage, with its included JavaScript library, supports uploading directl
144
144
 
145
145
  1. Include the Active Storage JavaScript in your application's JavaScript bundle or reference it directly.
146
146
 
147
- Requiring directly without bundling through the asset pipeline in the application html with autostart:
148
- ```html
147
+ Requiring directly without bundling through the asset pipeline in the application HTML with autostart:
148
+ ```erb
149
149
  <%= javascript_include_tag "activestorage" %>
150
150
  ```
151
- Requiring via importmap-rails without bundling through the asset pipeline in the application html without autostart as ESM:
151
+ Requiring via importmap-rails without bundling through the asset pipeline in the application HTML without autostart as ESM:
152
152
  ```ruby
153
153
  # config/importmap.rb
154
154
  pin "@rails/activestorage", to: "activestorage.esm.js"
@@ -170,7 +170,7 @@ Active Storage, with its included JavaScript library, supports uploading directl
170
170
  ```
171
171
  2. Annotate file inputs with the direct upload URL.
172
172
 
173
- ```ruby
173
+ ```erb
174
174
  <%= form.file_field :attachments, multiple: true, direct_upload: true %>
175
175
  ```
176
176
  3. That's it! Uploads begin upon form submission.
@@ -508,7 +508,7 @@ function toArray(value) {
508
508
  }
509
509
 
510
510
  class BlobRecord {
511
- constructor(file, checksum, url) {
511
+ constructor(file, checksum, url, customHeaders = {}) {
512
512
  this.file = file;
513
513
  this.attributes = {
514
514
  filename: file.name,
@@ -522,6 +522,9 @@ class BlobRecord {
522
522
  this.xhr.setRequestHeader("Content-Type", "application/json");
523
523
  this.xhr.setRequestHeader("Accept", "application/json");
524
524
  this.xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
525
+ Object.keys(customHeaders).forEach((headerKey => {
526
+ this.xhr.setRequestHeader(headerKey, customHeaders[headerKey]);
527
+ }));
525
528
  const csrfToken = getMetaValue("csrf-token");
526
529
  if (csrfToken != undefined) {
527
530
  this.xhr.setRequestHeader("X-CSRF-Token", csrfToken);
@@ -604,11 +607,12 @@ class BlobUpload {
604
607
  let id = 0;
605
608
 
606
609
  class DirectUpload {
607
- constructor(file, url, delegate) {
610
+ constructor(file, url, delegate, customHeaders = {}) {
608
611
  this.id = ++id;
609
612
  this.file = file;
610
613
  this.url = url;
611
614
  this.delegate = delegate;
615
+ this.customHeaders = customHeaders;
612
616
  }
613
617
  create(callback) {
614
618
  FileChecksum.create(this.file, ((error, checksum) => {
@@ -616,7 +620,7 @@ class DirectUpload {
616
620
  callback(error);
617
621
  return;
618
622
  }
619
- const blob = new BlobRecord(this.file, checksum, this.url);
623
+ const blob = new BlobRecord(this.file, checksum, this.url, this.customHeaders);
620
624
  notify(this.delegate, "directUploadWillCreateBlobWithXHR", blob.xhr);
621
625
  blob.create((error => {
622
626
  if (error) {
@@ -767,9 +771,9 @@ function start() {
767
771
  }
768
772
 
769
773
  function didClick(event) {
770
- const {target: target} = event;
771
- if ((target.tagName == "INPUT" || target.tagName == "BUTTON") && target.type == "submit" && target.form) {
772
- submitButtonsByForm.set(target.form, target);
774
+ const button = event.target.closest("button, input");
775
+ if (button && button.type === "submit" && button.form) {
776
+ submitButtonsByForm.set(button.form, button);
773
777
  }
774
778
  }
775
779
 
@@ -841,4 +845,4 @@ function autostart() {
841
845
 
842
846
  setTimeout(autostart, 1);
843
847
 
844
- export { DirectUpload, start };
848
+ export { DirectUpload, DirectUploadController, DirectUploadsController, start };
@@ -503,7 +503,7 @@
503
503
  }
504
504
  }
505
505
  class BlobRecord {
506
- constructor(file, checksum, url) {
506
+ constructor(file, checksum, url, customHeaders = {}) {
507
507
  this.file = file;
508
508
  this.attributes = {
509
509
  filename: file.name,
@@ -517,6 +517,9 @@
517
517
  this.xhr.setRequestHeader("Content-Type", "application/json");
518
518
  this.xhr.setRequestHeader("Accept", "application/json");
519
519
  this.xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
520
+ Object.keys(customHeaders).forEach((headerKey => {
521
+ this.xhr.setRequestHeader(headerKey, customHeaders[headerKey]);
522
+ }));
520
523
  const csrfToken = getMetaValue("csrf-token");
521
524
  if (csrfToken != undefined) {
522
525
  this.xhr.setRequestHeader("X-CSRF-Token", csrfToken);
@@ -596,11 +599,12 @@
596
599
  }
597
600
  let id = 0;
598
601
  class DirectUpload {
599
- constructor(file, url, delegate) {
602
+ constructor(file, url, delegate, customHeaders = {}) {
600
603
  this.id = ++id;
601
604
  this.file = file;
602
605
  this.url = url;
603
606
  this.delegate = delegate;
607
+ this.customHeaders = customHeaders;
604
608
  }
605
609
  create(callback) {
606
610
  FileChecksum.create(this.file, ((error, checksum) => {
@@ -608,7 +612,7 @@
608
612
  callback(error);
609
613
  return;
610
614
  }
611
- const blob = new BlobRecord(this.file, checksum, this.url);
615
+ const blob = new BlobRecord(this.file, checksum, this.url, this.customHeaders);
612
616
  notify(this.delegate, "directUploadWillCreateBlobWithXHR", blob.xhr);
613
617
  blob.create((error => {
614
618
  if (error) {
@@ -750,9 +754,9 @@
750
754
  }
751
755
  }
752
756
  function didClick(event) {
753
- const {target: target} = event;
754
- if ((target.tagName == "INPUT" || target.tagName == "BUTTON") && target.type == "submit" && target.form) {
755
- submitButtonsByForm.set(target.form, target);
757
+ const button = event.target.closest("button, input");
758
+ if (button && button.type === "submit" && button.form) {
759
+ submitButtonsByForm.set(button.form, button);
756
760
  }
757
761
  }
758
762
  function didSubmitForm(event) {
@@ -816,6 +820,8 @@
816
820
  }
817
821
  setTimeout(autostart, 1);
818
822
  exports.DirectUpload = DirectUpload;
823
+ exports.DirectUploadController = DirectUploadController;
824
+ exports.DirectUploadsController = DirectUploadsController;
819
825
  exports.start = start;
820
826
  Object.defineProperty(exports, "__esModule", {
821
827
  value: true