activestorage_saas 5.2.5.2 → 7.2.3

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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/AGENTS.md +260 -0
  3. data/CHANGELOG.md +12 -0
  4. data/COVERAGE.md +64 -0
  5. data/Gemfile +8 -4
  6. data/README.md +206 -17
  7. data/lib/active_storage/service/saas_service.rb +15 -10
  8. data/lib/active_storage_saas/blob_model_mixin.rb +48 -0
  9. data/lib/active_storage_saas/direct_uploads_controller_mixin.rb +31 -0
  10. data/lib/active_storage_saas/engine.rb +26 -5
  11. data/lib/active_storage_saas/routes.rb +3 -3
  12. data/lib/active_storage_saas/storage_service_configuration_model_mixin.rb +48 -0
  13. data/lib/active_storage_saas.rb +4 -2
  14. data/lib/generators/active_storage_saas/install/USAGE +5 -0
  15. data/lib/generators/active_storage_saas/install/install_generator.rb +19 -0
  16. data/lib/generators/active_storage_saas/install/templates/config/initializers/active_storage_saas.rb +6 -0
  17. metadata +13 -21
  18. data/.rspec +0 -3
  19. data/.rubocop.yml +0 -17
  20. data/Gemfile.lock +0 -112
  21. data/Rakefile +0 -12
  22. data/activestorage_saas.gemspec +0 -33
  23. data/app/controller/active_storage_saas/direct_uploads_controller.rb +0 -28
  24. data/app/javascript/active_storage_saas/direct_upload_controller/blob_record.js +0 -73
  25. data/app/javascript/active_storage_saas/direct_upload_controller/blob_upload.js +0 -45
  26. data/app/javascript/active_storage_saas/direct_upload_controller/direct_upload.js +0 -48
  27. data/app/javascript/active_storage_saas/direct_upload_controller/file_checksum.js +0 -53
  28. data/app/javascript/active_storage_saas/direct_upload_controller/helpers.js +0 -51
  29. data/app/javascript/active_storage_saas/direct_upload_controller.js +0 -78
  30. data/app/models/tenant_storage_service.rb +0 -5
  31. data/db/migrate/001_activestorage_saas_tables.rb +0 -17
  32. data/lib/active_storage_saas/blob_patch.rb +0 -51
  33. data/sig/activestorage_saas.rbs +0 -4
@@ -0,0 +1,48 @@
1
+ require 'active_storage/service/saas_service'
2
+
3
+ module ActiveStorageSaas
4
+ module BlobModelMixin
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ prepend InstanceMethods
9
+ end
10
+
11
+ prepended do
12
+ prepend InstanceMethods
13
+ end
14
+
15
+ module InstanceMethods
16
+ extend ActiveSupport::Concern
17
+
18
+ prepended do
19
+ redefine_method :service do
20
+ @service ||= begin
21
+ raise KeyError, "storage service name should not be 'saas'" if service_name.to_s == 'saas'
22
+
23
+ services.fetch(service_name) { |_| ActiveStorageSaas.service_resolver.call(self) } || global_service
24
+ end
25
+ end
26
+
27
+ validate on: :save do
28
+ errors.add(:service_name, :invalid) if service_name.to_s == 'saas'
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def global_service
35
+ self.class.service
36
+ end
37
+
38
+ def analyzer_class
39
+ analyzers = service.class.respond_to?(:analyzers) ? service.class.analyzers : ActiveStorage.analyzers
40
+ analyzers.detect { |klass| klass.accept?(self) } || ActiveStorage::Analyzer::NullAnalyzer
41
+ end
42
+
43
+ def validate_service_name_in_services
44
+ ActiveStorageSaas.service_name_validator.call(service_name) || super
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,31 @@
1
+ module ActiveStorageSaas
2
+ module DirectUploadsControllerMixin
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ prepend InstanceMethods
7
+ end
8
+
9
+ prepended do
10
+ prepend InstanceMethods
11
+ end
12
+
13
+ module InstanceMethods
14
+ def create
15
+ blob = ActiveStorage::Blob.create_before_direct_upload!(**blob_args)
16
+ render json: direct_upload_json(blob)
17
+ end
18
+
19
+ def callback
20
+ ActiveStorageSaas.direct_upload_callback.call(self)
21
+ end
22
+
23
+ private
24
+
25
+ def blob_args
26
+ super.merge(ActiveStorageSaas.direct_upload_extra_blob_args.call(self))
27
+ .merge(service_name: ActiveStorageSaas.service_name_converter.call(self))
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,17 +1,38 @@
1
+ require 'active_storage_saas/blob_model_mixin'
2
+ require 'active_storage_saas/direct_uploads_controller_mixin'
3
+ require 'active_storage_saas/storage_service_configuration_model_mixin'
1
4
  module ActiveStorageSaas
