transloadit 3.1.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c48cbed2048f296ca130e4cbb69790fea92b7a02fab75f4aa9c0e6811b89063e
4
- data.tar.gz: 2b9752757ce8a2575cb6b3c446a19aec436c4003e715869e835e8906fb768b85
3
+ metadata.gz: fc246e913322624e733835f51e2924112ec4131af0930694ae322da3a10ea9e7
4
+ data.tar.gz: 79bd642651fd5d6b3c0f3153bfb9d44c6f78b16a7b91171d094e227b430f8949
5
5
  SHA512:
6
- metadata.gz: 2d05074cb025387b2f805c14797ff93b9abd5b28f77b51bc7a6a69811d66deb2dad2260a0ad6f0ad7ea5ff4313e076d1867332528a5b136f6694267d56987eee
7
- data.tar.gz: e078c99468b14f03ddc1f1c48a7abab1f92492194d8fc17bb6208a696f0a0cfb9a638a4002f7a4905ef9cd714e6ba0159f4f7f6e275693527478d5ea1ff3eae6
6
+ metadata.gz: 6ab26e103e6653f9b4126aed543446c6080e6bd30f1348cecefa38bb8406c706ec289e61e9c36c27512535f8590908ca15473cb042bf6ea38ebacac3eb7cd0a8
7
+ data.tar.gz: ef78d102680364717e5d4a4193a15cd553a7296478da13134c0cefa65fcc96138acca340990c7173b04e34fa741825788527d5d067e53eab057656acbf20bf1d
data/.gitattributes CHANGED
@@ -1,2 +1,44 @@
1
- *.jpg binary
2
-
1
+ /.yarn/** linguist-vendored
2
+ /.yarn/releases/* binary
3
+ /.yarn/plugins/**/* binary
4
+ /.pnp.* binary linguist-generated
5
+ *.7z filter=lfs diff=lfs merge=lfs -text
6
+ *.aac filter=lfs diff=lfs merge=lfs -text
7
+ *.ai filter=lfs diff=lfs merge=lfs -text
8
+ *.avi filter=lfs diff=lfs merge=lfs -text
9
+ *.bmp filter=lfs diff=lfs merge=lfs -text
10
+ *.br filter=lfs diff=lfs merge=lfs -text
11
+ *.cr2 filter=lfs diff=lfs merge=lfs -text
12
+ *.dll filter=lfs diff=lfs merge=lfs -text
13
+ *.doc filter=lfs diff=lfs merge=lfs -text
14
+ *.docx filter=lfs diff=lfs merge=lfs -text
15
+ *.exe filter=lfs diff=lfs merge=lfs -text
16
+ *.flac filter=lfs diff=lfs merge=lfs -text
17
+ *.gif filter=lfs diff=lfs merge=lfs -text
18
+ *.gz filter=lfs diff=lfs merge=lfs -text
19
+ *.ico filter=lfs diff=lfs merge=lfs -text
20
+ *.jpeg filter=lfs diff=lfs merge=lfs -text
21
+ *.jpg filter=lfs diff=lfs merge=lfs -text
22
+ *.JPG filter=lfs diff=lfs merge=lfs -text
23
+ *.m4a filter=lfs diff=lfs merge=lfs -text
24
+ *.m4v filter=lfs diff=lfs merge=lfs -text
25
+ *.mkv filter=lfs diff=lfs merge=lfs -text
26
+ *.mov filter=lfs diff=lfs merge=lfs -text
27
+ *.mp3 filter=lfs diff=lfs merge=lfs -text
28
+ *.mp4 filter=lfs diff=lfs merge=lfs -text
29
+ *.ogg filter=lfs diff=lfs merge=lfs -text
30
+ *.pages filter=lfs diff=lfs merge=lfs -text
31
+ *.pdf filter=lfs diff=lfs merge=lfs -text
32
+ *.png filter=lfs diff=lfs merge=lfs -text
33
+ *.PNG filter=lfs diff=lfs merge=lfs -text
34
+ *.psd filter=lfs diff=lfs merge=lfs -text
35
+ *.pxm filter=lfs diff=lfs merge=lfs -text
36
+ *.tar filter=lfs diff=lfs merge=lfs -text
37
+ *.tgz filter=lfs diff=lfs merge=lfs -text
38
+ *.tif filter=lfs diff=lfs merge=lfs -text
39
+ *.tiff filter=lfs diff=lfs merge=lfs -text
40
+ *.webm filter=lfs diff=lfs merge=lfs -text
41
+ *.webp filter=lfs diff=lfs merge=lfs -text
42
+ *.woff2 filter=lfs diff=lfs merge=lfs -text
43
+ *.xlsx filter=lfs diff=lfs merge=lfs -text
44
+ *.zip filter=lfs diff=lfs merge=lfs -text
@@ -13,32 +13,33 @@ jobs:
13
13
  strategy:
14
14
  matrix:
15
15
  ruby:
16
- - 3.0
17
- - 3.1
18
- - 3.2
19
- - 3.3
20
- - jruby
21
- - truffleruby
16
+ - "3.1"
17
+ - "3.2"
18
+ - "3.3"
19
+ - "3.4"
20
+ - "4.0"
22
21
  fail-fast: false
23
22
  steps:
24
- - uses: actions/checkout@v3
23
+ - uses: actions/checkout@v4
24
+ with:
25
+ lfs: true
25
26
  - uses: actions/setup-node@v4
26
27
  with:
27
28
  node-version: 20
28
29
  - run: npm install -g tsx
29
- - uses: ruby/setup-ruby@v1
30
+ - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f
30
31
  with:
31
32
  ruby-version: ${{ matrix.ruby }}
32
33
  bundler-cache: true
33
34
  - run: bundle exec standardrb
34
35
  - name: Run tests
35
36
  env:
36
- COVERAGE: ${{ matrix.ruby == '3.3' && '1' || '0' }}
37
- TEST_NODE_PARITY: ${{ matrix.ruby == '3.3' && '1' || '0' }}
37
+ COVERAGE: ${{ matrix.ruby == '4.0' && '1' || '0' }}
38
+ TEST_NODE_PARITY: ${{ matrix.ruby == '4.0' && '1' || '0' }}
38
39
  run: bundle exec rake test
39
40
  - name: Upload coverage to Codecov
40
- if: matrix.ruby == '3.3'
41
- uses: codecov/codecov-action@v5
41
+ if: matrix.ruby == '4.0'
42
+ uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
42
43
  with:
43
44
  token: ${{ secrets.CODECOV_TOKEN }}
44
45
  files: ./coverage/coverage.json
@@ -53,10 +54,12 @@ jobs:
53
54
  TRANSLOADIT_KEY: ${{ secrets.TRANSLOADIT_KEY }}
54
55
  TRANSLOADIT_SECRET: ${{ secrets.TRANSLOADIT_SECRET }}
55
56
  steps:
56
- - uses: actions/checkout@v3
57
- - uses: ruby/setup-ruby@v1
57
+ - uses: actions/checkout@v4
58
+ with:
59
+ lfs: true
60
+ - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f
58
61
  with:
59
- ruby-version: 3.3
62
+ ruby-version: "4.0"
60
63
  bundler-cache: true
61
64
  - name: Ensure e2e credentials are configured
62
65
  if: ${{ env.TRANSLOADIT_KEY == '' || env.TRANSLOADIT_SECRET == '' }}
data/.gitignore CHANGED
@@ -16,4 +16,4 @@ env.sh
16
16
  .env
17
17
  vendor/bundle/
18
18
  .docker-cache/
