restforce 5.3.1 → 6.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7156aa3b1821199121b06cbf84b2c00039efeddc17cc58cbe1d8454bddbf1eb7
4
- data.tar.gz: 8cfbd9d725041f02fa8abd45cc08254a38e563dce206747f0c778bd6c91c3306
3
+ metadata.gz: 06ba6ff782797da12181fade1eb6d25cec0da4395a0880080d684a6c8d0c928e
4
+ data.tar.gz: 17854adb01066aa6d09c784adeecee764b530afff0083297162c0d2633fac38f
5
5
  SHA512:
6
- metadata.gz: 5cf147d56213c10144b4e7819f6e5a62961a84c134b66f7b506d4f76bb8aad4563c7d69b39702e06b468441c35dafac4c8e1d74a65c3c76e7c47cab76ef58080
7
- data.tar.gz: 1351ded2015aca8bd6c8f89ab8c28c684c125b7aa2fd0c077660072064e96b4a1d917d401c9df1cd99873d12780866ba9811d23e228d185e8b6dc426c14c6aaa
6
+ metadata.gz: 8cb18b0f488c6e793b2c1a64e54e982f08b1739522ae3bb3a5f7dd8837ffe62c05506365731f9040b25dd396b7ad5f3aff143dd9476fd0f2be475bf23623547f
7
+ data.tar.gz: 7445f7337587cc19c61743abe80dad16c3d1b2c10527691d6e33edb65a023dcd4afb32db9a569405c43a7878c3cba32fb2426dd50264d7b56cfc95e5bdb2d203
@@ -1,15 +1,12 @@
1
1
  name: 'Build'
2
- on:
3
- push:
4
- branches: [main]
5
- pull_request:
6
- branches: [main]
2
+ on: push
7
3
  jobs:
8
4
  lint-and-test:
9
5
  runs-on: ubuntu-latest
10
6
  strategy:
7
+ fail-fast: false
11
8
  matrix:
12
- ruby_version: ['2.6', '2.7', '3.0', '3.1', '3.2.0-preview1']
9
+ ruby_version: ['2.7', '3.0', '3.1', '3.2.0-preview1']
13
10
  steps:
14
11
  - name: Checkout code
15
12
  uses: actions/checkout@v3
@@ -1,15 +1,16 @@
1
1
  name: 'Test against supported Faraday minor versions'
2
- on:
3
- push:
4
- branches: [main]
5
- pull_request:
6
- branches: [main]
2
+ on: push
7
3
  jobs:
8
4
  lint-and-test:
9
5
  runs-on: ubuntu-latest
10
6
  strategy:
7
+ fail-fast: false
11
8
  matrix:
12
- faraday_version: ['1.0.1', '1.1.0', '1.2.0', '1.3.1', '1.4.1', '1.5.1', '1.6.0', '1.7.2', '1.8.0', '1.9.3', '1.10.0']
9
+ # Normally, we only test the most recent patch version for any given minor version.
10
+ # For v2.0.x, we test v2.0.0 and v2.0.1 because v2.0.0 has a special behaviour where
11
+ # the Net::HTTP adapter is not included. See
12
+ # https://github.com/lostisland/faraday/blob/main/UPGRADING.md#faraday-20.
13
+ faraday_version: ['1.1.0', '1.2.0', '1.3.1', '1.4.1', '1.5.1', '1.6.0', '1.7.2', '1.8.0', '1.9.3', '1.10.0', '2.0.0', '2.0.1', '2.1.0', '2.2.0', '2.3.0', '2.4.0']
13
14
  env:
14
15
  FARADAY_VERSION: ~> ${{ matrix.faraday_version }}
15
16
  steps:
data/.rubocop.yml CHANGED
@@ -8,7 +8,7 @@ AllCops:
8
8
  - .*/**/*
9
9
  - vendor/**/*
10
10
  NewCops: enable
11
- TargetRubyVersion: 2.6
11
+ TargetRubyVersion: 2.7
12
12
 
13
13
  # Limit lines to 90 characters.
14
14
  Layout/LineLength:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ # 6.0.0.rc.1 (Aug 4 2022)