2
5
  class Engine < Rails::Engine
3
- config.before_configuration do
4
- # disable active_storage routes
5
- ActiveStorage::Engine.config.paths['config/routes.rb'] = []
6
+ config.generators do |g|
7
+ g.test_framework :rspec
8
+ end
9
+ config.active_storage_saas = ActiveSupport::OrderedOptions.new
10
+
11
+ initializer "active_storage_saas.configs" do
12
+ config.after_initialize do |app|
13
+ default_service_resolver = ->(blob) { StorageServiceConfiguration.from_service_name(blob.service_name)&.to_service }
14
+ default_service_name_converter = ->(controller) { StorageServiceConfiguration.first.to_service_name }
15
+ default_service_name_validator = ->(service_name) { StorageServiceConfiguration.valid_service_name?(service_name) }
16
+ default_direct_upload_extra_blob_args = ->(controller) { { } }
17
+ ActiveStorageSaas.service_resolver = app.config.active_storage_saas.service_resolver || default_service_resolver
18
+ ActiveStorageSaas.service_name_converter = app.config.active_storage_saas.service_name_converter || default_service_name_converter
19
+ ActiveStorageSaas.service_name_validator = app.config.active_storage_saas.service_name_validator || default_service_name_validator
20
+ ActiveStorageSaas.direct_upload_extra_blob_args = app.config.active_storage_saas.direct_upload_extra_blob_args || default_direct_upload_extra_blob_args
21
+ ActiveStorage::Blob # call this class to load mixin
22
+ end
23
+
24
+ config.to_prepare do
25
+ ActiveStorage::DirectUploadsController.include ActiveStorageSaas::DirectUploadsControllerMixin
26
+ end
6
27
  end
7
28
 
8
29
  config.to_prepare do
9
30
  ActionDispatch::Routing::Mapper.include Routes
10
31
  end
11
32
 
12
- initializer 'patch' do
33
+ initializer 'active_storage_saas.load_mixins' do
13
34
  ActiveSupport.on_load(:active_storage_blob) do
14
- include ActiveStorageSaas::BlobPatch
35
+ include ActiveStorageSaas::BlobModelMixin
15
36
  end
16
37
  end
17
38
  end
@@ -3,9 +3,9 @@ module ActiveStorageSaas
3
3
  # rubocop: disable Layout/LineLength
4
4
  def draw_active_storage_saas_routes(
5
5
  prefix: '/rails/active_storage',
6
- blobs_controller: 'active_storage/blobs',
7
- representations_controller: 'active_storage/representations',
8
- disk_controller: 'active_storage/disk',
6
+ blobs_controller: 'active_storage_saas/blobs',
7
+ representations_controller: 'active_storage_saas/representations',
8
+ disk_controller: 'active_storage_saas/disk',
9
9
  direct_uploads_controller: 'active_storage_saas/direct_uploads',
10
10
  **option_overrides
11
11
  )
@@ -0,0 +1,48 @@
1
+ module ActiveStorageSaas
2
+ module StorageServiceConfigurationMixin
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ prepend InstanceMethods
7
+ end
8
+
9
+ prepended do
10
+ prepend InstanceMethods
11
+ end
12
+
13
+ module InstanceMethods
14
+ extend ActiveSupport::Concern
15
+
16
+ class_methods do
17
+ def service_name_pattern
18
+ /^#{name}:(\d+)$/
19
+ end
20
+
21
+ def from_service_name(service_name)
22
+ find_by(id: Regexp.last_match(1)) if service_name =~ service_name_pattern
23
+ end
24
+
25
+ def valid_service_name?(service_name)
26
+ service_name_pattern.match?(service_name)
27
+ end
28
+ end
29
+
30
+ def to_service
31
+ defined_service = ActiveStorage::Blob.services.fetch(service_name)
32
+ klass = defined_service.class
33
+ options = ActiveStorage::Blob.services.send(:configurations).fetch(service_name.to_sym).deep_dup
34
+ options.delete(:service) if service_name == 'amazon'
35
+ options.deep_merge! service_options.deep_symbolize_keys
36
+ klass.new(**options).tap do |instance|
37
+ instance.instance_eval <<~RUBY
38
+ define_singleton_method(:name) { "#{to_service_name}" }
39
+ RUBY
40
+ end
41
+ end
42
+
43
+ def to_service_name
44
+ "#{self.class.name}:#{id}"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -3,9 +3,11 @@
3
3
  module ActiveStorageSaas
