restforce 4.2.1 → 6.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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/unhandled-salesforce-error.md +17 -0
  3. data/.github/dependabot.yml +10 -0
  4. data/.github/funding.yml +1 -0
  5. data/.github/workflows/build.yml +23 -0
  6. data/.github/workflows/faraday.yml +27 -0
  7. data/.rubocop.yml +5 -4
  8. data/CHANGELOG.md +115 -0
  9. data/CONTRIBUTING.md +21 -1
  10. data/Dockerfile +31 -0
  11. data/Gemfile +15 -7
  12. data/README.md +102 -24
  13. data/UPGRADING.md +67 -0
  14. data/docker-compose.yml +7 -0
  15. data/lib/restforce/abstract_client.rb +1 -0
  16. data/lib/restforce/collection.rb +27 -4
  17. data/lib/restforce/concerns/api.rb +3 -2
  18. data/lib/restforce/concerns/base.rb +2 -2
  19. data/lib/restforce/concerns/caching.rb +7 -0
  20. data/lib/restforce/concerns/composite_api.rb +104 -0
  21. data/lib/restforce/concerns/connection.rb +1 -1
  22. data/lib/restforce/concerns/picklists.rb +2 -2
  23. data/lib/restforce/concerns/streaming.rb +1 -3
  24. data/lib/restforce/config.rb +14 -9
  25. data/lib/restforce/error_code.rb +650 -0
  26. data/lib/restforce/file_part.rb +32 -0
  27. data/lib/restforce/mash.rb +8 -3
  28. data/lib/restforce/middleware/authentication.rb +1 -0
  29. data/lib/restforce/middleware/caching.rb +140 -15
  30. data/lib/restforce/middleware/json_request.rb +90 -0
  31. data/lib/restforce/middleware/json_response.rb +85 -0
  32. data/lib/restforce/middleware/logger.rb +14 -9
  33. data/lib/restforce/middleware/raise_error.rb +13 -5
  34. data/lib/restforce/middleware.rb +2 -0
  35. data/lib/restforce/version.rb +1 -1
  36. data/lib/restforce.rb +15 -14
  37. data/restforce.gemspec +13 -21
  38. data/spec/fixtures/sobject/list_view_results_success_response.json +151 -0
  39. data/spec/integration/abstract_client_spec.rb +56 -35
  40. data/spec/integration/data/client_spec.rb +6 -2
  41. data/spec/spec_helper.rb +24 -1
  42. data/spec/support/client_integration.rb +7 -7
  43. data/spec/support/concerns.rb +1 -1
  44. data/spec/support/fixture_helpers.rb +1 -3
  45. data/spec/support/middleware.rb +1 -2
  46. data/spec/unit/collection_spec.rb +38 -2
  47. data/spec/unit/concerns/api_spec.rb +22 -15
  48. data/spec/unit/concerns/authentication_spec.rb +6 -6
  49. data/spec/unit/concerns/caching_spec.rb +26 -0
  50. data/spec/unit/concerns/composite_api_spec.rb +143 -0
  51. data/spec/unit/concerns/connection_spec.rb +2 -2
  52. data/spec/unit/concerns/streaming_spec.rb +4 -4
  53. data/spec/unit/config_spec.rb +2 -2
  54. data/spec/unit/error_code_spec.rb +61 -0
  55. data/spec/unit/mash_spec.rb +5 -0
  56. data/spec/unit/middleware/authentication/jwt_bearer_spec.rb +24 -8
  57. data/spec/unit/middleware/authentication/password_spec.rb +12 -4
  58. data/spec/unit/middleware/authentication/token_spec.rb +12 -4
  59. data/spec/unit/middleware/authentication_spec.rb +14 -8
  60. data/spec/unit/middleware/gzip_spec.rb +2 -2
  61. data/spec/unit/middleware/raise_error_spec.rb +29 -10
  62. data/spec/unit/signed_request_spec.rb +1 -1
  63. metadata +64 -187
  64. data/.circleci/config.yml +0 -56
  65. data/lib/restforce/upload_io.rb +0 -9
@@ -11,9 +11,10 @@ module Restforce
11
11
  # appropriate Restforce::Collection, Restforce::SObject and
12
12
  # Restforce::Mash objects.
13
13
  def build(val, client)
14
- if val.is_a?(Array)
14
+ case val
15
+ when Array
15
16
  val.collect { |a_val| self.build(a_val, client) }
16
- elsif val.is_a?(Hash)
17
+ when Hash
17
18
  self.klass(val).new(val, client)
18
19
  else
19
20
  val
@@ -28,7 +29,7 @@ module Restforce
28
29
  # of sobject records.
29
30
  Restforce::Collection
30
31
  elsif val.key? 'attributes'
31
- case (val['attributes']['type'])
32
+ case val.dig('attributes', 'type')
32
33
  when "Attachment"