2
+
3
+ *This version is a release candidate. Once we have gathered feedback from users and are confident that it works as expected, we will release a final `v6.0.0` version.*
4
+
5
+ __This version contains breaking changes. For help with upgrading, see [`UPGRADING.md`](https://github.com/restforce/restforce/blob/v6.0.0.rc.1/UPGRADING.md).__
6
+
7
+ * __⚠️ Drop support for Ruby 2.6__, since [Ruby 2.6 has reached its end-of-life](https://www.ruby-lang.org/en/downloads/) (@timrogers)
8
+ * __⚠️ Drop compatability with `faraday` versions before `v1.1.0`__ (@timrogers)
9
+ * Add support for `faraday` versions `v2.0.0` onwards (@timrogers)
10
+
1
11
  # 5.3.1 (Jul 19 2022)
2
12
 
3
13
  * Handle the `EXCEEDED_ID_LIMIT` error returned by the Salesforce API (@timrogers, @yashshah1)
data/Gemfile CHANGED
@@ -3,8 +3,10 @@
3
3
  source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
+ faraday_version = ENV.fetch('FARADAY_VERSION', '~> 1.8.0')
7
+
6
8
  # Enable us to explicitly pick a Faraday version when running tests
7
- gem 'faraday', ENV.fetch('FARADAY_VERSION', '~> 1.8.0')
9
+ gem 'faraday', faraday_version
8
10
  gem 'faye' unless RUBY_PLATFORM == 'java'
9
11
  gem 'guard-rspec'
10
12
  gem 'guard-rubocop'
@@ -14,6 +16,8 @@ gem 'rspec', '~> 3.11.0'
14
16
  gem 'rspec-collection_matchers', '~> 1.2.0'
15
17
  gem 'rspec-its', '~> 1.3.0'
16
18
  gem 'rspec_junit_formatter', '~> 0.5.1'
17
- gem 'rubocop', '~> 1.31.2'
19
+ gem 'rubocop', '~> 1.32.0'
18
20
  gem 'simplecov', '~> 0.21.2'
19
- gem 'webmock', '~> 3.14.0'
21
+ gem 'webmock', '~> 3.16.0'
22
+
23
+ gem 'faraday-typhoeus', '~> 0.2.1' unless faraday_version.start_with?("~> 1")
data/UPGRADING.md CHANGED
@@ -1,3 +1,32 @@
1
+ # Upgrading from Restforce 5.x to 6.x
2
+
3
+ __There are two breaking changes introduced in Restforce 6.x__. In this guide, you'll learn about these changes and what you should check in your code to make sure that it will work with the latest version of the library.
4
+
5
+ ## Versions of `faraday` before `v1.1.0` are no longer supported
6
+
7
+ __Likelyhood of impact__: Moderate
8
+
9
+ Restforce uses a gem called [`faraday`](https://github.com/lostisland/faraday) to make HTTP requests to Salesforce.
10
+
11
+ Up until now, Restforce has supported Faraday versions between v0.9.0 and v1.10.0.
12
+
13
+ In Restforce 6.x, we drop support for Faraday versions before v1.1.0, and add support for Faraday v2.x.
14
+
15
+ This will allow you to use the latest versions of Faraday and benefit from security patches, new features, etc., but you may need to adapt your code. The impact of this change will depend on your project:
16
+
17
+ * If Restforce is the only part of your project using Faraday - that is, your own code doesn't use Faraday and none of your other gems use Faraday - then you shouldn't need to do anything special. Just upgrade Restforce, and everything should be handled automatically.
18
+ * If your own code uses Faraday or another gem you use depends on Faraday, and you're currently using a Faraday version before v1.1.0, you will need to upgrade your Faraday version. If possible, you should upgrade to the latest version (v2.4.0 at the time of writing). This may require you to adapt your code (see [here](https://github.com/lostisland/faraday/blob/main/UPGRADING.md) for Faraday's instructions) or upgrade other gems you depend on.
19
+
20
+ ## Ruby 2.6 is no longer supported
21
+
22
+ __Likelyhood of impact__: Moderate
23
+
24
+ Ruby 2.6 is no longer officially supported as an active version of the Ruby language. That means that it will not receive patches and security fixes.
25
+
26
+ Accordingly, we've dropped support for Ruby 2.6 and earlier in the Restforce library. The gemspec now specifies that only 2.7 onwards is supported, and this will be enforced by RubyGems.
27
+
28
+ Before you update to Restforce 6.x, you'll need to switch to Ruby 2.7 or later. The current version of Ruby at the time of wriing is 3.1.
29
+
1
30
  # Upgrading from Restforce 4.x to 5.x
2
31
 
3
32
  __There are three breaking changes introduced in Restforce 5.x__. In this guide, you'll learn about these changes and what you should check in your code to make sure that it will work with the latest version of the library.
@@ -43,7 +43,7 @@ module Restforce
43
43
  # Caches GET requests.
44
44
  builder.use Restforce::Middleware::Caching, cache, options if cache
45
45
  # Follows 30x redirects.
46
- builder.use FaradayMiddleware::FollowRedirects
46
+ builder.use Faraday::FollowRedirects::Middleware
47
47
  # Raises errors for 40x responses.
48
48
  builder.use Restforce::Middleware::RaiseError
49
49
  # Parses returned JSON response into a hash.
@@ -1,14 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  case Faraday::VERSION
4
- when /\A0\./
5
- require 'faraday/upload_io'
6
4
  when /\A1\.[0-8]\./
7
5
  # Faraday 1.x versions before 1.9 - not matched by
8
6
  # the previous clause - use `FilePart` (which must be explicitly
9
7
  # required)
10
8
  require 'faraday/file_part'
11
- when /\A1\./
9
+ when /\A[12]\./
12
10
  # Later 1.x versions from 1.9 onwards automatically include the
13
11
  # `faraday-multipart` gem, which includes `Faraday::FilePart`
14
12
  require 'faraday/multipart'
@@ -16,7 +14,6 @@ else
16
14
  raise "Unexpected Faraday version #{Faraday::VERSION} - not sure how to set up " \
17
15
  "multipart support"
18
16
  end
19
-
20
17
  module Restforce
21
18
  if defined?(::Faraday::FilePart)
22
19
  FilePart = Faraday::FilePart
@@ -49,7 +49,7 @@ module Restforce
49
49
  @connection ||= Faraday.new(faraday_options) do |builder|
50
50
  builder.use Faraday::Request::UrlEncoded
51
51
  builder.use Restforce::Middleware::Mashify, nil, @options
52
- builder.use FaradayMiddleware::FollowRedirects
52
+ builder.use Faraday::FollowRedirects::Middleware
53
53
  builder.response :json
54
54
 
55
55
  if Restforce.log?
@@ -1,30 +1,155 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ #
4
+ # Taken from `lib/faraday_middleware/response/caching.rb` in the `faraday_middleware`
5
+ # gem (<https://github.com/lostisland/faraday_middleware/blob/784b4f8/lib/faraday_middleware/response/caching.rb>).
6
+ #
7
+ # Includes some small modifications to allow the cache to be cleared in
8
+ # `#without_caching` mode, replicating traditional Restforce behaviour.
9
+ #
10
+ # Copyright (c) 2011 Erik Michaels-Ober, Wynn Netherland, et al.
11
+ # Licensed under the MIT License.
12
+ #
13
+ require 'faraday'
14
+ require 'forwardable'
15
+ require 'digest/sha1'
16
+
3
17
  module Restforce
4
- class Middleware::Caching < FaradayMiddleware::Caching
5
- def call(env)
6
- expire(cache_key(env)) unless use_cache?
7
- super
18
+ # Public: Caches GET responses and pulls subsequent ones from the cache.
19
+ class Middleware::Caching < Faraday::Middleware
20
+ attr_reader :cache
21
+
22
+ # Internal: List of status codes that can be cached:
23
+ # * 200 - 'OK'
24
+ # * 203 - 'Non-Authoritative Information'
25
+ # * 300 - 'Multiple Choices'
26
+ # * 301 - 'Moved Permanently'
27
+ # * 302 - 'Found'
28
+ # * 404 - 'Not Found'
29
+ # * 410 - 'Gone'
30
+ CACHEABLE_STATUS_CODES = [200, 203, 300, 301, 302, 404, 410].freeze
31
+
32
+ extend Forwardable
33
+ def_delegators :'Faraday::Utils', :parse_query, :build_query
34
+
35
+ # Public: initialize the middleware.
36
+ #
37
+ # cache - An object that responds to read and write (default: nil).
38
+ # options - An options Hash (default: {}):
39
+ # :ignore_params - String name or Array names of query
40
+ # params that should be ignored when forming
41
+ # the cache key (default: []).
42
+ # :write_options - Hash of settings that should be passed as the
43
+ # third options parameter to the cache's #write
44
+ # method. If not specified, no options parameter
45
+ # will be passed.
46
+ # :full_key - Boolean - use full URL as cache key:
47
+ # (url.host + url.request_uri)
48
+ # :status_codes - Array of http status code to be cache
49
+ # (default: CACHEABLE_STATUS_CODE)
50
+ #
51
+ # Yields if no cache is given. The block should return a cache object.
52
+ def initialize(app, cache = nil, options = {})
53
+ super(app)
54
+ if cache.is_a?(Hash) && block_given?
55
+ options = cache
56
+ cache = nil
57
+ end
58
+ @cache = cache || yield
59
+ @options = options
8
60
  end
9
61
 
10
- def expire(key)
11
- cache&.delete(key)
62
+ def call(env)
63
+ # Taken from `Restforce::Middleware::Caching` implementation
64
+ # before we switched away from the `faraday_middleware` gem.
65
+ # See https://github.com/restforce/restforce/blob/a08b9d6c5e277bd7111ffa7ed50465dd49c05fab/lib/restforce/middleware/caching.rb.
66
+ cache&.delete(cache_key(env)) unless use_cache?
67
+
68
+ if env[:method] == :get
69
+ if env[:parallel_manager]
70
+ # callback mode
71
+ cache_on_complete(env)
72
+ else
73
+ # synchronous mode
74
+ key = cache_key(env)
75
+ unless (response = cache.read(key)) && response
76
+ response = @app.call(env)
77
+ store_response_in_cache(key, response)
78
+ end
79
+ finalize_response(response, env)
80
+ end
81
+ else
82
+ @app.call(env)
83
+ end
12
84
  end
13
85
 
14
- # We don't want to cache requests for different clients, so append the
15
- # oauth token to the cache key.
16
86
  def cache_key(env)
17
- super(env) + hashed_auth_header(env)
87
+ url = env[:url].dup
88
+ if url.query && params_to_ignore.any?
89
+ params = parse_query url.query
90
+ params.reject! { |k,| params_to_ignore.include? k }
91
+ url.query = params.any? ? build_query(params) : nil
92
+ end
93
+ url.normalize!
94
+ digest = full_key? ? url.host + url.request_uri : url.request_uri
95
+ Digest::SHA1.hexdigest(digest)
18
96
  end
19
97
 
20
- def use_cache?
21
- @options[:use_cache]
98
+ def params_to_ignore
99
+ @params_to_ignore ||= Array(@options[:ignore_params]).map(&:to_s)
100
+ end
101
+
102
+ def full_key?
103
+ @full_key ||= @options[:full_key]
22
104
  end
23
105
 
24
- def hashed_auth_header(env)
25
- Digest::SHA1.hexdigest(
26
- env[:request_headers][Restforce::Middleware::Authorization::AUTH_HEADER]
27
- )
106
+ def custom_status_codes
107
+ @custom_status_codes ||= begin
108
+ codes = CACHEABLE_STATUS_CODES & Array(@options[:status_codes]).map(&:to_i)
109
+ codes.any? ? codes : CACHEABLE_STATUS_CODES
110
+ end
111
+ end
112
+
113
+ def cache_on_complete(env)
114
+ key = cache_key(env)
115
+ if (cached_response = cache.read(key))
116
+ finalize_response(cached_response, env)
117
+ else
118
+ # response.status is nil at this point
119
+ # any checks need to be done inside on_complete block
120
+ @app.call(env).on_complete do |response_env|
121
+ store_response_in_cache(key, response_env.response)
122
+ response_env
123
+ end
124
+ end
125
+ end
126
+
127
+ def store_response_in_cache(key, response)
128
+ return unless custom_status_codes.include?(response.status)
129
+
130
+ if @options[:write_options]
131
+ cache.write(key, response, @options[:write_options])
132
+ else
133
+ cache.write(key, response)
134
+ end
135
+ end
136
+
137
+ def finalize_response(response, env)
138
+ response = response.dup if response.frozen?
139
+ env[:response] = response
140
+ unless env[:response_headers]
141
+ env.update response.env
142
+ # FIXME: omg hax
143
+ response.instance_variable_set('@env', env)
144
+ end
145
+ response
146
+ end
147
+
148
+ # Taken from `Restforce::Middleware::Caching` implementation
149
+ # before we switched away from the `faraday_middleware` gem.
150
+ # See https://github.com/restforce/restforce/blob/a08b9d6c5e277bd7111ffa7ed50465dd49c05fab/lib/restforce/middleware/caching.rb.
151
+ def use_cache?
152
+ @options[:use_cache]
28
153
  end
29
154
  end
30
155
  end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Adapted from `lib/faraday/request/json.rb` in the `faraday`
5
+ # gem (<https://github.com/lostisland/faraday/blob/5366029282968d59980a182258f8c2b0212721c8/lib/faraday/request/json.rb>).
6
+ #
7
+ # We use this because we want to support Faraday 1.x and Faraday 2.x.
8
+ # Faraday 2.x has the JSON middlewares included, but Faraday 1.x doesn't,
9
+ # forcing you to use the `faraday_middleware` gem. This approach allows us
10
+ # to support both.
11
+ #
12
+ # Copyright (c) 2009-2022 Rick Olson, Zack Hobson
13
+ # Licensed under the MIT License.
14
+ #
15
+ require 'json'
16
+
17
+ module Restforce
18
+ # Request middleware that encodes the body as JSON.
19
+ #
20
+ # Processes only requests with matching Content-type or those without a type.
21
+ # If a request doesn't have a type but has a body, it sets the Content-type
22
+ # to JSON MIME-type.
23
+ #
24
+ # Doesn't try to encode bodies that already are in string form.
25
+ # rubocop:disable Style/ClassAndModuleChildren
26
+ class Middleware::JsonRequest < Faraday::Middleware
27
+ # rubocop:enable Style/ClassAndModuleChildren
28
+
29
+ # This is the only line that differs substantively from the version in
30
+ # Faraday. In Faraday, this refers to a Faraday constant.
31
+ CONTENT_TYPE = 'Content-Type'
32
+
33
+ MIME_TYPE = 'application/json'
34
+ MIME_TYPE_REGEX = %r{^application/(vnd\..+\+)?json$}.freeze
35
+
36
+ #
37
+ # Taken from `lib/faraday/middleware.rb` in the `faraday`
38
+ # gem (<https://github.com/lostisland/faraday/blob/08b7d4d/lib/faraday/middleware.rb>),
39
+ # with a tiny adaptation to refer to the `@app` instance
40
+ # variable rather than expecting an `attr_reader` to exist.
41
+ #
42
+ # In Faraday versions before v1.2.0, `#call` is missing.
43
+ #
44
+ # Copyright (c) 2009-2022 Rick Olson, Zack Hobson
45
+ # Licensed under the MIT License.
46
+ #
47
+ def call(env)
48
+ on_request(env) if respond_to?(:on_request)
49
+ @app.call(env).on_complete do |environment|
50
+ on_complete(environment) if respond_to?(:on_complete)
51
+ end
52
+ end
53
+
54
+ def on_request(env)
55
+ match_content_type(env) do |data|
56
+ env[:body] = encode(data)
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def encode(data)
63
+ ::JSON.generate(data)
64
+ end
65
+
66
+ def match_content_type(env)
67
+ return unless process_request?(env)
68
+
69
+ env[:request_headers][CONTENT_TYPE] ||= MIME_TYPE
70
+ yield env[:body] unless env[:body].respond_to?(:to_str)
71
+ end
72
+
73
+ def process_request?(env)
74
+ type = request_type(env)
75
+ body?(env) && (type.empty? || type.match?(MIME_TYPE_REGEX))
76
+ end
77
+
78
+ def body?(env)
79
+ (body = env[:body]) && !(body.respond_to?(:to_str) && body.empty?)
80
+ end
81
+
82
+ def request_type(env)
83
+ type = env[:request_headers][CONTENT_TYPE].to_s
84
+ type = type.split(';', 2).first if type.index(';')
85
+ type
86
+ end
87
+ end
88
+ end
89
+
90
+ Faraday::Request.register_middleware(json: Restforce::Middleware::JsonRequest)
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Adapted from `lib/faraday/response/json.rb` in the `faraday`
5
+ # gem (<https://github.com/lostisland/faraday/blob/5366029/lib/faraday/response/json.rb>).
6
+ #
7
+ # Copyright (c) 2009-2022 Rick Olson, Zack Hobson
8
+ # Licensed under the MIT License.
9
+ #
10
+
11
+ require 'json'
12
+
13
+ module Restforce
14
+ # rubocop:disable Style/ClassAndModuleChildren
15
+ class Middleware::JsonResponse < Faraday::Middleware
16
+ # rubocop:enable Style/ClassAndModuleChildren
17
+
18
+ # This is the only line that differs substantively from the version in
19
+ # Faraday. In Faraday, this refers to a Faraday constant.
20
+ CONTENT_TYPE = 'Content-Type'
21
+
22
+ def initialize(app = nil, parser_options: nil, content_type: /\bjson$/,
23
+ preserve_raw: false)
24
+ super(app)
25
+ @parser_options = parser_options
26
+ @content_types = Array(content_type)
27
+ @preserve_raw = preserve_raw
28
+ end
29
+
30
+ #
31
+ # Taken from `lib/faraday/middleware.rb` in the `faraday`
32
+ # gem (<https://github.com/lostisland/faraday/blob/08b7d4d/lib/faraday/middleware.rb>),
33
+ # with a tiny adaptation to refer to the `@app` instance
34
+ # variable rather than expecting an `attr_reader` to exist.
35
+ #
36
+ # In Faraday versions before v1.2.0, `#call` is missing.
37
+ #
38
+ # Copyright (c) 2009-2022 Rick Olson, Zack Hobson
39
+ # Licensed under the MIT License.
40
+ #
41
+ def call(env)
42
+ on_request(env) if respond_to?(:on_request)
43
+ @app.call(env).on_complete do |environment|
44
+ on_complete(environment) if respond_to?(:on_complete)
45
+ end
46
+ end
47
+
48
+ def on_complete(env)
49
+ process_response(env) if parse_response?(env)
50
+ end
51
+
52
+ private
53
+
54
+ def process_response(env)
55
+ env[:raw_body] = env[:body] if @preserve_raw
56
+ env[:body] = parse(env[:body])
57
+ rescue StandardError, SyntaxError => e
58
+ raise Faraday::ParsingError.new(e, env[:response])
59
+ end
60
+
61
+ def parse(body)
62
+ ::JSON.parse(body, @parser_options || {}) unless body.strip.empty?
63
+ end
64
+
65
+ def parse_response?(env)
66
+ process_response_type?(env) &&
67
+ env[:body].respond_to?(:to_str)
68
+ end
69
+
70
+ def process_response_type?(env)
71
+ type = response_type(env)
72
+ @content_types.empty? || @content_types.any? do |pattern|
73
+ pattern.is_a?(Regexp) ? type.match?(pattern) : type == pattern
74
+ end
75
+ end
76
+
77
+ def response_type(env)
78
+ type = env[:response_headers][CONTENT_TYPE].to_s
79
+ type = type.split(';', 2).first if type.index(';')
80
+ type
81
+ end
82
+ end
83
+ end
84
+
85
+ Faraday::Response.register_middleware(json: Restforce::Middleware::JsonResponse)
@@ -3,7 +3,7 @@
3
3
  require 'forwardable'
4
4
 
5
5
  module Restforce
6
- class Middleware::Logger < Faraday::Response::Middleware
6
+ class Middleware::Logger < Faraday::Middleware
7
7
  extend Forwardable
8
8
 
9
9
  def initialize(app, logger, options)
@@ -24,7 +24,11 @@ module Restforce
24
24
  headers: env[:request_headers],
25
25
  body: env[:body]
26
26
  end
27
- super
27
+
28
+ on_request(env) if respond_to?(:on_request)
29
+ @app.call(env).on_complete do |environment|
30
+ on_complete(environment) if respond_to?(:on_complete)
31
+ end
28
32
  end
29
33
 
30
34
  def on_complete(env)
@@ -1,7 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Restforce
4
- class Middleware::RaiseError < Faraday::Response::Middleware
4
+ class Middleware::RaiseError < Faraday::Middleware
5
+ # Required for Faraday versions pre-v1.2.0 which do not include
6
+ # an implementation of `#call` by default
7
+ def call(env)
8
+ on_request(env) if respond_to?(:on_request)
9
+ @app.call(env).on_complete do |environment|
10
+ on_complete(environment) if respond_to?(:on_complete)
11
+ end
12
+ end
13
+
5
14
  def on_complete(env)
6
15
  @env = env
7
16
  case env[:status]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Restforce
4
- VERSION = '5.3.1'
4
+ VERSION = '6.0.0.rc.1'
5
5
  end
data/lib/restforce.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'faraday'
4
- require 'faraday_middleware'
4
+ require 'faraday/follow_redirects'
5
5
  require 'json'
6
6
  require 'jwt'
7
7
 
@@ -64,21 +64,23 @@ module Restforce
64
64
  EntityTooLargeError = Class.new(ResponseError)
65
65
 
66
66
  require 'restforce/error_code'
67
+ require 'restforce/middleware/json_request'
68
+ require 'restforce/middleware/json_response'
67
69
 
68
70
  class << self
69
71
  # Alias for Restforce::Data::Client.new
70
72
  #
71
73
  # Shamelessly pulled from https://github.com/pengwynn/octokit/blob/master/lib/octokit.rb
72
- def new(*args, &block)
73
- data(*args, &block)
74
+ def new(...)
75
+ data(...)
74
76
  end
75
77
 
76
- def data(*args, &block)
77
- Restforce::Data::Client.new(*args, &block)
78
+ def data(...)
79
+ Restforce::Data::Client.new(...)
78
80
  end
79
81
 
80
- def tooling(*args, &block)
81
- Restforce::Tooling::Client.new(*args, &block)
82
+ def tooling(...)
83
+ Restforce::Tooling::Client.new(...)
82
84
  end
83
85
 
84
86
  # Helper for decoding signed requests.
data/restforce.gemspec CHANGED
@@ -22,10 +22,12 @@ Gem::Specification.new do |gem|
22
22
  'rubygems_mfa_required' => 'true'
23
23
  }
24
24
 
25
- gem.required_ruby_version = '>= 2.6'
25
+ gem.required_ruby_version = '>= 2.7'
26
26
 
27
- gem.add_dependency 'faraday', '<= 1.10.0', '>= 0.9.0'
28
- gem.add_dependency 'faraday_middleware', ['>= 0.8.8', '<= 2.0']
27
+ gem.add_dependency 'faraday', '< 2.5.0', '>= 1.1.0'
28
+ gem.add_dependency 'faraday-follow_redirects', '<= 0.3.0', '< 1.0.0'
29
+ gem.add_dependency 'faraday-multipart', '>= 1.0.0', '< 2.0.0'
30
+ gem.add_dependency 'faraday-net_http', '< 3.0.0'
29
31
  gem.add_dependency 'hashie', '>= 1.2.0', '< 6.0'
30
32
  gem.add_dependency 'jwt', ['>= 1.5.6']
31
33
  end
@@ -367,7 +367,11 @@ shared_examples_for Restforce::AbstractClient do
367
367
  with_body: "grant_type=password&client_id=client_id" \
368
368
  "&client_secret=client_secret&username=foo" \
369
369
  "&password=barsecurity_token"
370
- ).to_return(status: 200, body: fixture(:auth_success_response))
370
+ ).to_return(
371
+ status: 200,
372
+ body: fixture(:auth_success_response),
373
+ headers: { "Content-Type" => "application/json" }
374
+ )
371
375
  end