4
4
  class Error < StandardError; end
5
5
 
6
- mattr_accessor :tenant_class_name, default: 'Tenant'
6
+ mattr_accessor :service_resolver
7
+ mattr_accessor :service_name_converter
8
+ mattr_accessor :service_name_validator
9
+ mattr_accessor :direct_upload_extra_blob_args
7
10
 
8
11
  require 'active_storage_saas/routes'
9
- require 'active_storage_saas/blob_patch'
10
12
  require 'active_storage_saas/engine'
11
13
  end
@@ -0,0 +1,5 @@
1
+ Description:
2
+ Install ActiveStorageSaas
3
+
4
+ Example:
5
+ bin/rails generate active_storage_saas:install
@@ -0,0 +1,19 @@
1
+ module ActiveStorageSaas
2
+ class InstallGenerator < Rails::Generators::Base
3
+ source_root File.expand_path("templates", __dir__)
4
+ class_option :configuration_model, type: :string, default: 'StorageServiceConfiguration'
5
+
6
+ def generate_model
7
+ generate "model", "#{options['configuration_model']} service_name service_options:json"
8
+ inject_into_file "app/models/#{options['configuration_model'].underscore}.rb", after: /^class .+\n/ do <<-'RUBY'
9
+ include ActiveStorageSaas::StorageServiceConfigurationMixin
10
+
11
+ RUBY
12
+ end
13
+ end
14
+
15
+ def copy_files
16
+ template 'config/initializers/active_storage_saas.rb'
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,6 @@
1
+ Rails.application.configure do
2
+ # config.active_storage_saas.service_resolver = ->(blob) { StorageServiceConfiguration.from_service_name(blob.service_name)&.to_service }
3
+ # config.active_storage_saas.service_name_converter = ->(controller) { controller.send(:current_tenant).storage_service&.to_service_name }
4
+ # config.active_storage_saas.service_name_validator = ->(service_name) { StorageServiceConfiguration.valid_service_name?(service_name) }
5
+ # config.active_storage_saas.direct_upload_extra_blob_args = ->(controller) { { tenant: controller.send(:current_tenant) } }
6
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activestorage_saas
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.2.5.2
4
+ version: 7.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - xiaohui
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-13 00:00:00.000000000 Z
11
+ date: 2025-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activestorage
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 5.2.5
19
+ version: 7.2.3
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 5.2.5
26
+ version: 7.2.3
27
27
  description: Each tenant can set its own storage service, ActiveStorage service can
28
28
  be dynamically loaded.
29
29
  email:
@@ -32,31 +32,23 @@ executables: []
32
32
  extensions: []
33
33
  extra_rdoc_files: []
34
34
  files:
35
- - ".rspec"
36
- - ".rubocop.yml"
35
+ - AGENTS.md
37
36
  - CHANGELOG.md
37
+ - COVERAGE.md
38
38
  - Gemfile
39
- - Gemfile.lock
40
39
  - LICENSE.txt
41
40
  - README.md
42
- - Rakefile
43
- - activestorage_saas.gemspec
44
- - app/controller/active_storage_saas/direct_uploads_controller.rb
45
- - app/javascript/active_storage_saas/direct_upload_controller.js
46
- - app/javascript/active_storage_saas/direct_upload_controller/blob_record.js
47
- - app/javascript/active_storage_saas/direct_upload_controller/blob_upload.js
48
- - app/javascript/active_storage_saas/direct_upload_controller/direct_upload.js
49
- - app/javascript/active_storage_saas/direct_upload_controller/file_checksum.js
50
- - app/javascript/active_storage_saas/direct_upload_controller/helpers.js
51
- - app/models/tenant_storage_service.rb
52
- - db/migrate/001_activestorage_saas_tables.rb
53
41
  - lib/active_storage/service/saas_service.rb