19
- .cache/rubocop_cache/04e06e0faf5ad652d8bcbcfd85bac5f6c32e711e/3031a80880d8a984708138f0d003f77c4bad2648
19
+ .cache/
data/.standard.yml CHANGED
@@ -0,0 +1,2 @@
1
+ ignore:
2
+ - ".docker-cache/**/*"
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ### 4.0.0 / 2026-09-03
2
+
3
+ - BREAKING: Replace the long-dormant `rest-client` transport with Faraday 2 and `faraday-multipart`.
4
+ - BREAKING: Raise the minimum supported Ruby version from 3.0 to 3.1.
5
+ - Keep HTTP client types out of SDK responses and exceptions while preserving response status, headers, body access, multipart ordering, and rate-limit retries.
6
+ - Add a [v3 to v4 migration guide](MIGRATING_TO_V4.md).
7
+ - Test all Ruby versions from the supported minimum through Ruby 4.0.
8
+
9
+ ### 3.1.2 / 2025-10-29
10
+
11
+ - Compress e2e fixture asset to keep gem size close to previous releases (kvz)
12
+ - Ensure binary assets (images/audio) are marked via `.gitattributes` to avoid line ending mangling (kvz)
13
+ - Document GitHub release helper and add RubyGems publish script (kvz)
14
+
1
15
  ### 3.1.1 / 2025-10-28
2
16
 
3
17
  - Add optional live end-to-end upload harness and CI job for parity verification, defaulted in Docker tests (kvz)
data/CONTRIBUTING.md CHANGED
@@ -71,8 +71,8 @@ The test uploads `chameleon.jpg`, resizes it, and asserts on a real assembly res
71
71
  2. Run the full test suite (including Docker, parity, and e2e checks as needed).
72
72
  3. Commit the release changes and tag:
73
73
  ```bash
74
- git commit -am "Release X.Y.Z"
75
- git tag -a vX.Y.Z -m "Release X.Y.Z"
74
+ git commit -am "Release vX.Y.Z"
75
+ git tag -a vX.Y.Z -m "Release vX.Y.Z"
76
76
  ```
77
77
  4. Push the commit and tag:
78
78
  ```bash
@@ -83,7 +83,11 @@ The test uploads `chameleon.jpg`, resizes it, and asserts on a real assembly res
83
83
  ```bash
84
84
  GEM_HOST_API_KEY=... ./scripts/notify-registry.sh
