restforce 6.0.0 → 8.0.1

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build.yml +3 -3
  3. data/.github/workflows/faraday.yml +31 -3
  4. data/.gitignore +4 -0
  5. data/.rubocop.yml +1 -1
  6. data/CHANGELOG.md +74 -0
  7. data/Gemfile +8 -8
  8. data/README.md +41 -23
  9. data/UPGRADING.md +24 -0
  10. data/lib/restforce/collection.rb +2 -2
  11. data/lib/restforce/concerns/authentication.rb +8 -0
  12. data/lib/restforce/concerns/base.rb +5 -0
  13. data/lib/restforce/concerns/batch_api.rb +2 -2
  14. data/lib/restforce/concerns/composite_api.rb +9 -1
  15. data/lib/restforce/concerns/connection.rb +10 -3
  16. data/lib/restforce/concerns/picklists.rb +1 -1
  17. data/lib/restforce/concerns/streaming.rb +4 -4
  18. data/lib/restforce/config.rb +6 -2
  19. data/lib/restforce/error_code.rb +23 -1
  20. data/lib/restforce/file_part.rb +3 -1
  21. data/lib/restforce/mash.rb +2 -2
  22. data/lib/restforce/middleware/authentication/client_credential.rb +15 -0
  23. data/lib/restforce/middleware/authentication.rb +2 -1
  24. data/lib/restforce/middleware/gzip.rb +5 -0
  25. data/lib/restforce/middleware/json_request.rb +2 -2
  26. data/lib/restforce/middleware/json_response.rb +1 -1
  27. data/lib/restforce/middleware/raise_error.rb +1 -1
  28. data/lib/restforce/patches/parts.rb +2 -0
  29. data/lib/restforce/version.rb +1 -1
  30. data/lib/restforce.rb +1 -1
  31. data/restforce.gemspec +4 -4
  32. data/spec/integration/abstract_client_spec.rb +6 -3
  33. data/spec/unit/concerns/authentication_spec.rb +33 -0
  34. data/spec/unit/concerns/base_spec.rb +1 -1
  35. data/spec/unit/concerns/composite_api_spec.rb +43 -0
  36. data/spec/unit/concerns/connection_spec.rb +3 -1
  37. data/spec/unit/config_spec.rb +28 -1
  38. data/spec/unit/middleware/authentication/client_credential_spec.rb +36 -0
  39. data/spec/unit/middleware/authentication_spec.rb +3 -3
  40. data/spec/unit/middleware/authorization_spec.rb +5 -1
  41. data/spec/unit/middleware/custom_headers_spec.rb +6 -2
  42. data/spec/unit/middleware/gzip_spec.rb +60 -14
  43. data/spec/unit/middleware/instance_url_spec.rb +2 -2
  44. data/spec/unit/middleware/logger_spec.rb +1 -1
  45. data/spec/unit/sobject_spec.rb +9 -5
  46. metadata +12 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9aade8a096cdf3f75ed27ec3d2f8393b6c2798875a3eb25fa5d7c3506532f104
4
- data.tar.gz: b7d98630ac5c44018f4a30bcd17c14bc6d89c3d50fb27331270e7e94cb64e1a8
3
+ metadata.gz: d15210bc91589b14b39393257c157630f0e97a48f645182f859b111ff217c1ce
4
+ data.tar.gz: 6e53ae6ada7fcb4743e5e9ee5b42728007d878612bf7487a02510755786d6355
5
5
  SHA512:
6
- metadata.gz: 4d8e4d1d84a12806a0e913a0ca0e64d481584fc774abeb2f968c95cff2d9e92699a872c8f06fe0f03eca6a838345d1b7dfebed6decacfb6f28f72f26e2cae033
7
- data.tar.gz: 04a9c55df3fd6e49491b0a87a5da2b5f1bdd816c5f1256810770c790ec27d8aa264e537fda96b029d8ba11ce1f1872510507004e9d692cf34360da42a7252844
6
+ metadata.gz: c8eb88e8e6eb093808deaa1aa6def7c59d9e883069d3835a315b492903cab8b6a3f85bd14a3b0a27ee43376075bfa49ed5af97cf11149748f7e7f2947a29b54d
7
+ data.tar.gz: f74e373ce9c0c206541f1555fa822ae0b2ade70a05fdec3eb5d3f7cee2ffeb0da8876a33b20e2e7350af34cb97b6335c0eaa64bf5b207d905113aebd5b9095f7
@@ -6,10 +6,10 @@ jobs:
6
6
  strategy:
7
7
  fail-fast: false
8
8
  matrix:
9
- ruby_version: ['2.7', '3.0', '3.1', '3.2.0-preview1']
9
+ ruby_version: ["3.1", "3.2", "3.3", "3.4", "4.0"]
10
10
  steps:
11
11
  - name: Checkout code
12
- uses: actions/checkout@v3
12
+ uses: actions/checkout@v4
13
13
  - name: Setup Ruby ${{ matrix.ruby_version }}
14
14
  uses: ruby/setup-ruby@v1
15
15
  with:
@@ -20,4 +20,4 @@ jobs:
20
20
  - name: Lint Ruby files
21
21
  run: bundle exec rubocop
22
22
  - name: Run RSpec tests
23
- run: bundle exec rspec
23
+ run: bundle exec rspec
@@ -10,12 +10,40 @@ jobs:
10
10
  # For v2.0.x, we test v2.0.0 and v2.0.1 because v2.0.0 has a special behaviour where
11
11
  # the Net::HTTP adapter is not included. See
12
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
+ faraday_version:
14
+ [
15
+ "1.1.0",
16
+ "1.2.0",
17
+ "1.3.1",
18
+ "1.4.3",
19
+ "1.5.1",
20
+ "1.6.0",
21
+ "1.7.2",
22
+ "1.8.0",
23
+ "1.9.3",
24
+ "1.10.3",
25
+ "2.0.0",
26
+ "2.0.1",
27
+ "2.1.0",
28
+ "2.2.0",
29
+ "2.3.0",
30
+ "2.4.0",
31
+ "2.5.2",
32
+ "2.6.0",
33
+ "2.7.12",
34
+ "2.8.1",
35
+ "2.9.2",
36
+ "2.10.1",
37
+ "2.11.0",
38
+ "2.12.3",
39
+ "2.13.4",
40
+ "2.14.0"
41
+ ]
14
42
  env:
15
43
  FARADAY_VERSION: ~> ${{ matrix.faraday_version }}
16
44
  steps:
17
45
  - name: Checkout code
18
- uses: actions/checkout@v3
46
+ uses: actions/checkout@v4
19
47
  - name: Setup Ruby ${{ matrix.ruby_version }}
20
48
  uses: ruby/setup-ruby@v1
21
49
  with:
@@ -24,4 +52,4 @@ jobs:
24
52
  - name: Install dependencies
25
53
  run: bundle install
26
54
  - name: Run RSpec tests
27
- run: bundle exec rspec
55
+ run: bundle exec rspec
data/.gitignore CHANGED
@@ -19,3 +19,7 @@ tmp
19
19
  .rspec
20
20
  .ruby-version
21
21
  *.swp
22
+ .idea
23
+ Vagrantfile
24
+ .vagrant/
25
+ vendor/
data/.rubocop.yml CHANGED
@@ -8,7 +8,7 @@ AllCops:
8
8
  - .*/**/*
9
9
  - vendor/**/*
10
10
  NewCops: enable
11
- TargetRubyVersion: 2.7
11
+ TargetRubyVersion: 3.1
12
12
 
13
13
  # Limit lines to 90 characters.
14
14
  Layout/LineLength:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,77 @@