54
42
  - lib/active_storage_saas.rb
55
- - lib/active_storage_saas/blob_patch.rb
43
+ - lib/active_storage_saas/blob_model_mixin.rb
44
+ - lib/active_storage_saas/direct_uploads_controller_mixin.rb
56
45
  - lib/active_storage_saas/engine.rb
57
46
  - lib/active_storage_saas/routes.rb
47
+ - lib/active_storage_saas/storage_service_configuration_model_mixin.rb
58
48
  - lib/activestorage_saas.rb
59
- - sig/activestorage_saas.rbs
49
+ - lib/generators/active_storage_saas/install/USAGE
50
+ - lib/generators/active_storage_saas/install/install_generator.rb
51
+ - lib/generators/active_storage_saas/install/templates/config/initializers/active_storage_saas.rb
60
52
  homepage: https://github.com/xiaohui-zhangxh/activestorage_saas
61
53
  licenses:
62
54
  - MIT
@@ -79,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
71
  - !ruby/object:Gem::Version
80
72
  version: '0'
81
73
  requirements: []
82
- rubygems_version: 3.3.7
74
+ rubygems_version: 3.5.16
83
75
  signing_key:
84
76
  specification_version: 4
85
77
  summary: Wraps multi-tenant storage services as ActiveStorage service
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
data/.rubocop.yml DELETED
@@ -1,17 +0,0 @@
1
- AllCops:
2
- TargetRubyVersion: 2.6
3
- NewCops: enable
4
- Style/StringLiterals:
5
- Enabled: true
6
- EnforcedStyle: single_quotes
7
-
8
- Style/StringLiteralsInInterpolation:
9
- Enabled: true
10
- EnforcedStyle: double_quotes
11
-
12
- Layout/LineLength:
13
- Max: 120
14
-
15
- Layout/IndentationConsistency:
16
- Enabled: true
17
- EnforcedStyle: indented_internal_methods
data/Gemfile.lock DELETED
@@ -1,112 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- activestorage_saas (5.2.5.1)
5
- activestorage (= 5.2.5)
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- actionpack (5.2.5)
11
- actionview (= 5.2.5)
12
- activesupport (= 5.2.5)
13
- rack (~> 2.0, >= 2.0.8)
14
- rack-test (>= 0.6.3)
15
- rails-dom-testing (~> 2.0)
16
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
17
- actionview (5.2.5)
18
- activesupport (= 5.2.5)
19
- builder (~> 3.1)
20
- erubi (~> 1.4)
21
- rails-dom-testing (~> 2.0)
22
- rails-html-sanitizer (~> 1.0, >= 1.0.3)
23
- activemodel (5.2.5)
24
- activesupport (= 5.2.5)
25
- activerecord (5.2.5)
26
- activemodel (= 5.2.5)
27
- activesupport (= 5.2.5)
28
- arel (>= 9.0)
29
- activestorage (5.2.5)
30
- actionpack (= 5.2.5)
31
- activerecord (= 5.2.5)
32
- marcel (~> 1.0.0)
33
- activesupport (5.2.5)
34
- concurrent-ruby (~> 1.0, >= 1.0.2)
35
- i18n (>= 0.7, < 2)
36
- minitest (~> 5.1)
37
- tzinfo (~> 1.1)
38
- arel (9.0.0)
39
- ast (2.4.2)
40
- builder (3.2.4)
41
- concurrent-ruby (1.1.10)
42
- crass (1.0.6)
43
- diff-lcs (1.5.0)
44
- erubi (1.11.0)
45
- i18n (1.12.0)
46
- concurrent-ruby (~> 1.0)
47
- loofah (2.18.0)
48
- crass (~> 1.0.2)
49
- nokogiri (>= 1.5.9)
50
- marcel (1.0.2)
51
- mini_portile2 (2.8.0)
52
- minitest (5.16.2)
53
- nokogiri (1.13.8)
54
- mini_portile2 (~> 2.8.0)
55
- racc (~> 1.4)
56
- parallel (1.22.1)
57
- parser (3.1.1.0)
58
- ast (~> 2.4.1)
59
- racc (1.6.0)
60
- rack (2.2.4)
61
- rack-test (2.0.2)
62
- rack (>= 1.3)
63
- rails-dom-testing (2.0.3)
64
- activesupport (>= 4.2.0)
65
- nokogiri (>= 1.6)
66
- rails-html-sanitizer (1.4.3)
67
- loofah (~> 2.3)
68
- rainbow (3.1.1)
69
- rake (13.0.6)
70
- regexp_parser (2.5.0)
71
- rexml (3.2.5)
72
- rspec (3.11.0)
73
- rspec-core (~> 3.11.0)
74
- rspec-expectations (~> 3.11.0)
75
- rspec-mocks (~> 3.11.0)
76
- rspec-core (3.11.0)
77
- rspec-support (~> 3.11.0)
78
- rspec-expectations (3.11.0)
79
- diff-lcs (>= 1.2.0, < 2.0)
80
- rspec-support (~> 3.11.0)
81
- rspec-mocks (3.11.1)
82
- diff-lcs (>= 1.2.0, < 2.0)
83
- rspec-support (~> 3.11.0)
84
- rspec-support (3.11.0)
85
- rubocop (1.27.0)
86
- parallel (~> 1.10)
87
- parser (>= 3.1.0.0)
88
- rainbow (>= 2.2.2, < 4.0)
89
- regexp_parser (>= 1.8, < 3.0)
90
- rexml
91
- rubocop-ast (>= 1.16.0, < 2.0)
92
- ruby-progressbar (~> 1.7)
93
- unicode-display_width (>= 1.4.0, < 3.0)
94
- rubocop-ast (1.17.0)
95
- parser (>= 3.1.1.0)
96
- ruby-progressbar (1.11.0)
97
- thread_safe (0.3.6)
98
- tzinfo (1.2.10)
99
- thread_safe (~> 0.1)
100
- unicode-display_width (2.1.0)
101
-
102
- PLATFORMS
103
- ruby
104
-
105
- DEPENDENCIES
106
- activestorage_saas!
107
- rake (~> 13.0)
108
- rspec (~> 3.0)
109
- rubocop (~> 1.21)
110
-
111
- BUNDLED WITH
112
- 2.3.10
data/Rakefile DELETED
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
5
-
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- require "rubocop/rake_task"
9
-
10
- RuboCop::RakeTask.new
11
-
12
- task default: %i[spec rubocop]
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- activestorage_version = '5.2.5'
4
- gem_version = 2
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "activestorage_saas"
8
- spec.version = "#{activestorage_version}.#{gem_version}"
9
- spec.authors = ["xiaohui"]
10
- spec.email = ["xiaohui@tanmer.com"]
11
-
12
- spec.summary = "Wraps multi-tenant storage services as ActiveStorage service"
13
- spec.description = "Each tenant can set its own storage service, ActiveStorage service can be dynamically loaded."
14
- spec.homepage = "https://github.com/xiaohui-zhangxh/activestorage_saas"
15
- spec.license = "MIT"
16
- spec.required_ruby_version = ">= 2.6.0"
17
-
18
- spec.metadata["homepage_uri"] = spec.homepage
19
- spec.metadata["source_code_uri"] = spec.homepage
20
- spec.metadata["changelog_uri"] = "#{spec.homepage}/CHANGELOG.md"
21
-
22
- # Specify which files should be added to the gem when it is released.
23
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
24
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
- `git ls-files -z`.split("\x0").reject do |f|
26
- (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
27
- end
28
- end
29
-
30
- spec.require_paths = ["lib"]
31
-
32
- spec.add_dependency "activestorage", activestorage_version
33
- end
@@ -1,28 +0,0 @@
1
- class ActiveStorageSaas::DirectUploadsController < ActiveStorage::BaseController
2
- def create
3
- blob = ActiveStorage::Blob.create!(blob_args)
4
- render json: direct_upload_json(blob)
5
- end
6
-
7
- def callback
8
- raise NotImplementedError
9
- end
10
-
11
- private
12
-
13
- def blob_args
14
- blob_args = params.require(:blob).permit(:filename, :byte_size, :checksum, :content_type).to_h.symbolize_keys
15
- blob_args.merge! tenant: current_tenant, tenant_storage_service: current_tenant.storage_service
16
- end
17
-
18
- def direct_upload_json(blob)
19
- blob.as_json(root: false, methods: :signed_id, only: :signed_id)
20
- .merge(direct_upload: {
21
- url: blob.service_url_for_direct_upload,
22
- method: blob.service_http_method_for_direct_upload,
23
- responseType: blob.service_http_response_type_for_direct_upload,
24
- headers: blob.service_headers_for_direct_upload,
25
- formData: blob.service_form_data_for_direct_upload.presence
26
- })
27
- end
28
- end
@@ -1,73 +0,0 @@
1
- import { getMetaValue } from "./helpers"
2
-
3
- export class BlobRecord {
4
- constructor(file, checksum, url) {
5
- this.file = file
6
-
7
- this.attributes = {
8
- filename: file.name,
9
- content_type: file.type || "application/octet-stream",
10
- byte_size: file.size,
11
- checksum: checksum
12
- }
13
-
14
- this.xhr = new XMLHttpRequest
15
- this.xhr.open("POST", url, true)
16
- this.xhr.responseType = "json"
17
- this.xhr.setRequestHeader("Content-Type", "application/json")
18
- this.xhr.setRequestHeader("Accept", "application/json")
19
- this.xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest")
20
-
21
- const csrfToken = getMetaValue("csrf-token")
22
- if (csrfToken != undefined) {
23
- this.xhr.setRequestHeader("X-CSRF-Token", csrfToken)
24
- }
25
-
26
- this.xhr.addEventListener("load", event => this.requestDidLoad(event))
27
- this.xhr.addEventListener("error", event => this.requestDidError(event))
28
- }
29
-
30
- get status() {
31
- return this.xhr.status
32
- }
33
-
34
- get response() {
35
- const { responseType, response } = this.xhr
36
- if (responseType == "json") {
37
- return response
38
- } else {
39
- // Shim for IE 11: https://connect.microsoft.com/IE/feedback/details/794808
40
- return JSON.parse(response)
41
- }
42
- }
43
-
44
- create(callback) {
45
- this.callback = callback
46
- this.xhr.send(JSON.stringify({ blob: this.attributes }))
47
- }
48
-
49
- requestDidLoad(event) {
50
- if (this.status >= 200 && this.status < 300) {
51
- const { response } = this
52
- const { direct_upload } = response
53
- delete response.direct_upload
54
- this.attributes = response
55
- this.directUploadData = direct_upload
56
- this.callback(null, this.toJSON())
57
- } else {
58
- this.requestDidError(event)
59
- }
60
- }
61
-
62
- requestDidError(event) {
63
- this.callback(event, this)
64
- }
65
-
66
- toJSON() {
67
- const result = {}
68
- for (const key in this.attributes) {
69
- result[key] = this.attributes[key]
70
- }
71
- return result
72
- }
73
- }
@@ -1,45 +0,0 @@
1
- export class BlobUpload {
2
- constructor(blob) {
3
- this.blob = blob
4
- this.file = blob.file
5
-
6
- const { url, headers, method, responseType } = blob.directUploadData
7
-
8
- this.xhr = new XMLHttpRequest
9
- this.xhr.open(method || "PUT", url, true)
10
- this.xhr.responseType = responseType || "text"
11
- for (const key in headers) {
12
- this.xhr.setRequestHeader(key, headers[key])
13
- }
14
- this.xhr.addEventListener("load", event => this.requestDidLoad(event))
15
- this.xhr.addEventListener("error", event => this.requestDidError(event))
16
- }
17
-
18
- create(callback) {
19
- this.callback = callback
20
- if(this.blob.directUploadData.formData){
21
- var formData
22
- formData = new FormData()
23
- for(const key in this.blob.directUploadData.formData){
24
- formData.append(key, this.blob.directUploadData.formData[key])
25
- }
26
- formData.append('file', this.file)
27
- this.xhr.send(formData)
28
- }else{
29
- this.xhr.send(this.file.slice())
30
- }
31
- }
32
-
33
- requestDidLoad(event) {
34
- const { status, response } = this.xhr
35
- if (status >= 200 && status < 300) {
36
- this.callback(null, response)
37
- } else {
38
- this.requestDidError(event)
39
- }
40
- }
41
-
42
- requestDidError(event) {
43
- this.callback(event, this)
44
- }
45
- }