85
85
  ```
86
- 6. Draft a GitHub release from the new tag and publish the generated notes.
86
+ 6. Publish the GitHub release notes:
87
+ ```bash
88
+ gh release create vX.Y.Z --title "vX.Y.Z" --notes "$(ruby -e 'puts File.read("CHANGELOG.md")[/^### #{ARGV[0].dump.gsub(/\"/, "\\\"")}/, /\A### /m] || "")'"
89
+ ```
90
+ Adjust the notes if needed before publishing.
87
91
 
88
92
  ### RubyGems Credentials
89
93
 
@@ -92,4 +96,3 @@ The test uploads `chameleon.jpg`, resizes it, and asserts on a real assembly res
92
96
  - Export the token as `GEM_HOST_API_KEY` in your environment before running `./scripts/notify-registry.sh`. The script refuses to run if the variable is missing.
93
97
 
94
98
  That’s it! Thank you for contributing.
95
-
data/Dockerfile CHANGED
@@ -1,6 +1,6 @@
1
1
  # syntax=docker/dockerfile:1
2
2
 
3
- FROM ruby:3.3 AS base
3
+ FROM ruby:4.0 AS base
4
4
 
5
5
  RUN apt-get update \
6
6
  && apt-get install -y --no-install-recommends \
@@ -0,0 +1,136 @@
1
+ # Migrating from v3 to v4
2
+
3
+ Version 4 replaces the `rest-client` HTTP transport with Faraday 2. Most applications only use the
4
+ Transloadit API exposed by this gem and do not need code changes. The migration is a major release
5
+ because v3 also delegated undocumented methods to RestClient response objects and exposed
6
+ RestClient exception inheritance.
7
+
8
+ Version 4 requires Ruby 3.1 or newer. The final v3 release allowed Ruby 3.0, so applications still
9
+ running Ruby 3.0 must upgrade Ruby before updating this gem.
10
+
11
+ ## Update the dependency
12
+
13
+ Once v4 is released, update the application Gemfile and bundle:
14
+
15
+ ```ruby
16
+ gem "transloadit", "~> 4.0"
17
+ ```
18
+
19
+ ```shell
20
+ bundle update transloadit
21
+ ```
22
+
23
+ The SDK installs Faraday and its multipart middleware. Applications do not need to add Faraday
24
+ directly. Remove an explicit `rest-client` dependency only if the application does not use it for
25
+ anything else. Version 4 no longer installs or loads the `RestClient` constant on the application's
26
+ behalf.
27
+
28
+ ## Responses
29
+
30
+ Use the SDK-owned response API:
31
+
32
+ ```ruby
33
+ response = transloadit.assembly.get(assembly_id)
34
+
35
+ response["ok"]
36
+ response[:assembly_id]
37
+ response.body
38
+ response.headers
39
+ response.code
40
+ response.status
41
+ ```
42
+
43
+ `code` continues to return the integer HTTP status, and `status` is its new explicit alias. Header
44
+ names remain normalized to lowercase symbols with underscores, for example
45
+ `response.headers[:retry_after]`.
46
+
47
+ HTTP error statuses still return `Transloadit::Response` objects. They are not converted into
48
+ transport exceptions:
49
+
50
+ ```ruby
51
+ response = transloadit.assembly.get(assembly_id)
52
+
53
+ if response.code >= 400
54
+ warn response["error"]
55
+ end
56
+ ```
57
+
58
+ ### Remove raw RestClient response usage
59
+
60
+ In v3, `Transloadit::Response` delegated unknown methods to a `RestClient::Response`. Version 4 no
61
+ longer exposes the underlying HTTP client. Replace calls to RestClient-specific response methods
62
+ with the SDK-owned response API above.
63
+
64
+ For example:
65
+
66
+ ```ruby
67
+ # v3: relied on the delegated RestClient object
68
+ response.raw_headers
69
+
70
+ # v4
71
+ response.headers
72
+ ```
73
+
74
+ If an application relies on another delegated method that has no equivalent, open an issue with the
75
+ use case before upgrading.
76
+
77
+ ## Request failures
78
+
79
+ Network, TLS, and timeout failures now raise `Transloadit::Exception::RequestFailed` instead of a
80
+ RestClient exception:
81
+
82
+ ```ruby
83
+ # v3
84
+ begin
85
+ transloadit.assembly.get(assembly_id)
86
+ rescue RestClient::Exception => error
87
+ warn error.message
88
+ end
89
+
90
+ # v4
91
+ begin
92
+ transloadit.assembly.get(assembly_id)
93
+ rescue Transloadit::Exception::RequestFailed => error
94
+ warn error.message
95
+ end
96
+ ```
97
+
98
+ The original adapter exception is retained as `error.cause` for diagnostics. Avoid branching on its
99
+ class so application behavior does not become coupled to Faraday.
100
+
101
+ ## Rate-limit failures
102
+
103
+ Continue rescuing the SDK exception directly:
104
+
105
+ ```ruby
106
+ begin
107
+ assembly.create!(file)
108
+ rescue Transloadit::Exception::RateLimitReached => error
109
+ retry_after = error.response.wait_time
110
+ end
111
+ ```
112
+
113
+ `RateLimitReached` remains a `StandardError` and retains its Transloadit response through
114
+ `error.response`, but it no longer inherits from `RestClient::RequestEntityTooLarge`. Replace code
115
+ that rescues the RestClient superclass with the SDK exception.
116
+
117
+ ## Uploaded file handles
118
+
119
+ Version 4 does not close path-backed file objects supplied by the caller. Prefer a block so ownership
120
+ is explicit:
121
+
122
+ ```ruby
123
+ File.open("video.mp4", "rb") do |file|
124
+ assembly.create!(file)
125
+ end
126
+ ```
127
+
128
+ Multipart field order is unchanged: `params` and `signature` are sent before file bodies.
129
+
130
+ ## Upgrade checklist
131
+
132
+ - Update the gem and run the application's request and upload tests.
133
+ - Replace rescues of `RestClient::Exception` and `RestClient::RequestEntityTooLarge`.
134
+ - Replace calls to delegated RestClient response methods.
135
+ - Confirm the application closes files that it opens.
136
+ - Remove the direct `rest-client` dependency if nothing else uses it.
data/README.md CHANGED
@@ -19,6 +19,9 @@ _If you run Ruby on Rails and are looking to integrate with the browser for file
19
19
  gem install transloadit
20
20
  ```
