uploadcare-ruby 2.1.2 → 3.0.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.
- checksums.yaml +4 -4
- data/.github/workflows/gem-push.yml +20 -0
- data/.github/workflows/ruby.yml +52 -0
- data/.gitignore +13 -6
- data/.rspec +2 -0
- data/.rubocop.yml +20 -0
- data/.yardopts +4 -0
- data/CHANGELOG.md +24 -51
- data/DEVELOPMENT.md +18 -0
- data/Gemfile +2 -0
- data/LICENSE +1 -1
- data/README.md +164 -578
- data/Rakefile +5 -5
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/uploadcare.rb +36 -32
- data/lib/uploadcare/api/api.rb +25 -0
- data/lib/uploadcare/client/file_client.rb +44 -0
- data/lib/uploadcare/client/file_list_client.rb +46 -0
- data/lib/uploadcare/client/group_client.rb +45 -0
- data/lib/uploadcare/client/multipart_upload/chunks_client.rb +46 -0
- data/lib/uploadcare/client/multipart_upload_client.rb +62 -0
- data/lib/uploadcare/client/project_client.rb +18 -0
- data/lib/uploadcare/client/rest_client.rb +73 -0
- data/lib/uploadcare/client/rest_group_client.rb +23 -0
- data/lib/uploadcare/client/upload_client.rb +35 -0
- data/lib/uploadcare/client/uploader_client.rb +93 -0
- data/lib/uploadcare/client/webhook_client.rb +43 -0
- data/lib/uploadcare/concern/error_handler.rb +54 -0
- data/lib/uploadcare/concern/throttle_handler.rb +25 -0
- data/lib/uploadcare/concern/upload_error_handler.rb +32 -0
- data/lib/uploadcare/entity/decorator/paginator.rb +81 -0
- data/lib/uploadcare/entity/entity.rb +18 -0
- data/lib/uploadcare/entity/file.rb +81 -0
- data/lib/uploadcare/entity/file_list.rb +30 -0
- data/lib/uploadcare/entity/group.rb +41 -0
- data/lib/uploadcare/entity/group_list.rb +24 -0
- data/lib/uploadcare/entity/project.rb +13 -0
- data/lib/uploadcare/entity/uploader.rb +73 -0
- data/lib/uploadcare/entity/webhook.rb +14 -0
- data/lib/uploadcare/exception/request_error.rb +9 -0
- data/lib/uploadcare/exception/throttle_error.rb +14 -0
- data/lib/uploadcare/param/authentication_header.rb +25 -0
- data/lib/uploadcare/param/param.rb +10 -0
- data/lib/uploadcare/param/secure_auth_header.rb +37 -0
- data/lib/uploadcare/param/simple_auth_header.rb +14 -0
- data/lib/uploadcare/param/upload/signature_generator.rb +24 -0
- data/lib/uploadcare/param/upload/upload_params_generator.rb +23 -0
- data/lib/uploadcare/param/user_agent.rb +21 -0
- data/lib/uploadcare/ruby/version.rb +5 -0
- data/uploadcare-ruby.gemspec +50 -37
- metadata +98 -113
- data/.travis.yml +0 -26
- data/UPGRADE_NOTES.md +0 -36
- data/lib/uploadcare/api.rb +0 -26
- data/lib/uploadcare/api/file_api.rb +0 -7
- data/lib/uploadcare/api/file_list_api.rb +0 -19
- data/lib/uploadcare/api/file_storage_api.rb +0 -34
- data/lib/uploadcare/api/group_api.rb +0 -38
- data/lib/uploadcare/api/group_list_api.rb +0 -17
- data/lib/uploadcare/api/project_api.rb +0 -9
- data/lib/uploadcare/api/raw_api.rb +0 -38
- data/lib/uploadcare/api/uploading_api.rb +0 -71
- data/lib/uploadcare/api/uploading_api/upload_params.rb +0 -72
- data/lib/uploadcare/api/validators/file_list_options_validator.rb +0 -73
- data/lib/uploadcare/api/validators/group_list_options_validator.rb +0 -49
- data/lib/uploadcare/errors/errors.rb +0 -64
- data/lib/uploadcare/resources/file.rb +0 -164
- data/lib/uploadcare/resources/file_list.rb +0 -14
- data/lib/uploadcare/resources/group.rb +0 -115
- data/lib/uploadcare/resources/group_list.rb +0 -14
- data/lib/uploadcare/resources/project.rb +0 -13
- data/lib/uploadcare/resources/resource_list.rb +0 -83
- data/lib/uploadcare/rest/auth/auth.rb +0 -31
- data/lib/uploadcare/rest/auth/secure.rb +0 -43
- data/lib/uploadcare/rest/auth/simple.rb +0 -16
- data/lib/uploadcare/rest/connections/api_connection.rb +0 -53
- data/lib/uploadcare/rest/connections/upload_connection.rb +0 -22
- data/lib/uploadcare/rest/middlewares/auth_middleware.rb +0 -24
- data/lib/uploadcare/rest/middlewares/parse_json_middleware.rb +0 -33
- data/lib/uploadcare/rest/middlewares/raise_error_middleware.rb +0 -21
- data/lib/uploadcare/utils/parser.rb +0 -71
- data/lib/uploadcare/utils/user_agent.rb +0 -44
- data/lib/uploadcare/version.rb +0 -3
- data/spec/api/file_list_api_spec.rb +0 -95
- data/spec/api/file_storage_api_spec.rb +0 -88
- data/spec/api/group_list_api_spec.rb +0 -59
- data/spec/api/raw_api_spec.rb +0 -25
- data/spec/api/uploading_api/upload_params_spec.rb +0 -99
- data/spec/api/uploading_api_spec.rb +0 -59
- data/spec/resources/file_list_spec.rb +0 -25
- data/spec/resources/file_spec.rb +0 -223
- data/spec/resources/group_list_spec.rb +0 -25
- data/spec/resources/group_spec.rb +0 -101
- data/spec/resources/operations_spec.rb +0 -59
- data/spec/resources/project_spec.rb +0 -21
- data/spec/rest/api_connection_spec.rb +0 -68
- data/spec/rest/auth/secure_spec.rb +0 -66
- data/spec/rest/auth/simple_spec.rb +0 -31
- data/spec/rest/errors_spec.rb +0 -75
- data/spec/rest/upload_connection_spec.rb +0 -19
- data/spec/shared/resource_list.rb +0 -188
- data/spec/spec_helper.rb +0 -54
- data/spec/uploadcare_spec.rb +0 -43
- data/spec/utils/parser_spec.rb +0 -85
- data/spec/utils/user_agent_spec.rb +0 -46
- data/spec/view.png +0 -0
- data/spec/view2.jpg +0 -0
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
require 'ostruct'
|
|
2
|
-
require_relative 'resource_list'
|
|
3
|
-
|
|
4
|
-
module Uploadcare
|
|
5
|
-
class Api
|
|
6
|
-
class FileList < ResourceList
|
|
7
|
-
private
|
|
8
|
-
|
|
9
|
-
def to_resource(api, file_data)
|
|
10
|
-
Uploadcare::Api::File.new(api, file_data['uuid'], file_data)
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
require 'ostruct'
|
|
2
|
-
|
|
3
|
-
module Uploadcare
|
|
4
|
-
class Api
|
|
5
|
-
class Group < OpenStruct
|
|
6
|
-
def initialize api, uuid_or_cdn_url, data=nil
|
|
7
|
-
result = Uploadcare::Parser.parse_group_string(uuid_or_cdn_url)
|
|
8
|
-
|
|
9
|
-
@api = api
|
|
10
|
-
group = {uuid: result.uuid, files_count: result.count}
|
|
11
|
-
super group
|
|
12
|
-
|
|
13
|
-
# if data is suplide - just pass it to builder.
|
|
14
|
-
set_data(data) if data
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def cdn_url
|
|
18
|
-
@api.options[:static_url_base] + "/#{uuid}/"
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def file_cdn_url index=0
|
|
22
|
-
raise ArgumentError.new "The index was given is greater than files count in group." if index + 1 > files_count
|
|
23
|
-
cdn_url + "nth/#{index}/"
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# Loading logic
|
|
27
|
-
def is_loaded?
|
|
28
|
-
!send(:files).nil?
|
|
29
|
-
end
|
|
30
|
-
alias_method :loaded?, :is_loaded?
|
|
31
|
-
|
|
32
|
-
def load_data
|
|
33
|
-
unless is_loaded?
|
|
34
|
-
load_data!
|
|
35
|
-
end
|
|
36
|
-
self
|
|
37
|
-
end
|
|
38
|
-
alias_method :load, :load_data
|
|
39
|
-
|
|
40
|
-
def load_data!
|
|
41
|
-
data = @api.get "/groups/#{uuid}/"
|
|
42
|
-
set_data data
|
|
43
|
-
|
|
44
|
-
self
|
|
45
|
-
end
|
|
46
|
-
alias_method :load!, :load_data!
|
|
47
|
-
|
|
48
|
-
# Store group (and all files in group)
|
|
49
|
-
def store
|
|
50
|
-
unless is_stored?
|
|
51
|
-
store!
|
|
52
|
-
end
|
|
53
|
-
self
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def store!
|
|
57
|
-
data = @api.put "/groups/#{uuid}/storage/"
|
|
58
|
-
set_data(data)
|
|
59
|
-
self
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def is_stored?
|
|
63
|
-
return nil unless is_loaded?
|
|
64
|
-
!send(:datetime_stored).nil?
|
|
65
|
-
end
|
|
66
|
-
alias_method :stored?, :is_stored?
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
["created", "stored"].each do |dt|
|
|
70
|
-
define_method "datetime_#{dt}" do
|
|
71
|
-
date = @table["datetime_#{dt}".to_sym]
|
|
72
|
-
if date.is_a?(String)
|
|
73
|
-
begin
|
|
74
|
-
parsed = DateTime.parse(date)
|
|
75
|
-
self.send("datetime_#{dt}=", parsed)
|
|
76
|
-
parsed
|
|
77
|
-
rescue Exception => e
|
|
78
|
-
date
|
|
79
|
-
end
|
|
80
|
-
else
|
|
81
|
-
date
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
private
|
|
88
|
-
def set_data data
|
|
89
|
-
data = map_files(data) unless data["files"].nil?
|
|
90
|
-
|
|
91
|
-
if data.respond_to? (:each)
|
|
92
|
-
data.each do |k, v|
|
|
93
|
-
self.send "#{k}=", v
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
@is_loaded = true
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
# map files (hashes basicly) to
|
|
101
|
-
# actual File objects
|
|
102
|
-
def map_files data
|
|
103
|
-
data["files"].map! do |file|
|
|
104
|
-
unless file.nil?
|
|
105
|
-
Uploadcare::Api::File.new(@api, file["uuid"], file)
|
|
106
|
-
else
|
|
107
|
-
file
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
data
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
end
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
require 'ostruct'
|
|
2
|
-
require_relative 'resource_list'
|
|
3
|
-
|
|
4
|
-
module Uploadcare
|
|
5
|
-
class Api
|
|
6
|
-
class GroupList < ResourceList
|
|
7
|
-
private
|
|
8
|
-
|
|
9
|
-
def to_resource(api, group_data)
|
|
10
|
-
Uploadcare::Api::Group.new api, group_data["id"], group_data
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
require 'ostruct'
|
|
2
|
-
|
|
3
|
-
module Uploadcare
|
|
4
|
-
class Api
|
|
5
|
-
class ResourceList
|
|
6
|
-
include Enumerable
|
|
7
|
-
|
|
8
|
-
extend Forwardable
|
|
9
|
-
def_delegator :@data, :meta
|
|
10
|
-
def_delegator :@data, :objects
|
|
11
|
-
|
|
12
|
-
attr_reader :options
|
|
13
|
-
|
|
14
|
-
def initialize(api, data, options)
|
|
15
|
-
@api = api
|
|
16
|
-
@data = build_data(data)
|
|
17
|
-
@options = options.dup.freeze
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def [](index)
|
|
21
|
-
first(index + 1).last
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def each
|
|
25
|
-
return enum_for(:each) unless block_given?
|
|
26
|
-
|
|
27
|
-
resource_enumerator.each { |object| yield object }
|
|
28
|
-
|
|
29
|
-
self
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def total
|
|
33
|
-
meta['total']
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def loaded
|
|
37
|
-
objects.size
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def fully_loaded?
|
|
41
|
-
meta['next'].nil?
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
private
|
|
45
|
-
|
|
46
|
-
attr_reader :api
|
|
47
|
-
|
|
48
|
-
def build_data(data_hash)
|
|
49
|
-
OpenStruct.new(
|
|
50
|
-
meta: data_hash.reject{|k, _| k == 'results'}.freeze,
|
|
51
|
-
objects: data_hash['results'].map{|object| to_resource(api, object)}
|
|
52
|
-
)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def get_next_page
|
|
56
|
-
return nil if fully_loaded?
|
|
57
|
-
|
|
58
|
-
next_page = build_data(api.get(@data.meta['next']))
|
|
59
|
-
|
|
60
|
-
@data = OpenStruct.new(
|
|
61
|
-
meta: next_page.meta,
|
|
62
|
-
objects: objects + next_page.objects
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
next_page
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def to_resource(*args)
|
|
69
|
-
raise NotImplementedError, 'You must define this method in a child class'
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def resource_enumerator
|
|
73
|
-
Enumerator.new do |yielder|
|
|
74
|
-
objects.each { |obj| yielder << obj }
|
|
75
|
-
|
|
76
|
-
while next_page = get_next_page do
|
|
77
|
-
next_page.objects.each { |obj| yielder << obj }
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
end
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
module Uploadcare
|
|
2
|
-
module Connections
|
|
3
|
-
module Auth
|
|
4
|
-
|
|
5
|
-
def self.strategy(options)
|
|
6
|
-
auth_scheme = options.fetch(:auth_scheme)
|
|
7
|
-
|
|
8
|
-
unless [:simple, :secure].include?(auth_scheme)
|
|
9
|
-
raise ArgumentError, "Unknown auth_scheme: '#{auth_scheme}'"
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
klass = const_get(auth_scheme.capitalize)
|
|
13
|
-
klass.new(options)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
class Base
|
|
17
|
-
attr_reader :public_key, :private_key
|
|
18
|
-
|
|
19
|
-
def initialize(options)
|
|
20
|
-
@public_key = options.fetch(:public_key)
|
|
21
|
-
@private_key = options.fetch(:private_key)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def apply(env)
|
|
25
|
-
raise NotImplementedError
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
require 'time'
|
|
2
|
-
|
|
3
|
-
module Uploadcare
|
|
4
|
-
module Connections
|
|
5
|
-
module Auth
|
|
6
|
-
class Secure < Base
|
|
7
|
-
|
|
8
|
-
def apply(env)
|
|
9
|
-
date = Time.now.utc
|
|
10
|
-
headers(env, date).each{|k, v| env.request_headers[k] = v}
|
|
11
|
-
env
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
private
|
|
15
|
-
|
|
16
|
-
def headers(env, date)
|
|
17
|
-
{
|
|
18
|
-
"Date" => date.rfc2822,
|
|
19
|
-
"Authorization" => "Uploadcare #{public_key}:#{signature(env, date)}"
|
|
20
|
-
}
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def signature(env, date)
|
|
24
|
-
sign_string = sign_string(env, date)
|
|
25
|
-
digest = OpenSSL::Digest.new('sha1')
|
|
26
|
-
|
|
27
|
-
OpenSSL::HMAC.hexdigest(digest, private_key, sign_string)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def sign_string(env, date)
|
|
31
|
-
verb = env.method.upcase.to_s
|
|
32
|
-
uri = env.url.request_uri
|
|
33
|
-
date_header = date.rfc2822
|
|
34
|
-
content_type = env.request_headers['Content-Type']
|
|
35
|
-
content_md5 = OpenSSL::Digest.new('md5').hexdigest(env.body || "")
|
|
36
|
-
|
|
37
|
-
[verb, content_md5, content_type, date_header, uri].join("\n")
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
module Uploadcare
|
|
2
|
-
module Connections
|
|
3
|
-
module Auth
|
|
4
|
-
class Simple < Base
|
|
5
|
-
|
|
6
|
-
def apply(env)
|
|
7
|
-
auth_string = "Uploadcare.Simple #{public_key}:#{private_key}"
|
|
8
|
-
env.request_headers['Authorization'] = auth_string
|
|
9
|
-
|
|
10
|
-
env
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
require 'faraday'
|
|
2
|
-
require "faraday_middleware"
|
|
3
|
-
|
|
4
|
-
module Uploadcare
|
|
5
|
-
module Connections
|
|
6
|
-
class ApiConnection < Faraday::Connection
|
|
7
|
-
|
|
8
|
-
def initialize options
|
|
9
|
-
super options[:api_url_base] do |frd|
|
|
10
|
-
auth_strategy = Auth.strategy(options)
|
|
11
|
-
|
|
12
|
-
frd.headers['Accept'] = "application/vnd.uploadcare-v#{options[:api_version]}+json"
|
|
13
|
-
frd.headers['User-Agent'] = UserAgent.new.call(options)
|
|
14
|
-
|
|
15
|
-
# order of middleware matters!
|
|
16
|
-
|
|
17
|
-
# :json middleware changes request body and thus should be before
|
|
18
|
-
# uploadcare_auth which uses it to sign requests when secure auth
|
|
19
|
-
# strategy is being used
|
|
20
|
-
frd.request :json
|
|
21
|
-
frd.request :uploadcare_auth, auth_strategy
|
|
22
|
-
|
|
23
|
-
frd.response :uploadcare_raise_error
|
|
24
|
-
frd.response :follow_redirects, limit: 3, callback: lambda{|old, env| auth_strategy.apply(env) }
|
|
25
|
-
frd.response :uploadcare_parse_json
|
|
26
|
-
|
|
27
|
-
frd.adapter :net_http # actually, default adapter, just to be clear
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# NOTE: Faraday doesn't support body in DELETE requests, but
|
|
32
|
-
# Uploadcare API v0.5 requires clients to send array of UUIDs with
|
|
33
|
-
# `DELETE /files/storage/` requests.
|
|
34
|
-
#
|
|
35
|
-
# This is on override of the original Faraday::Connection#delete method.
|
|
36
|
-
#
|
|
37
|
-
# As for now, there are no DELETE requests in Uploadcare REST API
|
|
38
|
-
# which require params to be sent as URI params, so for simplicity
|
|
39
|
-
# this method send all params in a body.
|
|
40
|
-
def delete(url = nil, params = nil, headers = nil)
|
|
41
|
-
run_request(:delete, url, nil, headers) { |request|
|
|
42
|
-
# Original line from Faraday::Connection#delete method
|
|
43
|
-
# request.params.update(params) if params
|
|
44
|
-
|
|
45
|
-
# Monkey patch
|
|
46
|
-
request.body = params if params
|
|
47
|
-
|
|
48
|
-
yield(request) if block_given?
|
|
49
|
-
}
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
require "faraday"
|
|
2
|
-
|
|
3
|
-
module Uploadcare
|
|
4
|
-
module Connections
|
|
5
|
-
class UploadConnection < Faraday::Connection
|
|
6
|
-
def initialize options
|
|
7
|
-
ca_path = '/etc/ssl/certs' if File.exists?('/etc/ssl/certs')
|
|
8
|
-
|
|
9
|
-
super ssl: { ca_path: ca_path }, url: options[:upload_url_base] do |frd|
|
|
10
|
-
frd.request :multipart
|
|
11
|
-
frd.request :url_encoded
|
|
12
|
-
frd.headers['User-Agent'] = UserAgent.new.call(options)
|
|
13
|
-
|
|
14
|
-
frd.response :uploadcare_raise_error
|
|
15
|
-
frd.response :uploadcare_parse_json
|
|
16
|
-
|
|
17
|
-
frd.adapter :net_http
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
require 'faraday'
|
|
2
|
-
|
|
3
|
-
module Uploadcare
|
|
4
|
-
module Connections
|
|
5
|
-
module Request
|
|
6
|
-
class Auth < Faraday::Middleware
|
|
7
|
-
attr_reader :auth_strategy
|
|
8
|
-
|
|
9
|
-
def initialize(app=nil, auth_strategy)
|
|
10
|
-
@auth_strategy = auth_strategy
|
|
11
|
-
super(app)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def call(env)
|
|
15
|
-
auth_strategy.apply(env)
|
|
16
|
-
@app.call(env)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
Faraday::Request.register_middleware uploadcare_auth: Uploadcare::Connections::Request::Auth
|