372
376
 
373
377
  after do
@@ -419,7 +423,11 @@ shared_examples_for Restforce::AbstractClient do
419
423
  with_body: "grant_type=password&client_id=client_id" \
420
424
  "&client_secret=client_secret&username=foo&" \
421
425
  "password=barsecurity_token"
422
- ).to_return(status: 200, body: fixture(:auth_success_response))
426
+ ).to_return(
427
+ status: 200,
428
+ body: fixture(:auth_success_response),
429
+ headers: { "Content-Type" => "application/json" }
430
+ )
423
431
  end
424
432
 
425
433
  subject { lambda { client.query('SELECT some, fields FROM object') } }
@@ -443,7 +451,11 @@ shared_examples_for Restforce::AbstractClient do
443
451
  @login = stub_login_request(
444
452
  with_body: "grant_type=password&client_id=client_id&client_secret=" \
445
453
  "client_secret&username=foo&password=barsecurity_token"
446
- ).to_return(status: 200, body: fixture(:auth_success_response))
454
+ ).to_return(
455
+ status: 200,
456
+ body: fixture(:auth_success_response),
457
+ headers: { "Content-Type" => "application/json" }
458
+ )
447
459
  end
448
460
 
449
461
  after do
@@ -73,7 +73,7 @@ describe Restforce::Concerns::Connection do
73
73
  Restforce.stub(log?: true)