21
21
 
22
+ Upgrading from v3? See the [v4 migration guide](MIGRATING_TO_V4.md) for response, exception, and
23
+ file-handle compatibility notes.
24
+
22
25
  ## Usage
23
26
 
24
27
  To get started, you need to require the 'transloadit' gem:
data/chameleon.jpg CHANGED
Binary file
@@ -143,11 +143,22 @@ class Transloadit::Assembly < Transloadit::ApiModel
143
143
  when nil then steps
144
144
  when Hash then steps
145
145
  when Transloadit::Step then steps.to_hash
146
- else
147
- if steps.uniq(&:name) != steps
146
+ when Array
147
+ names = steps.inject([]) do |array, step|
148
+ case step
149
+ when Transloadit::Step then array << step.name
150
+ when Hash then array + step.keys.map(&:to_s)
151
+ else
152
+ raise ArgumentError, "Unsupported array element"
153
+ end
154
+ end
155
+
156
+ if names.uniq != names
148
157
  raise ArgumentError, "There are different Assembly steps using the same name"
149
158
  end
150
159
  steps.inject({}) { |h, s| h.update s }
160
+ else
161
+ raise ArgumentError, "Unsupported steps class"
151
162
  end
152
163
  end
153
164
 
@@ -162,8 +173,6 @@ class Transloadit::Assembly < Transloadit::ApiModel
162
173
  if is_retrying
163
174
  warn "Rate limit reached. Waiting for #{response.wait_time} seconds before retrying."
164
175
  sleep response.wait_time
165
- # RestClient closes file streams at the end of a request.
166
- ios.collect! { |file| File.open file.path }
167
176
  else
168
177
  raise Transloadit::Exception::RateLimitReached.new(response)
169
178
  end
@@ -1,16 +1,24 @@
1
1
  require "transloadit"
2
2
 
3
- require "rest-client"
4
-
5
3
  module Transloadit::Exception
4
+ #
5
+ # Exception raised when an HTTP request cannot be completed.
6
+ # The original transport error is available through +cause+.
7
+ #
8
+ class RequestFailed < StandardError
9
+ end
10
+
6
11
  #
7
12
  # Exception raised when Rate limit error response is returned from the API.
8
13
  # See {Rate Limiting}[https://transloadit.com/docs/api-docs/#rate-limiting]
9
14
  #
10
- class RateLimitReached < RestClient::RequestEntityTooLarge
11
- def default_message
12
- retry_msg = " Retry in #{@response.wait_time} seconds" if @response
13
- "Transloadit Rate Limit Reached.#{retry_msg}"
15
+ class RateLimitReached < StandardError
16
+ # @return [Transloadit::Response] the API response that reported the rate limit
17
+ attr_reader :response
18
+
19
+ def initialize(response)
20
+ @response = response
21
+ super("Transloadit Rate Limit Reached. Retry in #{response.wait_time} seconds")
14
22
  end
15
23
  end
16
24
 
@@ -1,6 +1,8 @@
1
1
  require "transloadit"
2
2
 
3
- require "rest-client"
3
+ require "faraday"
4
+ require "faraday/multipart"
5
+ require "mime/types"
4
6
  require "openssl"
5
7
 
6
8
  #
@@ -47,7 +49,7 @@ class Transloadit::Request
47
49
  #
48
50
  def get(params = {})
49
51
  request! do
50
- api[url.path + to_query(params)].get(API_HEADERS)
52
+ api.get(url.path + to_query(params), nil, API_HEADERS)
51
53
  end
52
54
  end
53
55
 
@@ -60,8 +62,10 @@ class Transloadit::Request
60
62
  #
61
63
  def delete(payload = {})
62
64
  request! do
63
- options = {payload: to_payload(payload)}
64
- api(options)[url.path].delete(API_HEADERS)
65
+ api.delete(url.path) do |request|
66
+ request.headers.update(API_HEADERS)
67
+ request.body = to_payload(payload)
68
+ end
65
69
  end
66
70
  end
67
71
 