1
+ ## 8.0.1 (December 29, 2025)
2
+
3
+ * Allow `faraday-follow_redirects` v0.4.x and v0.5.x to unlock Ruby 4.0 compatibility
4
+
5
+ ## 8.0.0 (December 18, 2024)
6
+
7
+ **This version contains breaking changes. For help with upgrading, see [`UPGRADING.md`](https://github.com/restforce/restforce/blob/main/UPGRADING.md).**
8
+
9
+ - **⚠️ Drop support for Ruby 3.0**, since Ruby 3.0 has reached its end-of-life (@timrogers)
10
+
11
+ ## 7.6.0 (December 18, 2024)
12
+
13
+ - **Allow all `faraday` versions up to, but not including, v3.0.0**: For more details, see https://github.com/restforce/restforce/pull/915 (@timrogers)
14
+
15
+ ## 7.5.0 (September 4, 2024)
16
+
17
+ - Add support for `faraday` v2.11.x (@timrogers)
18
+
19
+ ## 7.4.0 (July 10, 2024)
20
+
21
+ - Add support for `faraday` v2.10.x (@ryan-mcneil)
22
+
23
+ # 7.3.1 (Mar 30, 2024)
24
+
25
+ - Fix `uninitialized constant StringIO` error by explicitly requiring `StringIO` where it's used (@timrogers)
26
+
27
+ # 7.3.0 (Feb 14, 2024 🧡)
28
+
29
+ - Add support for making `GET` requests using the Composite API (@shravan097)
30
+
31
+ # 7.2.0 (Jan 23, 2024)
32
+
33
+ - Add support for `faraday` v2.9.x (@timrogers)
34
+
35
+ # 7.1.1 (Jan 23, 2024)
36
+
37
+ - Handle the `APEX_REST_SERVICES_DISABLED` error returned by the Salesforce API (@timrogers)
38
+
39
+ # 7.1.0 (Dec 20, 2023)
40
+
41
+ - Add support for the [OAuth 2.0 Client Credentials authentication flow](https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_client_credentials_flow.htm&type=5) (@rh-taro)
42
+ - Add support for `faraday` v2.8.x (@timrogers)
43
+
44
+ # 7.0.0 (Oct 6, 2023)
45
+
46
+ __This version contains breaking changes. For help with upgrading, see [`UPGRADING.md`](https://github.com/restforce/restforce/blob/main/UPGRADING.md).__
47
+
48
+ * __⚠️ Drop support for Ruby 2.7__, since [Ruby 2.7 has reached its end-of-life](https://www.ruby-lang.org/en/downloads/) (@timrogers)
49
+
50
+ # 6.2.4 (Oct 6, 2023)
51
+
52
+ * Register the custom JSON middleware for Faraday with a more unique name to avoid clashes with other middleware (@dbackeus)
53
+
54
+ # 6.2.3 (Jun 18 2023)
55
+
56
+ * Handle the `CANNOT_DELETE_OWNER`, `CANNOT_POST_TO_ARCHIVED_GROUP`, `INVALID_INPUT`, `INVALID_MARKUP` and `INVALID_SEARCH` errors returned by the Salesforce API (@spurton)
57
+
58
+ # 6.2.2 (Mar 24 2023)
59
+
60
+ * Handle the `INSUFFICIENT_ACCESS` error returned by the Salesforce API (@timrogers, @nstuart-at-salesforce)
61
+
62
+ # 6.2.1 (Jan 18 2023)
63
+
64
+ * When a response claims to be gzipped but isn't, return the body as it is and don't explode (@timrogers)
65
+
66
+ # 6.2.0 (Jan 18 2023)
67
+
68
+ * Add support for `faraday` v2.7.x (@timrogers)
69
+ * Expose the Faraday `Response` on` `CompositeAPIError`s (@shravan097)
70
+
71
+ # 6.1.0 (Nov 18 2022)
72
+
73
+ * Add support for `faraday` v2.5.x and v2.6.x (@marcrohloff, @timrogers)
74
+
1
75
  # 6.0.0 (Sep 9 2022)
2
76
 
3
77
  __This version contains breaking changes. For help with upgrading, see [`UPGRADING.md`](https://github.com/restforce/restforce/blob/main/UPGRADING.md).__
data/Gemfile CHANGED
@@ -3,20 +3,20 @@
3
3
  source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
- faraday_version = ENV.fetch('FARADAY_VERSION', '~> 1.8.0')
6
+ faraday_version = ENV.fetch('FARADAY_VERSION', '~> 2.12.2')
7
7
 
8
8
  # Enable us to explicitly pick a Faraday version when running tests
9
9
  gem 'faraday', faraday_version
10
- gem 'faraday-typhoeus', '~> 0.2.1' unless faraday_version.start_with?("~> 1")
10
+ gem 'faraday-typhoeus', '~> 1.1.0' unless faraday_version.start_with?("~> 1")
11
11
  gem 'faye' unless RUBY_PLATFORM == 'java'
12
12
  gem 'guard-rspec'
13
13
  gem 'guard-rubocop'
14
14
  gem 'jruby-openssl', platforms: :jruby
15
15
  gem 'rake'
16
- gem 'rspec', '~> 3.11.0'
16
+ gem 'rspec', '~> 3.13.0'
17
17
  gem 'rspec-collection_matchers', '~> 1.2.0'
18
- gem 'rspec-its', '~> 1.3.0'
19
- gem 'rspec_junit_formatter', '~> 0.5.1'
20
- gem 'rubocop', '~> 1.36.0'
21
- gem 'simplecov', '~> 0.21.2'
22
- gem 'webmock', '~> 3.18.1'
18
+ gem 'rspec-its', '~> 2.0.0'
19
+ gem 'rspec_junit_formatter', '~> 0.6.0'
20
+ gem 'rubocop', '~> 1.70.0'
21
+ gem 'simplecov', '~> 0.22.0'
22
+ gem 'webmock', '~> 3.24.0'
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![CircleCI](https://circleci.com/gh/restforce/restforce.svg?style=svg)](https://circleci.com/gh/restforce/restforce)
4
4
  ![Downloads](https://img.shields.io/gem/dt/restforce.svg)
5
5
 
6
- Restforce is a ruby gem for the [Salesforce REST api](http://www.salesforce.com/us/developer/docs/api_rest/index.htm).
6
+ Restforce is a ruby gem for the [Salesforce REST API](http://www.salesforce.com/us/developer/docs/api_rest/index.htm).
7
7
 
8
8
  Features include:
9
9
 
@@ -27,7 +27,7 @@ Features include:
27
27
 
28
28
  Add this line to your application's Gemfile:
29
29
 
30
- gem 'restforce', '~> 6.0.0'
30
+ gem 'restforce', '~> 8.0.1'
31
31
 
32
32
  And then execute:
33
33
 
@@ -37,14 +37,16 @@ Or install it yourself as:
37
37
 
38
38
  $ gem install restforce
39
39
 
40
- __As of version 6.0.0, this gem is only compatible with Ruby 2.7.0 and later.__ If you're using an earlier Ruby version:
40
+ **As of version 8.0.0, this gem is only compatible with Ruby 3.1.0 and later.** If you're using an earlier Ruby version:
41
41
 
42
- * for Ruby 2.6, use version 5.3.1 or earlier
43
- * for Ruby 2.5, use version 5.0.6 or earlier
44
- * for Ruby 2.4, use version 4.3.0 or earlier
45
- * for Ruby 2.3, use version 3.2.0 or earlier
46
- * for Ruby versions 2.2, 2.1 and 2.0, use version 2.5.3 or earlier
47
- * for Ruby 1.9.3, use version 2.4.2
42
+ - for Ruby 3.0, use version 7.6.0 or earlier
43
+ - for Ruby 2.7, use version 6.2.4 or earlier
44
+ - for Ruby 2.6, use version 5.3.1 or earlier
45
+ - for Ruby 2.5, use version 5.0.6 or earlier
46
+ - for Ruby 2.4, use version 4.3.0 or earlier
47
+ - for Ruby 2.3, use version 3.2.0 or earlier
48
+ - for Ruby versions 2.2, 2.1 and 2.0, use version 2.5.3 or earlier
49
+ - for Ruby 1.9.3, use version 2.4.2
48
50
 
49
51
  This gem is versioned using [Semantic Versioning](http://semver.org/), so you can be confident when updating that there will not be breaking changes outside of a major version (following format MAJOR.MINOR.PATCH, so for instance moving from 3.1.0 to 4.0.0 would be allowed to include incompatible API changes). See the [changelog](https://github.com/restforce/restforce/tree/master/CHANGELOG.md) for details on what has changed in each version.
50
52
 
@@ -58,7 +60,7 @@ so you can do things like `client.query('select Id, (select Name from Children__
58
60
 
59
61
  Which authentication method you use really depends on your use case. If you're
60
62
  building an application where many users from different organizations are authenticated
61
- through oauth and you need to interact with data in their org on their behalf,
63
+ through OAuth and you need to interact with data in their org on their behalf,
62
64
  you should use the OAuth token authentication method.
63
65
 
64
66
  If you're using the gem to interact with a single org (maybe you're building some
@@ -112,12 +114,13 @@ The `id` field can be used to [uniquely identify](https://developer.salesforce.c
112
114
  If you prefer to use a username and password to authenticate:
113
115
 
114
116
  ```ruby
115
- client = Restforce.new(username: 'foo',
116
- password: 'bar',
117
- security_token: 'security token',
118
- client_id: 'client_id',
119
- client_secret: 'client_secret',
120
- api_version: '41.0')
117
+ client = Restforce.new(username: config['username'],
118
+ password: config['password'],
119
+ instance_url: config['instance_url'],
120
+ host: config['host'], # test.salesforce.com for sandbox (optional)
121
+ client_id: config['client_key'], # Salesforce Client Key
122
+ client_secret: config['client_secret'], # Salesforce Client Secret
123
+ api_version: '55.0')
121
124
  ```
122
125
 
123
126
  #### JWT Bearer Token
@@ -153,6 +156,17 @@ client = Restforce.new
153
156
 
154
157
  **Note:** Restforce library does not cache JWT Bearer tokens automatically. This means that every instantiation of the Restforce class will be treated as a new login by Salesforce. Remember that Salesforce enforces [rate limits on login requests](https://help.salesforce.com/s/articleView?id=000312767&type=1). If you are building an application that will instantiate the Restforce class more than this specified rate limit, you might want to consider caching the Bearer token either in-memory or in your own storage by leveraging the `authentication_callback` method.
155
158
 
159
+ #### Client Credentials
160
+
161
+ If you want to authenticate as an application, you can use the [Client Credentials flow](https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_client_credentials_flow.htm&type=5):
162
+
163
+ ```ruby
164
+ client = Restforce.new(client_id: 'client_id',
165
+ client_secret: 'client_secret',
166
+ api_version: '55.0',
167
+ host: 'MYDOMAIN.my.salesforce.com')
168
+ ```
169
+
156
170
  #### Sandbox Organizations
157
171
 
158
172
  You can connect to sandbox organizations by specifying a host. The default host is
@@ -316,7 +330,7 @@ client.search('FIND {bar}')
316
330
  # => #<Restforce::Collection >
317
331
 
318
332
  # Find accounts matching the term 'genepoint' and return the `Name` field
319
- client.search('FIND {genepoint} RETURNING Account (Name)').map(&:Name)
333
+ client.search('FIND {genepoint} RETURNING Account (Name)')["searchRecords"].map(&:Name)
320
334
  # => ['GenePoint']
321
335
  ```
322
336
 
@@ -587,7 +601,6 @@ This feature permits the user to send a composite object—that is, a complex
587
601
  object with nested children—in a single API call. Up to 25 requests may be
588
602
  included in a single composite.
589
603
 
590
- Note that `GET` is not yet implemented for this API.
591
604
 
592
605
  ```ruby
593
606
  # build up an array of requests:
@@ -830,12 +843,17 @@ client.create!("CustomField", {
830
843
  })
831
844
  ```
832
845
 
833
- ## Links
846
+ ## Configuration Precedence
847
+
848
+ Here's the order of precedence from highest to lowest:
849
+
850
+ Arguments on new: passing configuration options directly as arguments has the highest precedence. These settings will override any other configuration.
851
+
852
+ Configuration block: using Restforce.configure to set configuration options is the next in line. They will take precedence over environment variables and defaults but will be overridden by direct arguments on instantiation.
853
+
854
+ Environment variables: has the lowest precedence. If you set options using environment variables, they will be overridden by any other configuration method.
834
855
 
835
- If you need a full Active Record experience, may be you can use
836
- [ActiveForce](https://github.com/ionia-corporation/active_force) that wraps
837
- Restforce and adds Associations, Query Building (like AREL), Validations and
838
- Callbacks.
856
+ Defaults: If none of the above methods are used, Restforce falls back to its default configuration values.
839
857
 
840
858
  ## Contributing
841
859
 
data/UPGRADING.md CHANGED
@@ -1,3 +1,27 @@
1
+ # Upgrading from Restforce 7.x to 8.x
2
+
3
+ ## Ruby 3.0 is no longer supported
4
+
5
+ **Likelyhood of impact**: Moderate
6
+
7
+ Ruby 3.0 is no longer officially supported as an active version of the Ruby language. That means that it will not receive patches and security fixes.
8
+
9
+ Accordingly, we've dropped support for Ruby 3.0 in the Restforce library. The gemspec now specifies that only 3.1 onwards is supported, and this will be enforced by RubyGems.
10
+
11
+ Before you update to Restforce 8.x, you'll need to switch to Ruby 3.1.0 or later. The current version of Ruby at the time of writing is 3.3.6.
12
+
13
+ # Upgrading from Restforce 6.x to 7.x
14
+
15
+ ## Ruby 2.7 is no longer supported
16
+
17
+ __Likelyhood of impact__: Moderate
18
+
19
+ Ruby 2.7 is no longer officially supported as an active version of the Ruby language. That means that it will not receive patches and security fixes.
20
+
21
+ Accordingly, we've dropped support for Ruby 2.7 in the Restforce library. The gemspec now specifies that only 3.0 onwards is supported, and this will be enforced by RubyGems.
22
+
23
+ Before you update to Restforce 7.x, you'll need to switch to Ruby 3.0.0 or later. The current version of Ruby at the time of writing is 3.2.2.
24
+
1
25
  # Upgrading from Restforce 5.x to 6.x
2
26
 
3
27
  __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.
@@ -12,12 +12,12 @@ module Restforce
12
12
  end
13
13
 
14
14
  # Yield each value on each page.
15
- def each(&block)
15
+ def each(&)
16
16
  @raw_page['records'].each { |record| yield Restforce::Mash.build(record, @client) }
17
17
 
18
18
  np = next_page
19
19
  while np
20
- np.current_page.each(&block)
20
+ np.current_page.each(&)
21
21
  np = np.next_page
22
22
  end
23
23
  end
@@ -21,6 +21,8 @@ module Restforce
21
21
  Restforce::Middleware::Authentication::Token
22
22
  elsif jwt?
23
23
  Restforce::Middleware::Authentication::JWTBearer
24
+ elsif client_credential?
25
+ Restforce::Middleware::Authentication::ClientCredential
24
26
  end
25
27
  end
26
28
 
@@ -48,6 +50,12 @@ module Restforce
48
50
  options[:username] &&
49
51
  options[:client_id]
50
52
  end
53
+
54
+ # Internal: Returns true if client credential flow should be used for
55
+ # authentication.
56
+ def client_credential?
57
+ options[:client_id] && options[:client_secret]
58
+ end
51
59
  end
52
60
  end
53
61
  end
@@ -57,6 +57,11 @@ module Restforce
57
57
  #
58
58
  # :request_headers - A hash containing custom headers that will be
59
59
  # appended to each request
60
+ #
61
+ # :clear_authorization_header - A boolean that when set to true will cause
62
+ # the Faraday::FollowRedirects middleware to
63
+ # omit the auth header when following
64
+ # redirects (default: false)
60
65
 
61
66
  def initialize(opts = {})
62
67
  raise ArgumentError, 'Please specify a hash of options' unless opts.is_a?(Hash)
@@ -29,8 +29,8 @@ module Restforce
29
29
  end.flatten
30
30
  end
31
31
 
32
- def batch!(&block)
33
- batch(halt_on_error: true, &block)
32
+ def batch!(&)
33
+ batch(halt_on_error: true, &)
34
34
  end
35
35
 
36
36
  class Subrequests
@@ -29,7 +29,7 @@ module Restforce
29
29
  if all_or_none && has_errors
30
30
  last_error_index = results.rindex { |result| result['httpStatusCode'] != 412 }
31
31
  last_error = results[last_error_index]
32
- raise CompositeAPIError, last_error['body'][0]['errorCode']
32
+ raise CompositeAPIError.new(last_error['body'][0]['errorCode'], response)
33
33
  end
34
34
 
35
35
  results
@@ -93,6 +93,14 @@ module Restforce
93
93
  }
94
94
  end
95
95
 
96
+ def find(sobject, reference_id, id)
97
+ requests << {
98
+ method: 'GET',
99
+ url: composite_api_path("#{sobject}/#{id}"),
100
+ referenceId: reference_id
101
+ }
102
+ end
103
+
96
104
  private
97
105
 
98
106
  def composite_api_path(path)
@@ -20,6 +20,8 @@ module Restforce
20
20
  private
21
21
 
22
22
  # Internal: Internal faraday connection where all requests go through
23
+ # rubocop:disable Metrics/AbcSize
24
+ # rubocop:disable Metrics/BlockLength
23
25
  def connection
24
26
  @connection ||= Faraday.new(options[:instance_url],
25
27
  connection_options) do |builder|
@@ -31,7 +33,7 @@ module Restforce
31
33
  # Handles multipart file uploads for blobs.
32
34
  builder.use Restforce::Middleware::Multipart
33
35
  # Converts the request into JSON.
34
- builder.request :json
36
+ builder.request :restforce_json
35
37
  # Handles reauthentication for 403 responses.
36
38
  if authentication_middleware
37
39
  builder.use authentication_middleware, self, options
@@ -43,11 +45,14 @@ module Restforce
43
45
  # Caches GET requests.
44
46
  builder.use Restforce::Middleware::Caching, cache, options if cache
45
47
  # Follows 30x redirects.
46
- builder.use Faraday::FollowRedirects::Middleware
48
+ builder.use Faraday::FollowRedirects::Middleware, {
49
+ # Pass the option to clear or send the auth header on redirects through
50
+ clear_authorization_header: options[:clear_authorization_header]
51
+ }
47
52
  # Raises errors for 40x responses.
48
53
  builder.use Restforce::Middleware::RaiseError
49
54
  # Parses returned JSON response into a hash.
50
- builder.response :json, content_type: /\bjson$/
55
+ builder.response :restforce_json, content_type: /\bjson$/
51
56
  # Compress/Decompress the request/response
52
57
  unless adapter == :httpclient
53
58
  builder.use Restforce::Middleware::Gzip, self, options
@@ -64,6 +69,8 @@ module Restforce
64
69
  builder.adapter adapter
65
70
  end
66
71
  end
72
+ # rubocop:enable Metrics/BlockLength
73
+ # rubocop:enable Metrics/AbcSize
67
74
 
68
75
  def adapter
69
76
  options[:adapter]
@@ -85,7 +85,7 @@ module Restforce
85
85
  def valid?(picklist_entry)
86
86
  valid_for = picklist_entry['validFor'].ljust(16, 'A').unpack1('m').
87
87
  unpack('C*')
88
- (valid_for[index >> 3] & (0x80 >> (index % 8))).positive?
88
+ valid_for[index >> 3].anybits?((0x80 >> (index % 8)))
89
89
  end
90
90
  end
91
91
  end
@@ -9,9 +9,9 @@ module Restforce
9
9
  # block - A block to run when a new message is received.
10
10
  #
11
11
  # Returns a Faye::Subscription
12
- def legacy_subscribe(topics, options = {}, &block)
12
+ def legacy_subscribe(topics, options = {}, &)
13
13
  topics = Array(topics).map { |channel| "/topic/#{channel}" }
14
- subscription(topics, options, &block)
14
+ subscription(topics, options, &)
15
15
  end
16
16
  alias subscribe legacy_subscribe
17
17
 
@@ -21,12 +21,12 @@ module Restforce
21
21
  # block - A block to run when a new message is received.
22
22
  #
23
23
  # Returns a Faye::Subscription
24
- def subscription(channels, options = {}, &block)
24
+ def subscription(channels, options = {}, &)
25
25
  one_or_more_channels = Array(channels)
26
26
  one_or_more_channels.each do |channel|
27
27
  replay_handlers[channel] = options[:replay]
28
28
  end
29
- faye.subscribe(one_or_more_channels, &block)
29
+ faye.subscribe(one_or_more_channels, &)
30
30
  end
31
31
 
32
32
  # Public: Faye client to use for subscribing to PushTopics
@@ -113,8 +113,8 @@ module Restforce
113
113
  # The private key for JWT authentication
114
114
  option :jwt_key
115
115
 
116
- # Set this to true if you're authenticating with a Sandbox instance.
117
- # Defaults to false.
116
+ # The login host.
117
+ # Defaults to login.salesforce.com.
118
118
  option :host, default: lambda { ENV.fetch('SALESFORCE_HOST', 'login.salesforce.com') }
119
119
 
120
120
  option :oauth_token
@@ -161,6 +161,10 @@ module Restforce
161
161
  # Set use_cache to false to opt in to caching with client.with_caching
162
162
  option :use_cache, default: true
163
163
 
164
+ # Set to true to have Faraday::FollowRedirects middleware omit the auth header
165
+ # when following redirects
166
+ option :clear_authorization_header, default: false
167
+
164
168
  def options
165
169
  self.class.options
166
170
  end