74
74
  end
75
75
 
76
- it "must always be used as the last handler" do
76
+ it "must always be used as the last handler before the adapter" do
77
77
  client.middleware.handlers.reverse.index(Restforce::Middleware::Logger).
78
78
  should eq 0
79
79
  end
@@ -18,14 +18,22 @@ describe Restforce::Middleware::Authentication::JWTBearer do
18
18
  stub_login_request(
19
19
  body: "grant_type=grant_type—urn:ietf:params:oauth:grant-type:jwt-bearer&" \
20
20
  "assertion=abc1234567890"
21
- ).to_return(status: 200, body: fixture(:auth_success_response))
21
+ ).to_return(
22
+ status: 200,
23
+ body: fixture(:auth_success_response),
24
+ headers: { "Content-Type" => "application/json" }
25
+ )
22
26
  end
23
27
 
24
28
  let(:fail_request) do
25
29
  stub_login_request(
26
30
  body: "grant_type=grant_type—urn:ietf:params:oauth:grant-type:jwt-bearer&" \
27
31
  "assertion=abc1234567890"
28
- ).to_return(status: 400, body: fixture(:refresh_error_response))
32
+ ).to_return(
33
+ status: 400,
34
+ body: fixture(:refresh_error_response),
35
+ headers: { "Content-Type" => "application/json" }
36
+ )
29
37
  end