@@ -74,7 +78,7 @@ class Transloadit::Request
74
78
  #
75
79
  def post(payload = {})
76
80
  request! do
77
- api[url.path].post(to_payload(payload), API_HEADERS)
81
+ api.post(url.path, to_payload(payload), API_HEADERS)
78
82
  end
79
83
  end
80
84
 
@@ -87,7 +91,7 @@ class Transloadit::Request
87
91
  #
88
92
  def put(payload = {})
89
93
  request! do
90
- api[url.path].put(to_payload(payload), API_HEADERS)
94
+ api.put(url.path, to_payload(payload), API_HEADERS)
91
95
  end
92
96
  end
93
97
 
@@ -118,12 +122,20 @@ class Transloadit::Request
118
122
  # hostname, then the hostname is used as the base endpoint of the API.
119
123
  # Otherwise uses the class-level API base.
120
124
  #
121
- # @return [RestClient::Resource] the API endpoint for this instance
125
+ # @return [Faraday::Connection] the API endpoint for this instance
122
126
  #
123
- def api(options = {})
127
+ def api
124
128
  @api ||= case url.host
125
- when String then RestClient::Resource.new("#{url.scheme}://#{url.host}", options)
126
- else RestClient::Resource.new("#{API_ENDPOINT.scheme}://#{API_ENDPOINT.host}", options)
129
+ when String then connection_for("#{url.scheme}://#{url.host}")
130
+ else connection_for("#{API_ENDPOINT.scheme}://#{API_ENDPOINT.host}")
131
+ end
132
+ end
133
+
134
+ def connection_for(base_url)
135
+ Faraday.new(url: base_url) do |connection|
136
+ connection.request :multipart
137
+ connection.request :url_encoded
138
+ connection.adapter Faraday.default_adapter
127
139
  end
128
140
  end
129
141
 
@@ -151,12 +163,33 @@ class Transloadit::Request
151
163
  sig = signature(new_payload[:params])
152
164
  new_payload[:signature] = sig unless sig.nil?
153
165
 
154
- # Copy all values, excluding :params and :signature keys.
155
- new_payload.update payload.reject { |key, _| key == :params || key == :signature }
166
+ payload.each do |key, value|
167
+ next if key == :params || key == :signature
168
+
169
+ new_payload[key] = upload?(value) ? multipart_file(value) : value
170
+ end
156
171
 
157
172
  new_payload
158
173
  end
159
174
 
175
+ def upload?(value)
176
+ value.respond_to?(:read)
177
+ end
178
+
179
+ def multipart_file(file)
180
+ path = file.path if file.respond_to?(:path)
181
+ filename = file.original_filename if file.respond_to?(:original_filename)
182
+ filename = File.basename(path) if filename.to_s.empty? && path
183
+ filename = "upload" if filename.to_s.empty?
184
+
185
+ content_type = file.content_type if file.respond_to?(:content_type)
186
+ content_type = MIME::Types.type_for(path).first&.content_type if content_type.to_s.empty? && path
187
+ content_type = "application/octet-stream" if content_type.to_s.empty?
188
+
189
+ source = path || file
190
+ Faraday::Multipart::FilePart.new(source, content_type, filename)
191
+ end
192
+
160
193
  #
161
194
  # Updates the GET/DELETE params hash to be compliant with the Transloadit
162
195
  # API by URI escaping and encoding the params hash, and attaching a
@@ -181,18 +214,17 @@ class Transloadit::Request
181
214
  end
182
215
 
183
216
  #
184
- # Wraps a request's results in a Transloadit::Response, even if an exception
185
- # is raised by RestClient.
217
+ # Wraps a request's result in a Transloadit::Response.
186
218
  #
187
219
  def request!(&request)