33
34
  Restforce::Attachment
34
35
  when "Document"
@@ -55,6 +56,9 @@ module Restforce
55
56
  self.class.new(self, @client, self.default)
56
57
  end
57
58
 
59
+ # The #convert_value method and its signature are part of Hashie::Mash's API, so we
60
+ # can't unilaterally decide to change `duping` to be a keyword argument
61
+ # rubocop:disable Style/OptionalBooleanParameter
58
62
  def convert_value(val, duping = false)
59
63
  case val
60
64
  when self.class
@@ -68,5 +72,6 @@ module Restforce
68
72
  val
69
73
  end
70
74
  end
75
+ # rubocop:enable Style/OptionalBooleanParameter
71
76
  end
72
77
  end
@@ -49,6 +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 Faraday::FollowRedirects::Middleware
52
53
  builder.response :json
53
54
 
54
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.fetch(:use_cache, true)
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)
@@ -11,7 +11,7 @@ module Restforce
11
11
  @options = options
12
12
  @logger = logger || begin
13
13
  require 'logger'
14
- ::Logger.new(STDOUT)
14
+ ::Logger.new($stdout)
15
15
  end
16
16
  end
17
17
 
@@ -20,23 +20,28 @@ module Restforce
20
20
  def call(env)
21
21
  debug('request') do
22
22
  dump url: env[:url].to_s,
23
- method: env[:method],
24
- headers: env[:request_headers],
25
- body: env[:body]
23
+ method: env[:method],
24
+ headers: env[:request_headers],
25
+ body: env[:body]
26
+ end
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)
26
31
  end
27
- super
28
32
  end
29
33
 
30
34
  def on_complete(env)
31
35
  debug('response') do
32
36
  dump status: env[:status].to_s,
33
- headers: env[:response_headers],
34
- body: env[:body]
37
+ headers: env[:response_headers],
38
+ body: env[:body]
35
39
  end
36
40
  end
37
41
 
38
42
  def dump(hash)
39
- "\n" + hash.map { |k, v| " #{k}: #{v.inspect}" }.join("\n")
43
+ dumped_pairs = hash.map { |k, v| " #{k}: #{v.inspect}" }.join("\n")
44
+ "\n#{dumped_pairs}"
40
45
  end
41
46
  end
42
47
  end
@@ -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]
@@ -11,9 +20,9 @@ module Restforce
11
20
  response_values
12
21
  )
13
22
  when 401
14
- raise Restforce::UnauthorizedError, message
23
+ raise Restforce::UnauthorizedError.new(message, response_values)
15
24
  when 404
16
- raise Restforce::NotFoundError, message
25
+ raise Restforce::NotFoundError.new(message, response_values)
17
26
  when 413