30
38
  end
31
39
 
@@ -48,14 +56,22 @@ describe Restforce::Middleware::Authentication::JWTBearer do
48
56
  stub_login_request(
49
57
  body: "grant_type=grant_type—urn:ietf:params:oauth:grant-type:jwt-bearer&" \
50
58
  "assertion=abc1234567890"
51
- ).to_return(status: 200, body: fixture(:auth_success_response))
59
+ ).to_return(
60
+ status: 200,
61
+ body: fixture(:auth_success_response),
62
+ headers: { "Content-Type" => "application/json" }
63
+ )
52
64
  end
53
65
 
54
66
  let(:fail_request) do
55
67
  stub_login_request(
56
68
  body: "grant_type=grant_type—urn:ietf:params:oauth:grant-type:jwt-bearer&" \
57
69
  "assertion=abc1234567890"
58
- ).to_return(status: 400, body: fixture(:refresh_error_response))
70
+ ).to_return(
71
+ status: 400,
72
+ body: fixture(:refresh_error_response),
73
+ headers: { "Content-Type" => "application/json" }
74
+ )
59
75
  end
60
76
  end
61
77
  end
@@ -18,14 +18,22 @@ describe Restforce::Middleware::Authentication::Password do
18
18
  stub_login_request(
19
19
  body: "grant_type=password&client_id=client_id&client_secret=client_secret" \
20
20
  "&username=foo&password=barsecurity_token"
21
- ).to_return(status: 200, body: fixture(:auth_success_response))
21
+ ).to_return(
22
+ status: 200,
23
+ body: fixture(:auth_success_response),
24
+ headers: { "Content-Type" => "application/json" }
25
+ )
22
26
  end