188
- Transloadit::Response.new yield
189
- rescue RestClient::Exception => e
190
- # The response attribute can be nil, for example for RestClient::Exceptions::OpenTimeout exceptions.
191
- # Then, we cannot convert them into a Transloadit::Response, so instead we raise them again for
192
- # the user to be visible.
193
- # See https://github.com/transloadit/ruby-sdk/issues/53
194
- raise e if e.response.nil?
195
- Transloadit::Response.new e.response
220
+ response = yield
221
+ Transloadit::Response.new(
222
+ body: response.body,
223
+ headers: response.headers,
224
+ status: response.status
225
+ )
226
+ rescue Faraday::Error
227
+ raise Transloadit::Exception::RequestFailed, "Transloadit request failed"
196
228
  end
197
229
 
198
230
  #
@@ -1,20 +1,30 @@
1
1
  require "transloadit"
2
2
 
3
- require "rest-client"
4
- require "delegate"
5
-
6
- class Transloadit::Response < Delegator
3
+ class Transloadit::Response
7
4
  autoload :Assembly, "transloadit/response/assembly"
8
5
 
9
6
  #
10
- # Creates an enhanced response wrapped around a RestClient response.
7
+ # Creates a response without exposing the underlying HTTP client.
11
8
  #
12
- # @param [RestClient::Response] response the JSON response to wrap
9
+ # @param [String] body the raw response body
10
+ # @param [Hash] headers the response headers
11
+ # @param [Integer] status the HTTP response status
13
12
  #
14
- def initialize(response)
15
- __setobj__(response)
13
+ def initialize(body:, headers:, status:)
14
+ @raw_body = body
15
+ @headers = normalize_headers(headers)
16
+ @status = status
16
17
  end
17
18
 
19
+ # @return [Hash] normalized response headers
20
+ attr_reader :headers
21
+
22
+ # @return [Integer] the HTTP response status
23
+ attr_reader :status
24
+
25
+ # RestClient exposed the status through +code+ in previous SDK versions.
26
+ alias_method :code, :status
27
+
18
28
  #
19
29
  # Returns the attribute from the JSON response.
20
30
  #
@@ -31,7 +41,7 @@ class Transloadit::Response < Delegator
31
41
  # @return [Hash] the parsed JSON body hash
32
42
  #
33
43
  def body
34
- MultiJson.load __getobj__.body
44
+ MultiJson.load @raw_body
35
45
  end
36
46
 
37
47
  #
@@ -56,36 +66,28 @@ class Transloadit::Response < Delegator
56
66
  self
57
67
  end
58
68
 
59
- protected
60
-
61
- #
62
- # The object to delegate method calls to.
63
- #
64
- # @return [RestClient::Response]
65
- #
66
- def __getobj__
67
- @response
68
- end
69
-
70
69
  #
71
- # Sets the object to delegate method calls to.
70
+ # Replaces this response's HTTP data with another response's data.
72
71
  #
73
- # @param [RestClient::Response] response the response to delegate to
74
- # @return [RestClient::Response] the delegated response
75
- #
76
- def __setobj__(response)
77
- @response = response
78
- end
79
-
80
- #
81
- # Replaces the object this instance delegates to with the one the other
82
- # object uses.
83
- #
84
- # @param [Delegator] other the object whose delegate to use
72
+ # @param [Transloadit::Response] other the response whose data to use
85
73
  # @return [Transloadit::Response] this response
86
74
  #
87
75
  def replace(other)
88
- __setobj__ other.__getobj__
76
+ @raw_body = other.raw_body
77
+ @headers = other.headers
78
+ @status = other.status
89
79
  self
90
80
  end
81
+
82
+ protected
83
+
84
+ attr_reader :raw_body
85
+
86
+ private
87
+
88
+ def normalize_headers(headers)
89
+ headers.to_h.each_with_object({}) do |(name, value), normalized|
90
+ normalized[name.to_s.downcase.tr("-", "_").to_sym] = value
91
+ end
92
+ end
91
93
  end
@@ -1,3 +1,3 @@
1
1
  class Transloadit
2
- VERSION = "3.1.1"
2
+ VERSION = "4.0.0"
3
3
  end
data/lib/transloadit.rb CHANGED
@@ -2,7 +2,7 @@ require "multi_json"
2
2
  require "date"
3
3
  require "json"
4
4
  require "openssl"
5
- require "cgi"
5
+ require "cgi/escape"
6
6
  require "uri"
7
7
 
8
8
  #