18
27
  raise Restforce::EntityTooLargeError.new(
19
28
  "413: Request Entity Too Large",
@@ -56,8 +65,7 @@ module Restforce
56
65
  def exception_class_for_error_code(error_code)
57
66
  return Restforce::ResponseError unless ERROR_CODE_MATCHER.match?(error_code)
58
67
 
59
- constant_name = error_code.split('_').map(&:capitalize).join.to_sym
60
- Restforce::ErrorCode.const_get(constant_name)
68
+ Restforce::ErrorCode.get_exception_class(error_code)
61
69
  end
62
70
  end
63
71
  end
@@ -16,6 +16,8 @@ module Restforce
16
16
  autoload :CustomHeaders, 'restforce/middleware/custom_headers'
17
17
 
18
18
  def initialize(app, client, options)
19
+ super(app)
20
+
19
21
  @app = app
20
22
  @client = client
21
23
  @options = options
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Restforce
4
- VERSION = '4.2.1'
4
+ VERSION = '6.0.0'
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
 
@@ -15,7 +15,8 @@ module Restforce
15
15
  autoload :Middleware, 'restforce/middleware'
16
16
  autoload :Attachment, 'restforce/attachment'
17
17
  autoload :Document, 'restforce/document'
18
- autoload :UploadIO, 'restforce/upload_io'
18
+ autoload :FilePart, 'restforce/file_part'
19
+ autoload :UploadIO, 'restforce/file_part' # Deprecated
19
20
  autoload :SObject, 'restforce/sobject'
20
21
  autoload :Client, 'restforce/client'
21
22
  autoload :Mash, 'restforce/mash'
@@ -31,6 +32,7 @@ module Restforce
31
32
  autoload :Base, 'restforce/concerns/base'
32
33
  autoload :API, 'restforce/concerns/api'
33
34
  autoload :BatchAPI, 'restforce/concerns/batch_api'
35
+ autoload :CompositeAPI, 'restforce/concerns/composite_api'
34
36
  end
35
37
 
36
38
  module Data
@@ -44,9 +46,10 @@ module Restforce
44
46
  Error = Class.new(StandardError)
45
47
  ServerError = Class.new(Error)
46
48
  AuthenticationError = Class.new(Error)
47
- UnauthorizedError = Class.new(Error)
49
+ UnauthorizedError = Class.new(Faraday::ClientError)
48
50
  APIVersionError = Class.new(Error)
49
51
  BatchAPIError = Class.new(Error)
52
+ CompositeAPIError = Class.new(Error)
50
53
 
51
54
  # Inherit from Faraday::ResourceNotFound for backwards-compatibility
52
55
  # Consumers of this library that rescue and handle Faraday::ResourceNotFound
@@ -60,26 +63,24 @@ module Restforce
60
63
  MatchesMultipleError= Class.new(ResponseError)
61
64
  EntityTooLargeError = Class.new(ResponseError)
62
65
 
63
- module ErrorCode
64
- def self.const_missing(constant_name)
65
- const_set constant_name, Class.new(ResponseError)
66
- end
67
- end
66
+ require 'restforce/error_code'
67
+ require 'restforce/middleware/json_request'
68
+ require 'restforce/middleware/json_response'
68
69
 
69
70
  class << self
70
71
  # Alias for Restforce::Data::Client.new
71
72
  #
72
73
  # Shamelessly pulled from https://github.com/pengwynn/octokit/blob/master/lib/octokit.rb
73
- def new(*args, &block)
74
- data(*args, &block)
74
+ def new(...)
75
+ data(...)
75
76
  end
76
77
 
77
- def data(*args, &block)
78
- Restforce::Data::Client.new(*args, &block)
78
+ def data(...)
79
+ Restforce::Data::Client.new(...)
79
80
  end
80
81
 
81
- def tooling(*args, &block)
82
- Restforce::Tooling::Client.new(*args, &block)
82
+ def tooling(...)
83
+ Restforce::Tooling::Client.new(...)
83
84
  end
84
85
 
85
86
  # Helper for decoding signed requests.
data/restforce.gemspec CHANGED
@@ -3,39 +3,31 @@
3
3
  require File.expand_path('lib/restforce/version', __dir__)
4
4
 
5
5
  Gem::Specification.new do |gem|
6
- gem.authors = ["Eric J. Holmes", "Tim Rogers"]
7
- gem.email = ["eric@ejholmes.net", "tim@gocardless.com"]
8
- gem.description = 'A lightweight ruby client for the Salesforce REST API.'
9
- gem.summary = 'A lightweight ruby client for the Salesforce REST API.'
10
- gem.homepage = "http://restforce.org/"
6
+ gem.authors = ["Tim Rogers", "Eric J. Holmes"]
7
+ gem.email = ["me@timrogers.co.uk", "eric@ejholmes.net"]
8
+ gem.description = 'A lightweight Ruby client for the Salesforce REST API'
9
+ gem.summary = 'A lightweight Ruby client for the Salesforce REST API'
10
+ gem.homepage = "https://restforce.github.io/"
11
11
  gem.license = "MIT"
12
12
 
13
13
  gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
14
14
  gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
15
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
15
  gem.name = "restforce"
17
16
  gem.require_paths = ["lib"]
18
17
  gem.version = Restforce::VERSION
19
18
 
20
19
  gem.metadata = {
21
20
  'source_code_uri' => 'https://github.com/restforce/restforce',
22
- 'changelog_uri' => 'https://github.com/restforce/restforce/blob/master/CHANGELOG.md'
21
+ 'changelog_uri' => 'https://github.com/restforce/restforce/blob/master/CHANGELOG.md',
22
+ 'rubygems_mfa_required' => 'true'
23
23
  }
24
24
 
25
- gem.required_ruby_version = '>= 2.4'
25
+ gem.required_ruby_version = '>= 2.7'
26
26
 
27
- gem.add_dependency 'faraday', '<= 1.0', '>= 0.9.0'
28
- gem.add_dependency 'faraday_middleware', ['>= 0.8.8', '<= 1.0']
29
-
30
- gem.add_dependency 'json', '>= 1.7.5'
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'
31
+ gem.add_dependency 'hashie', '>= 1.2.0', '< 6.0'
31
32
  gem.add_dependency 'jwt', ['>= 1.5.6']
32
-
33
- gem.add_dependency 'hashie', '>= 1.2.0', '< 5.0'
34
-
35
- gem.add_development_dependency 'faye' unless RUBY_PLATFORM == 'java'
36
- gem.add_development_dependency 'rspec', '~> 2.14.0'
37
- gem.add_development_dependency 'rspec_junit_formatter', '~> 0.4.1'
38
- gem.add_development_dependency 'rubocop', '~> 0.77.0'
39
- gem.add_development_dependency 'simplecov', '~> 0.17.1'
40
- gem.add_development_dependency 'webmock', '~> 3.7.6'
41
33
  end