23
27
 
24
28
  let(:fail_request) do
25
29
  stub_login_request(
26
30
  body: "grant_type=password&client_id=client_id&client_secret=client_secret" \
27
31
  "&username=foo&password=barsecurity_token"
28
- ).to_return(status: 400, body: fixture(:auth_error_response))
32
+ ).to_return(
33
+ status: 400,
34
+ body: fixture(:auth_error_response),
35
+ headers: { "Content-Type" => "application/json" }
36
+ )
29
37
  end
30
38
  end
31
39
 
@@ -16,14 +16,22 @@ describe Restforce::Middleware::Authentication::Token do
16
16
  stub_login_request(
17
17
  body: "grant_type=refresh_token&refresh_token=refresh_token&" \
18
18
  "client_id=client_id&client_secret=client_secret"
19
- ).to_return(status: 200, body: fixture(:auth_success_response))
19
+ ).to_return(
20
+ status: 200,
21
+ body: fixture(:auth_success_response),
22
+ headers: { "Content-Type" => "application/json" }
23
+ )
20
24
  end
21
25
 
22
26
  let(:fail_request) do
23
27
  stub_login_request(
24
28
  body: "grant_type=refresh_token&refresh_token=refresh_token&" \
25
29
  "client_id=client_id&client_secret=client_secret"
26
- ).to_return(status: 400, body: fixture(:refresh_error_response))
30
+ ).to_return(
31
+ status: 400,
32
+ body: fixture(:refresh_error_response),
33
+ headers: { "Content-Type" => "application/json" }
34
+ )
27
35
  end
28
36
  end
29
37
  end
@@ -59,7 +59,7 @@ describe Restforce::Middleware::Authentication do
59
59
  end
60
60
 
61
61
  its(:handlers) {
62
- should include FaradayMiddleware::ParseJson
62
+ should include Restforce::Middleware::JsonResponse
63
63
  }
64
64
  its(:handlers) { should_not include Restforce::Middleware::Logger }
65
65
  its(:adapter) { should eq Faraday::Adapter::NetHttp }
@@ -71,7 +71,7 @@ describe Restforce::Middleware::Authentication do
71
71
  end
72
72
 
73
73
  its(:handlers) {
74
- should include FaradayMiddleware::ParseJson,
74
+ should include Restforce::Middleware::JsonResponse,
75
75
  Restforce::Middleware::Logger
76
76
  }
77
77
  its(:adapter) { should eq Faraday::Adapter::NetHttp }
@@ -83,7 +83,7 @@ describe Restforce::Middleware::Authentication do
83
83
  end
84
84
 
85
85
  its(:handlers) {
86
- should include FaradayMiddleware::ParseJson
86
+ should include Restforce::Middleware::JsonResponse
87
87
  }
88
88
  its(:adapter) { should eq Faraday::Adapter::Typhoeus }
89
89
  end
@@ -97,7 +97,7 @@ describe Restforce::Middleware::Authentication do
97
97
  end
98
98
 
99
99
  describe '.error_message' do
100
- context 'when response.body is present' do
100
+ context 'when response_body is present' do
101
101
  let(:response) {
102
102
  Faraday::Response.new(
103
103
  response_body: { 'error' => 'error', 'error_description' => 'description' },
@@ -109,7 +109,7 @@ describe Restforce::Middleware::Authentication do
109
109
  it { should eq "error: description (401)" }
110
110
  end
111
111
 
112
- context 'when response.body is nil' do
112
+ context 'when response_body is nil' do
113
113
  let(:response) { Faraday::Response.new(status: 401) }
114
114
 
115
115
  subject { middleware.error_message(response) }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restforce
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.3.1
4
+ version: 6.0.0.rc.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Rogers
@@ -9,48 +9,82 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-07-19 00:00:00.000000000 Z
12
+ date: 2022-08-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "<="
18
+ - - "<"
19
19
  - !ruby/object:Gem::Version
20
- version: 1.10.0
20
+ version: 2.5.0
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 0.9.0
23
+ version: 1.1.0
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
- - - "<="
28
+ - - "<"
29
29
  - !ruby/object:Gem::Version
30
- version: 1.10.0
30
+ version: 2.5.0
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.9.0
33
+ version: 1.1.0
34
34
  - !ruby/object:Gem::Dependency
35
- name: faraday_middleware
35
+ name: faraday-follow_redirects
36
36
  requirement: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "<="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.3.0
41
+ - - "<"
39
42
  - !ruby/object:Gem::Version
40
- version: 0.8.8
43
+ version: 1.0.0
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: !ruby/object:Gem::Requirement
47
+ requirements:
41
48
  - - "<="
42
49
  - !ruby/object:Gem::Version
43
- version: '2.0'
50
+ version: 0.3.0
51
+ - - "<"
52
+ - !ruby/object:Gem::Version
53
+ version: 1.0.0
54
+ - !ruby/object:Gem::Dependency
55
+ name: faraday-multipart
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 1.0.0
61
+ - - "<"
62
+ - !ruby/object:Gem::Version
63
+ version: 2.0.0
44
64
  type: :runtime
45
65
  prerelease: false
46
66
  version_requirements: !ruby/object:Gem::Requirement
47
67
  requirements:
48
68
  - - ">="
49
69
  - !ruby/object:Gem::Version
50
- version: 0.8.8
51
- - - "<="
70
+ version: 1.0.0
71
+ - - "<"
52
72
  - !ruby/object:Gem::Version
53
- version: '2.0'
73
+ version: 2.0.0
74
+ - !ruby/object:Gem::Dependency
75
+ name: faraday-net_http
76
+ requirement: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "<"
79
+ - !ruby/object:Gem::Version
80
+ version: 3.0.0
81
+ type: :runtime
82
+ prerelease: false
83
+ version_requirements: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "<"
86
+ - !ruby/object:Gem::Version
87
+ version: 3.0.0
54
88
  - !ruby/object:Gem::Dependency
55
89
  name: hashie
56
90
  requirement: !ruby/object:Gem::Requirement
@@ -143,6 +177,8 @@ files:
143
177
  - lib/restforce/middleware/custom_headers.rb
144
178
  - lib/restforce/middleware/gzip.rb
145
179
  - lib/restforce/middleware/instance_url.rb
180
+ - lib/restforce/middleware/json_request.rb
181
+ - lib/restforce/middleware/json_response.rb
146
182
  - lib/restforce/middleware/logger.rb
147
183
  - lib/restforce/middleware/mashify.rb
148
184
  - lib/restforce/middleware/multipart.rb
@@ -249,12 +285,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
249
285
  requirements:
250
286
  - - ">="
251
287
  - !ruby/object:Gem::Version
252
- version: '2.6'
288
+ version: '2.7'
253
289
  required_rubygems_version: !ruby/object:Gem::Requirement
254
290
  requirements:
255
- - - ">="
291
+ - - ">"
256
292
  - !ruby/object:Gem::Version
257
- version: '0'
293
+ version: 1.3.1
258
294
  requirements: []
259
295
  rubygems_version: 3.1.6
260
296
  signing_key: