restforce 3.1.0 → 3.2.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 +5 -5
- data/.rubocop.yml +9 -11
- data/.rubocop_todo.yml +128 -81
- data/CHANGELOG.md +14 -1
- data/Gemfile +1 -1
- data/README.md +4 -4
- data/lib/restforce.rb +21 -1
- data/lib/restforce/abstract_client.rb +1 -0
- data/lib/restforce/attachment.rb +1 -0
- data/lib/restforce/concerns/api.rb +9 -6
- data/lib/restforce/concerns/batch_api.rb +87 -0
- data/lib/restforce/concerns/canvas.rb +1 -0
- data/lib/restforce/concerns/picklists.rb +1 -0
- data/lib/restforce/concerns/streaming.rb +1 -3
- data/lib/restforce/config.rb +1 -0
- data/lib/restforce/document.rb +1 -0
- data/lib/restforce/middleware/multipart.rb +1 -0
- data/lib/restforce/middleware/raise_error.rb +24 -8
- data/lib/restforce/signed_request.rb +1 -0
- data/lib/restforce/sobject.rb +1 -0
- data/lib/restforce/tooling/client.rb +3 -3
- data/lib/restforce/version.rb +1 -1
- data/restforce.gemspec +5 -5
- data/spec/integration/abstract_client_spec.rb +42 -1
- data/spec/support/fixture_helpers.rb +2 -2
- data/spec/unit/concerns/batch_api_spec.rb +107 -0
- data/spec/unit/middleware/raise_error_spec.rb +32 -11
- metadata +33 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 41d61a57996195a4809acd8e3d16d79dcf1ff9b1637ddd0e4c8b12cb8f967f5c
|
4
|
+
data.tar.gz: 41a090599ea254b58142ffdd0ed4fae33bad9d99fce472260d187018768a0cac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7be41c73c7e8aa79f1d5246e339e320e567cfddee5f317dc8286279d3fba0cbcf0bf631524330c2b4e2fad6ba71c6da6c88fa63f0af871fad04e9c5e43a0aaed
|
7
|
+
data.tar.gz: 42fe28bb527485254263015de5c5877a6371e59f14eb2aa6048fd3821356d17c143801bf389603632100eae860559f644c816727dcd0dc651d97aad30839d34a
|
data/.rubocop.yml
CHANGED
@@ -4,46 +4,44 @@ inherit_from: .rubocop_todo.yml
|
|
4
4
|
|
5
5
|
AllCops:
|
6
6
|
DisplayCopNames: true
|
7
|
-
Include:
|
8
|
-
- Rakefile
|
9
7
|
Exclude:
|
10
8
|
- .*/**/*
|
11
9
|
- vendor/**/*
|
12
10
|
TargetRubyVersion: 2.3
|
13
11
|
|
14
12
|
# Limit lines to 80 characters.
|
15
|
-
LineLength:
|
13
|
+
Metrics/LineLength:
|
16
14
|
Max: 90
|
17
15
|
|
18
|
-
ClassLength:
|
16
|
+
Metrics/ClassLength:
|
19
17
|
Enabled: false
|
20
18
|
|
21
|
-
ModuleLength:
|
19
|
+
Metrics/ModuleLength:
|
22
20
|
Enabled: false
|
23
21
|
|
24
22
|
# Avoid methods longer than 30 lines of code
|
25
|
-
MethodLength:
|
23
|
+
Metrics/MethodLength:
|
26
24
|
CountComments: false # count full line comments?
|
27
25
|
Max: 87
|
28
26
|
|
29
27
|
# Avoid single-line methods.
|
30
|
-
SingleLineMethods:
|
28
|
+
Style/SingleLineMethods:
|
31
29
|
AllowIfMethodIsEmpty: true
|
32
30
|
|
33
|
-
StringLiterals:
|
31
|
+
Style/StringLiterals:
|
34
32
|
Enabled: false
|
35
33
|
|
36
|
-
GlobalVars:
|
34
|
+
Style/GlobalVars:
|
37
35
|
Enabled: false # We use them Redis + StatsD (though maybe we shouldn't?)
|
38
36
|
|
39
37
|
# Wants underscores in all large numbers. Pain in the ass for things like
|
40
38
|
# unix timestamps.
|
41
|
-
NumericLiterals:
|
39
|
+
Style/NumericLiterals:
|
42
40
|
Enabled: false
|
43
41
|
|
44
42
|
# Wants you to use the same argument names for every reduce. This seems kinda
|
45
43
|
# naff compared to naming them semantically
|
46
|
-
SingleLineBlockParams:
|
44
|
+
Style/SingleLineBlockParams:
|
47
45
|
Enabled: false
|
48
46
|
|
49
47
|
Style/SignalException:
|
data/.rubocop_todo.yml
CHANGED
@@ -1,117 +1,164 @@
|
|
1
|
-
# This configuration was generated by
|
2
|
-
#
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2019-10-09 21:39:40 +0100 using RuboCop version 0.75.0.
|
3
4
|
# The point is for the user to remove these configuration records
|
4
5
|
# one by one as the offenses are removed from the code base.
|
5
6
|
# Note that changes in the inspected code, or installation of new
|
6
7
|
# versions of RuboCop, may require this file to be generated again.
|
7
8
|
|
8
|
-
# Offense count:
|
9
|
+
# Offense count: 17
|
9
10
|
# Cop supports --auto-correct.
|
11
|
+
# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
|
12
|
+
# SupportedHashRocketStyles: key, separator, table
|
13
|
+
# SupportedColonStyles: key, separator, table
|
14
|
+
# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
|
15
|
+
Layout/AlignHash:
|
16
|
+
Exclude:
|
17
|
+
- 'lib/restforce/middleware/logger.rb'
|
18
|
+
- 'restforce.gemspec'
|
19
|
+
- 'spec/integration/abstract_client_spec.rb'
|
20
|
+
- 'spec/unit/config_spec.rb'
|
21
|
+
|
22
|
+
# Offense count: 2
|
23
|
+
# Cop supports --auto-correct.
|
24
|
+
# Configuration parameters: EnforcedStyle, IndentationWidth.
|
25
|
+
# SupportedStyles: special_inside_parentheses, consistent, align_braces
|
26
|
+
Layout/IndentFirstHashElement:
|
27
|
+
Exclude:
|
28
|
+
- 'lib/restforce/concerns/connection.rb'
|
29
|
+
|
30
|
+
# Offense count: 1
|
31
|
+
# Cop supports --auto-correct.
|
32
|
+
# Configuration parameters: AllowForAlignment.
|
33
|
+
Layout/SpaceAroundOperators:
|
34
|
+
Exclude:
|
35
|
+
- 'lib/restforce.rb'
|
36
|
+
|
37
|
+
# Offense count: 8
|
38
|
+
# Cop supports --auto-correct.
|
39
|
+
# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
|
10
40
|
Lint/UnusedBlockArgument:
|
11
|
-
|
41
|
+
Exclude:
|
42
|
+
- 'lib/restforce/concerns/api.rb'
|
43
|
+
- 'lib/restforce/concerns/batch_api.rb'
|
44
|
+
- 'lib/restforce/middleware/multipart.rb'
|
45
|
+
- 'spec/unit/config_spec.rb'
|
12
46
|
|
13
|
-
# Offense count:
|
47
|
+
# Offense count: 9
|
14
48
|
Metrics/AbcSize:
|
15
|
-
Max:
|
49
|
+
Max: 38
|
16
50
|
|
17
|
-
# Offense count:
|
51
|
+
# Offense count: 1
|
18
52
|
Metrics/CyclomaticComplexity:
|
19
|
-
Max:
|
53
|
+
Max: 8
|
20
54
|
|
21
|
-
# Offense count:
|
55
|
+
# Offense count: 1
|
22
56
|
Metrics/PerceivedComplexity:
|
23
|
-
Max:
|
57
|
+
Max: 9
|
24
58
|
|
25
|
-
# Offense count:
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
59
|
+
# Offense count: 5
|
60
|
+
# Configuration parameters: EnforcedStyleForLeadingUnderscores.
|
61
|
+
# SupportedStylesForLeadingUnderscores: disallowed, required, optional
|
62
|
+
Naming/MemoizedInstanceVariableName:
|
63
|
+
Exclude:
|
64
|
+
- 'lib/restforce/concerns/picklists.rb'
|
65
|
+
- 'lib/restforce/concerns/streaming.rb'
|
66
|
+
|
67
|
+
# Offense count: 2
|
68
|
+
# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist, MethodDefinitionMacros.
|
69
|
+
# NamePrefix: is_, has_, have_
|
70
|
+
# NamePrefixBlacklist: is_, has_, have_
|
71
|
+
# NameWhitelist: is_a?
|
72
|
+
# MethodDefinitionMacros: define_method, define_singleton_method
|
73
|
+
Naming/PredicateName:
|
74
|
+
Exclude:
|
75
|
+
- 'spec/**/*'
|
76
|
+
- 'lib/restforce/collection.rb'
|
77
|
+
- 'lib/restforce/middleware/multipart.rb'
|
34
78
|
|
35
|
-
# Offense count:
|
79
|
+
# Offense count: 12
|
36
80
|
# Cop supports --auto-correct.
|
37
|
-
# Configuration parameters: EnforcedStyle,
|
81
|
+
# Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, IgnoredMethods, AllowBracesOnProceduralOneLiners.
|
82
|
+
# SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
|
83
|
+
# ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
|
84
|
+
# FunctionalMethods: let, let!, subject, watch
|
85
|
+
# IgnoredMethods: lambda, proc, it
|
38
86
|
Style/BlockDelimiters:
|
39
|
-
|
87
|
+
Exclude:
|
88
|
+
- 'lib/restforce/concerns/batch_api.rb'
|
89
|
+
- 'spec/support/event_machine.rb'
|
90
|
+
- 'spec/support/middleware.rb'
|
91
|
+
- 'spec/unit/concerns/base_spec.rb'
|
92
|
+
- 'spec/unit/concerns/batch_api_spec.rb'
|
93
|
+
- 'spec/unit/concerns/caching_spec.rb'
|
94
|
+
- 'spec/unit/concerns/streaming_spec.rb'
|
95
|
+
- 'spec/unit/middleware/authentication_spec.rb'
|
96
|
+
- 'spec/unit/middleware/mashify_spec.rb'
|
40
97
|
|
41
|
-
# Offense count:
|
42
|
-
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
43
|
-
Style/ClassAndModuleChildren:
|
44
|
-
Enabled: false
|
45
|
-
|
46
|
-
# Offense count: 21
|
47
|
-
# Cop supports --auto-correct.
|
48
|
-
Layout/ClosingParenthesisIndentation:
|
49
|
-
Enabled: false
|
50
|
-
|
51
|
-
# Offense count: 13
|
98
|
+
# Offense count: 12
|
52
99
|
# Cop supports --auto-correct.
|
53
|
-
# Configuration parameters:
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
100
|
+
# Configuration parameters: AutoCorrect, EnforcedStyle.
|
101
|
+
# SupportedStyles: nested, compact
|
102
|
+
Style/ClassAndModuleChildren:
|
103
|
+
Exclude:
|
104
|
+
- 'lib/restforce/middleware/authentication.rb'
|
105
|
+
- 'lib/restforce/middleware/authentication/password.rb'
|
106
|
+
- 'lib/restforce/middleware/authentication/token.rb'
|
107
|
+
- 'lib/restforce/middleware/authorization.rb'
|
108
|
+
- 'lib/restforce/middleware/caching.rb'
|
109
|
+
- 'lib/restforce/middleware/custom_headers.rb'
|
110
|
+
- 'lib/restforce/middleware/gzip.rb'
|
111
|
+
- 'lib/restforce/middleware/instance_url.rb'
|
112
|
+
- 'lib/restforce/middleware/logger.rb'
|
113
|
+
- 'lib/restforce/middleware/mashify.rb'
|
114
|
+
- 'lib/restforce/middleware/multipart.rb'
|
115
|
+
- 'lib/restforce/middleware/raise_error.rb'
|
116
|
+
|
117
|
+
# Offense count: 36
|
58
118
|
Style/Documentation:
|
59
119
|
Enabled: false
|
60
120
|
|
61
|
-
# Offense count:
|
121
|
+
# Offense count: 3
|
62
122
|
Style/DoubleNegation:
|
63
|
-
|
123
|
+
Exclude:
|
124
|
+
- 'lib/restforce/concerns/picklists.rb'
|
125
|
+
- 'lib/restforce/middleware/instance_url.rb'
|
64
126
|
|
65
|
-
# Offense count:
|
127
|
+
# Offense count: 1
|
66
128
|
# Configuration parameters: MinBodyLength.
|
67
129
|
Style/GuardClause:
|
68
|
-
|
69
|
-
|
70
|
-
# Offense count: 48
|
71
|
-
# Cop supports --auto-correct.
|
72
|
-
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
73
|
-
Layout/IndentHash:
|
74
|
-
Enabled: false
|
130
|
+
Exclude:
|
131
|
+
- 'lib/restforce/middleware/authentication.rb'
|
75
132
|
|
76
|
-
# Offense count:
|
133
|
+
# Offense count: 25
|
77
134
|
# Cop supports --auto-correct.
|
135
|
+
# Configuration parameters: EnforcedStyle.
|
136
|
+
# SupportedStyles: line_count_dependent, lambda, literal
|
78
137
|
Style/Lambda:
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
138
|
+
Exclude:
|
139
|
+
- 'lib/restforce/config.rb'
|
140
|
+
- 'spec/integration/abstract_client_spec.rb'
|
141
|
+
- 'spec/unit/concerns/base_spec.rb'
|
142
|
+
- 'spec/unit/concerns/streaming_spec.rb'
|
143
|
+
- 'spec/unit/middleware/authentication_spec.rb'
|
144
|
+
- 'spec/unit/middleware/authorization_spec.rb'
|
145
|
+
- 'spec/unit/middleware/custom_headers_spec.rb'
|
146
|
+
- 'spec/unit/middleware/gzip_spec.rb'
|
147
|
+
- 'spec/unit/middleware/instance_url_spec.rb'
|
148
|
+
- 'spec/unit/middleware/logger_spec.rb'
|
149
|
+
- 'spec/unit/sobject_spec.rb'
|
91
150
|
|
92
|
-
# Offense count:
|
93
|
-
# Cop supports --auto-correct.
|
94
|
-
Style/Proc:
|
95
|
-
Enabled: false
|
96
|
-
|
97
|
-
# Offense count: 173
|
151
|
+
# Offense count: 5
|
98
152
|
# Cop supports --auto-correct.
|
99
153
|
Style/RedundantSelf:
|
100
|
-
|
154
|
+
Exclude:
|
155
|
+
- 'lib/restforce/mash.rb'
|
156
|
+
- 'lib/restforce/sobject.rb'
|
101
157
|
|
102
|
-
# Offense count:
|
103
|
-
# Cop supports --auto-correct.
|
104
|
-
Layout/SpaceBeforeFirstArg:
|
105
|
-
Enabled: false
|
106
|
-
|
107
|
-
# Offense count: 3
|
108
|
-
# Cop supports --auto-correct.
|
109
|
-
# Configuration parameters: MultiSpaceAllowedForOperators.
|
110
|
-
Layout/SpaceAroundOperators:
|
111
|
-
Enabled: false
|
112
|
-
|
113
|
-
# Offense count: 5
|
158
|
+
# Offense count: 1
|
114
159
|
# Cop supports --auto-correct.
|
115
160
|
# Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, IgnoreClassMethods, Whitelist.
|
161
|
+
# Whitelist: to_ary, to_a, to_c, to_enum, to_h, to_hash, to_i, to_int, to_io, to_open, to_path, to_proc, to_r, to_regexp, to_str, to_s, to_sym
|
116
162
|
Style/TrivialAccessors:
|
117
|
-
|
163
|
+
Exclude:
|
164
|
+
- 'lib/restforce/middleware.rb'
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## 3.2.0 (Oct 9, 2019)
|
2
|
+
|
3
|
+
* Add support for the Batch API (@gaiottino, @teoulas)
|
4
|
+
* Return specific exceptions for errors that might be returned from Salesforce.com - instead of getting a generic `Faraday::Error::ClientError`, you might get something like a `Restforce::EntityTooLargeError` (@boblail)
|
5
|
+
* Expose the full response in exceptions' messages to make debugging easier (@boblail)
|
6
|
+
* Properly escape IDs with spaces in them when working with existing records (@pushups)
|
7
|
+
|
1
8
|
## 3.1.0 (Aug 16, 2018)
|
2
9
|
|
3
10
|
* Add support for replaying missed messages when using the Salesforce Streaming API (@andreimaxim, @drteeth, @panozzaj)
|
@@ -8,13 +15,19 @@
|
|
8
15
|
|
9
16
|
## 3.0.0 (Aug 2, 2018)
|
10
17
|
|
11
|
-
* __Deprecate support for Ruby 2.0, 2.1 and 2.2__, since [even Ruby 2.2 reached its end-of-life]
|
18
|
+
* __Deprecate support for Ruby 2.0, 2.1 and 2.2__, since [even Ruby 2.2 reached its end-of-life](https://www.ruby-lang.org/en/news/2018/06/20/support-of-ruby-2-2-has-ended/) in June 2018. (This is the only breaking change included in this version.)
|
12
19
|
* Fix `NoMethodError` when trying to upsert a record using a `Fixnum` as the external ID (@AlexandruCD)
|
13
20
|
* Escape record IDs passed in to the client to identify records to find, delete, etc. (@jmdx)
|
14
21
|
* Stop relying on our middleware for Gzip compression if you're using `httpclient`, since Faraday enables this automatically using `httpclient`'s built-in support (@shivanshgaur)
|
15
22
|
* Fix `get_updated` and `get_deleted` API calls by removing the erroneous leading forward slash from the path (@scottolsen)
|
16
23
|
* Fix unpacking of dependent picklist options (@parkm)
|
17
24
|
|
25
|
+
## 2.5.4 (May 15, 2019)
|
26
|
+
|
27
|
+
See the [`v2`](https://github.com/restforce/restforce/tree/v2) branch for this release.
|
28
|
+
|
29
|
+
* Escape record IDs passed in to the client to identify records to find, delete, etc. (@jmdx, @apanzerj)
|
30
|
+
|
18
31
|
## 2.5.3 (Apr 25, 2017)
|
19
32
|
|
20
33
|
* Raise an error where a custom external ID field name is supplied to `upsert` and `upsert!`, but it is missing from the provided attributes (@velveret)
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -25,7 +25,7 @@ Features include:
|
|
25
25
|
|
26
26
|
Add this line to your application's Gemfile:
|
27
27
|
|
28
|
-
gem 'restforce', '~> 3.
|
28
|
+
gem 'restforce', '~> 3.2.0'
|
29
29
|
|
30
30
|
And then execute:
|
31
31
|
|
@@ -43,7 +43,7 @@ This gem is versioned using [Semantic Versioning](http://semver.org/), so you ca
|
|
43
43
|
|
44
44
|
Restforce is designed with flexibility and ease of use in mind. By default, all API calls will
|
45
45
|
return [Hashie::Mash](https://github.com/intridea/hashie/tree/v1.2.0) objects,
|
46
|
-
so you can do things like `client.query('select Id, (select Name from Children__r) from Account').Children__r.first.Name`.
|
46
|
+
so you can do things like `client.query('select Id, (select Name from Children__r) from Account').first.Children__r.first.Name`.
|
47
47
|
|
48
48
|
### Initialization
|
49
49
|
|
@@ -523,7 +523,7 @@ require 'faye'
|
|
523
523
|
# Initialize a client with your username/password/oauth token/etc.
|
524
524
|
client = Restforce.new(username: 'foo',
|
525
525
|
password: 'bar',
|
526
|
-
security_token: 'security token'
|
526
|
+
security_token: 'security token',
|
527
527
|
client_id: 'client_id',
|
528
528
|
client_secret: 'client_secret')
|
529
529
|
|
@@ -585,7 +585,7 @@ memory using a Hash, stores a timestamp and has some rudimentary logic that
|
|
585
585
|
will use one of the magic IDs depending on the value of the timestamp:
|
586
586
|
|
587
587
|
```ruby
|
588
|
-
class
|
588
|
+
class SimpleReplayHandler
|
589
589
|
|
590
590
|
MAX_AGE = 86_400 # 24 hours
|
591
591
|
|
data/lib/restforce.rb
CHANGED
@@ -29,6 +29,7 @@ module Restforce
|
|
29
29
|
autoload :Verbs, 'restforce/concerns/verbs'
|
30
30
|
autoload :Base, 'restforce/concerns/base'
|
31
31
|
autoload :API, 'restforce/concerns/api'
|
32
|
+
autoload :BatchAPI, 'restforce/concerns/batch_api'
|
32
33
|
end
|
33
34
|
|
34
35
|
module Data
|
@@ -44,6 +45,25 @@ module Restforce
|
|
44
45
|
AuthenticationError = Class.new(Error)
|
45
46
|
UnauthorizedError = Class.new(Error)
|
46
47
|
APIVersionError = Class.new(Error)
|
48
|
+
BatchAPIError = Class.new(Error)
|
49
|
+
|
50
|
+
# Inherit from Faraday::Error::ResourceNotFound for backwards-compatibility
|
51
|
+
# Consumers of this library that rescue and handle Faraday::Error::ResourceNotFound
|
52
|
+
# can continue to do so.
|
53
|
+
NotFoundError = Class.new(Faraday::Error::ResourceNotFound)
|
54
|
+
|
55
|
+
# Inherit from Faraday::Error::ClientError for backwards-compatibility
|
56
|
+
# Consumers of this library that rescue and handle Faraday::Error::ClientError
|
57
|
+
# can continue to do so.
|
58
|
+
ResponseError = Class.new(Faraday::Error::ClientError)
|
59
|
+
MatchesMultipleError= Class.new(ResponseError)
|
60
|
+
EntityTooLargeError = Class.new(ResponseError)
|
61
|
+
|
62
|
+
module ErrorCode
|
63
|
+
def self.const_missing(constant_name)
|
64
|
+
const_set constant_name, Class.new(ResponseError)
|
65
|
+
end
|
66
|
+
end
|
47
67
|
|
48
68
|
class << self
|
49
69
|
# Alias for Restforce::Data::Client.new
|
@@ -74,7 +94,7 @@ module Restforce
|
|
74
94
|
self
|
75
95
|
end
|
76
96
|
end
|
77
|
-
Object.
|
97
|
+
Object.include Restforce::CoreExtensions unless Object.respond_to? :tap
|
78
98
|
end
|
79
99
|
|
80
100
|
if ENV['PROXY_URI']
|
data/lib/restforce/attachment.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'erb'
|
3
4
|
require 'uri'
|
4
5
|
require 'restforce/concerns/verbs'
|
5
6
|
|
@@ -320,6 +321,7 @@ module Restforce
|
|
320
321
|
def update!(sobject, attrs)
|
321
322
|
id = attrs.fetch(attrs.keys.find { |k, v| k.to_s.casecmp('id').zero? }, nil)
|
322
323
|
raise ArgumentError, 'ID field missing from provided attributes' unless id
|
324
|
+
|
323
325
|
attrs_without_id = attrs.reject { |k, v| k.to_s.casecmp("id").zero? }
|
324
326
|
api_patch "sobjects/#{sobject}/#{CGI.escape(id)}", attrs_without_id
|
325
327
|
true
|
@@ -377,7 +379,8 @@ module Restforce
|
|
377
379
|
api_post "sobjects/#{sobject}/#{field}", attrs
|
378
380
|
end
|
379
381
|
else
|
380
|
-
api_patch "sobjects/#{sobject}/#{field}
|
382
|
+
api_patch "sobjects/#{sobject}/#{field}/" \
|
383
|
+
"#{ERB::Util.url_encode(external_id)}", attrs
|
381
384
|
end
|
382
385
|
|
383
386
|
response.body.respond_to?(:fetch) ? response.body.fetch('id', true) : true
|
@@ -414,7 +417,7 @@ module Restforce
|
|
414
417
|
# Returns true of the sobject was successfully deleted.
|
415
418
|
# Raises an exception if an error is returned from Salesforce.
|
416
419
|
def destroy!(sobject, id)
|
417
|
-
api_delete "sobjects/#{sobject}/#{
|
420
|
+
api_delete "sobjects/#{sobject}/#{ERB::Util.url_encode(id)}"
|
418
421
|
true
|
419
422
|
end
|
420
423
|
|
@@ -428,9 +431,9 @@ module Restforce
|
|
428
431
|
# Returns the Restforce::SObject sobject record.
|
429
432
|
def find(sobject, id, field = nil)
|
430
433
|
url = if field
|
431
|
-
"sobjects/#{sobject}/#{field}/#{
|
434
|
+
"sobjects/#{sobject}/#{field}/#{ERB::Util.url_encode(id)}"
|
432
435
|
else
|
433
|
-
"sobjects/#{sobject}/#{
|
436
|
+
"sobjects/#{sobject}/#{ERB::Util.url_encode(id)}"
|
434
437
|
end
|
435
438
|
api_get(url).body
|
436
439
|
end
|
@@ -446,9 +449,9 @@ module Restforce
|
|
446
449
|
#
|
447
450
|
def select(sobject, id, select, field = nil)
|
448
451
|
path = if field
|
449
|
-
"sobjects/#{sobject}/#{field}/#{
|
452
|
+
"sobjects/#{sobject}/#{field}/#{ERB::Util.url_encode(id)}"
|
450
453
|
else
|
451
|
-
"sobjects/#{sobject}/#{
|
454
|
+
"sobjects/#{sobject}/#{ERB::Util.url_encode(id)}"
|
452
455
|
end
|
453
456
|
|
454
457
|
path = "#{path}?fields=#{select.join(',')}" if select&.any?
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'restforce/concerns/verbs'
|
4
|
+
|
5
|
+
module Restforce
|
6
|
+
module Concerns
|
7
|
+
module BatchAPI
|
8
|
+
extend Restforce::Concerns::Verbs
|
9
|
+
|
10
|
+
define_verbs :post
|
11
|
+
|
12
|
+
def batch(halt_on_error: false)
|
13
|
+
subrequests = Subrequests.new(options)
|
14
|
+
yield(subrequests)
|
15
|
+
subrequests.requests.each_slice(25).map do |requests|
|
16
|
+
properties = {
|
17
|
+
batchRequests: requests,
|
18
|
+
haltOnError: halt_on_error
|
19
|
+
}
|
20
|
+
response = api_post('composite/batch', properties.to_json)
|
21
|
+
body = response.body
|
22
|
+
results = body['results']
|
23
|
+
if halt_on_error && body['hasErrors']
|
24
|
+
last_error_index = results.rindex { |result| result['statusCode'] != 412 }
|
25
|
+
last_error = results[last_error_index]
|
26
|
+
raise BatchAPIError, last_error['result'][0]['errorCode']
|
27
|
+
end
|
28
|
+
results.map(&:compact)
|
29
|
+
end.flatten
|
30
|
+
end
|
31
|
+
|
32
|
+
def batch!(&block)
|
33
|
+
batch(halt_on_error: true, &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
class Subrequests
|
37
|
+
def initialize(options)
|
38
|
+
@options = options
|
39
|
+
@requests = []
|
40
|
+
end
|
41
|
+
attr_reader :options, :requests
|
42
|
+
|
43
|
+
def create(sobject, attrs)
|
44
|
+
requests << { method: 'POST', url: batch_api_path(sobject), richInput: attrs }
|
45
|
+
end
|
46
|
+
|
47
|
+
def update(sobject, attrs)
|
48
|
+
id = attrs.fetch(attrs.keys.find { |k, v| k.to_s.casecmp?('id') }, nil)
|
49
|
+
raise ArgumentError, 'Id field missing from attrs.' unless id
|
50
|
+
|
51
|
+
attrs_without_id = attrs.reject { |k, v| k.to_s.casecmp?('id') }
|
52
|
+
requests << {
|
53
|
+
method: 'PATCH',
|
54
|
+
url: batch_api_path("#{sobject}/#{id}"),
|
55
|
+
richInput: attrs_without_id
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def destroy(sobject, id)
|
60
|
+
requests << { method: 'DELETE', url: batch_api_path("#{sobject}/#{id}") }
|
61
|
+
end
|
62
|
+
|
63
|
+
def upsert(sobject, ext_field, attrs)
|
64
|
+
raise ArgumentError, 'External id field missing.' unless ext_field
|
65
|
+
|
66
|
+
ext_id = attrs.fetch(attrs.keys.find { |k, v|
|
67
|
+
k.to_s.casecmp?(ext_field.to_s)
|
68
|
+
}, nil)
|
69
|
+
raise ArgumentError, 'External id missing from attrs.' unless ext_id
|
70
|
+
|
71
|
+
attrs_without_ext_id = attrs.reject { |k, v| k.to_s.casecmp?(ext_field) }
|
72
|
+
requests << {
|
73
|
+
method: 'PATCH',
|
74
|
+
url: batch_api_path("#{sobject}/#{ext_field}/#{ext_id}"),
|
75
|
+
richInput: attrs_without_ext_id
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def batch_api_path(path)
|
82
|
+
"v#{options[:api_version]}/sobjects/#{path}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -62,9 +62,7 @@ module Restforce
|
|
62
62
|
|
63
63
|
def outgoing(message, callback)
|
64
64
|
# Leave non-subscribe messages alone
|
65
|
-
unless message['channel'] == '/meta/subscribe'
|
66
|
-
return callback.call(message)
|
67
|
-
end
|
65
|
+
return callback.call(message) unless message['channel'] == '/meta/subscribe'
|
68
66
|
|
69
67
|
channel = message['subscription'].gsub('/topic/', '')
|
70
68
|
|
data/lib/restforce/config.rb
CHANGED
data/lib/restforce/document.rb
CHANGED
@@ -6,23 +6,30 @@ module Restforce
|
|
6
6
|
@env = env
|
7
7
|
case env[:status]
|
8
8
|
when 300
|
9
|
-
raise
|
10
|
-
|
11
|
-
|
9
|
+
raise Restforce::MatchesMultipleError.new(
|
10
|
+
"300: The external ID provided matches more than one record",
|
11
|
+
response_values
|
12
|
+
)
|
12
13
|
when 401
|
13
14
|
raise Restforce::UnauthorizedError, message
|
14
15
|
when 404
|
15
|
-
raise
|
16
|
+
raise Restforce::NotFoundError, message
|
16
17
|
when 413
|
17
|
-
raise
|
18
|
-
|
18
|
+
raise Restforce::EntityTooLargeError.new(
|
19
|
+
"413: Request Entity Too Large",
|
20
|
+
response_values
|
21
|
+
)
|
19
22
|
when 400...600
|
20
|
-
|
23
|
+
klass = exception_class_for_error_code(body['errorCode'])
|
24
|
+
raise klass.new(message, response_values)
|
21
25
|
end
|
22
26
|
end
|
23
27
|
|
24
28
|
def message
|
25
|
-
"#{body['errorCode']}: #{body['message']}"
|
29
|
+
message = "#{body['errorCode']}: #{body['message']}"
|
30
|
+
message << "\nRESPONSE: #{JSON.dump(@env[:body])}"
|
31
|
+
rescue StandardError
|
32
|
+
message # if JSON.dump fails, return message without extra detail
|
26
33
|
end
|
27
34
|
|
28
35
|
def body
|
@@ -43,5 +50,14 @@ module Restforce
|
|
43
50
|
body: @env[:body]
|
44
51
|
}
|
45
52
|
end
|
53
|
+
|
54
|
+
ERROR_CODE_MATCHER = /\A[A-Z_]+\z/.freeze
|
55
|
+
|
56
|
+
def exception_class_for_error_code(error_code)
|
57
|
+
return Restforce::ResponseError unless ERROR_CODE_MATCHER.match?(error_code)
|
58
|
+
|
59
|
+
constant_name = error_code.split('_').map(&:capitalize).join.to_sym
|
60
|
+
Restforce::ErrorCode.const_get(constant_name)
|
61
|
+
end
|
46
62
|
end
|
47
63
|
end
|
data/lib/restforce/sobject.rb
CHANGED
data/lib/restforce/version.rb
CHANGED
data/restforce.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require File.expand_path('
|
3
|
+
require File.expand_path('lib/restforce/version', __dir__)
|
4
4
|
|
5
5
|
Gem::Specification.new do |gem|
|
6
6
|
gem.authors = ["Eric J. Holmes", "Tim Rogers"]
|
@@ -31,10 +31,10 @@ Gem::Specification.new do |gem|
|
|
31
31
|
|
32
32
|
gem.add_dependency 'hashie', ['>= 1.2.0', '< 4.0']
|
33
33
|
|
34
|
+
gem.add_development_dependency 'faye' unless RUBY_PLATFORM == 'java'
|
34
35
|
gem.add_development_dependency 'rspec', '~> 2.14.0'
|
35
|
-
gem.add_development_dependency 'webmock', '~> 3.4.0'
|
36
|
-
gem.add_development_dependency 'simplecov', '~> 0.15.0'
|
37
|
-
gem.add_development_dependency 'rubocop', '~> 0.50.0'
|
38
36
|
gem.add_development_dependency 'rspec_junit_formatter', '~> 0.3.0'
|
39
|
-
gem.add_development_dependency '
|
37
|
+
gem.add_development_dependency 'rubocop', '~> 0.75.0'
|
38
|
+
gem.add_development_dependency 'simplecov', '~> 0.17.1'
|
39
|
+
gem.add_development_dependency 'webmock', '~> 3.7.6'
|
40
40
|
end
|
@@ -96,7 +96,7 @@ shared_examples_for Restforce::AbstractClient do
|
|
96
96
|
subject do
|
97
97
|
client.create('Account', Name: 'Foobar',
|
98
98
|
Blob: Restforce::UploadIO.new(
|
99
|
-
File.expand_path('
|
99
|
+
File.expand_path('../fixtures/blob.jpg', __dir__),
|
100
100
|
'image/jpeg'
|
101
101
|
))
|
102
102
|
end
|
@@ -209,6 +209,24 @@ shared_examples_for Restforce::AbstractClient do
|
|
209
209
|
end
|
210
210
|
end
|
211
211
|
end
|
212
|
+
|
213
|
+
context 'when created with a space in the id' do
|
214
|
+
requests 'sobjects/Account/External__c/foo%20bar',
|
215
|
+
method: :patch,
|
216
|
+
with_body: "{\"Name\":\"Foobar\"}",
|
217
|
+
fixture: 'sobject/upsert_created_success_response'
|
218
|
+
|
219
|
+
[:External__c, 'External__c', :external__c, 'external__c'].each do |key|
|
220
|
+
context "with #{key.inspect} as the external id" do
|
221
|
+
subject do
|
222
|
+
client.upsert!('Account', 'External__c', key => 'foo bar',
|
223
|
+
:Name => 'Foobar')
|
224
|
+
end
|
225
|
+
|
226
|
+
it { should eq 'foo' }
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
212
230
|
end
|
213
231
|
|
214
232
|
describe '.destroy!' do
|
@@ -229,6 +247,13 @@ shared_examples_for Restforce::AbstractClient do
|
|
229
247
|
|
230
248
|
it { should be_true }
|
231
249
|
end
|
250
|
+
|
251
|
+
context 'with a space in the id' do
|
252
|
+
subject(:destroy!) { client.destroy!('Account', '001D000000 INjVe') }
|
253
|
+
requests 'sobjects/Account/001D000000%20INjVe', method: :delete
|
254
|
+
|
255
|
+
it { should be_true }
|
256
|
+
end
|
232
257
|
end
|
233
258
|
|
234
259
|
describe '.destroy' do
|
@@ -266,6 +291,14 @@ shared_examples_for Restforce::AbstractClient do
|
|
266
291
|
subject { client.find('Account', '1234', 'External_Field__c') }
|
267
292
|
it { should be_a Hash }
|
268
293
|
end
|
294
|
+
|
295
|
+
context 'with a space in an external id' do
|
296
|
+
requests 'sobjects/Account/External_Field__c/12%2034',
|
297
|
+
fixture: 'sobject/sobject_find_success_response'
|
298
|
+
|
299
|
+
subject { client.find('Account', '12 34', 'External_Field__c') }
|
300
|
+
it { should be_a Hash }
|
301
|
+
end
|
269
302
|
end
|
270
303
|
|
271
304
|
describe '.select' do
|
@@ -284,6 +317,14 @@ shared_examples_for Restforce::AbstractClient do
|
|
284
317
|
subject { client.select('Account', '1234', ['External_Field__c']) }
|
285
318
|
it { should be_a Hash }
|
286
319
|
end
|
320
|
+
|
321
|
+
context 'with a space in the id' do
|
322
|
+
requests 'sobjects/Account/12%2034',
|
323
|
+
fixture: 'sobject/sobject_select_success_response'
|
324
|
+
|
325
|
+
subject { client.select('Account', '12 34', nil, nil) }
|
326
|
+
it { should be_a Hash }
|
327
|
+
end
|
287
328
|
end
|
288
329
|
|
289
330
|
context 'when an external id is specified' do
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Restforce::Concerns::BatchAPI do
|
6
|
+
let(:endpoint) { 'composite/batch' }
|
7
|
+
|
8
|
+
before do
|
9
|
+
client.should_receive(:options).and_return(api_version: 34.0)
|
10
|
+
end
|
11
|
+
|
12
|
+
shared_examples_for 'batched requests' do
|
13
|
+
it '#create' do
|
14
|
+
client.
|
15
|
+
should_receive(:api_post).
|
16
|
+
with(endpoint, { batchRequests: [
|
17
|
+
{ method: 'POST', url: 'v34.0/sobjects/Object', richInput: { name: 'test' } }
|
18
|
+
], haltOnError: halt_on_error }.to_json).
|
19
|
+
and_return(response)
|
20
|
+
|
21
|
+
client.send(method) do |subrequests|
|
22
|
+
subrequests.create('Object', name: 'test')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it '#update' do
|
27
|
+
client.
|
28
|
+
should_receive(:api_post).
|
29
|
+
with(endpoint, { batchRequests: [
|
30
|
+
{ method: 'PATCH', url: "v34.0/sobjects/Object/123", richInput: {
|
31
|
+
name: 'test'
|
32
|
+
} }
|
33
|
+
], haltOnError: halt_on_error }.to_json).
|
34
|
+
and_return(response)
|
35
|
+
|
36
|
+
client.send(method) do |subrequests|
|
37
|
+
subrequests.update('Object', id: '123', name: 'test')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it '#destroy' do
|
42
|
+
client.
|
43
|
+
should_receive(:api_post).
|
44
|
+
with(endpoint, { batchRequests: [
|
45
|
+
{ method: 'DELETE', url: "v34.0/sobjects/Object/123" }
|
46
|
+
], haltOnError: halt_on_error }.to_json).
|
47
|
+
and_return(response)
|
48
|
+
|
49
|
+
client.send(method) do |subrequests|
|
50
|
+
subrequests.destroy('Object', '123')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it '#upsert' do
|
55
|
+
client.
|
56
|
+
should_receive(:api_post).
|
57
|
+
with(endpoint, { batchRequests: [
|
58
|
+
{ method: 'PATCH', url: 'v34.0/sobjects/Object/extIdField__c/456', richInput: {
|
59
|
+
name: 'test'
|
60
|
+
} }
|
61
|
+
], haltOnError: halt_on_error }.to_json).
|
62
|
+
and_return(response)
|
63
|
+
|
64
|
+
client.send(method) do |subrequests|
|
65
|
+
subrequests.upsert('Object', 'extIdField__c',
|
66
|
+
extIdField__c: '456', name: 'test')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'multiple subrequests' do
|
71
|
+
client.
|
72
|
+
should_receive(:api_post).
|
73
|
+
with(endpoint, { batchRequests: [
|
74
|
+
{ method: 'POST', url: 'v34.0/sobjects/Object', richInput: {
|
75
|
+
name: 'test'
|
76
|
+
} },
|
77
|
+
{ method: 'PATCH', url: "v34.0/sobjects/Object/123", richInput: {
|
78
|
+
name: 'test'
|
79
|
+
} },
|
80
|
+
{ method: 'DELETE', url: "v34.0/sobjects/Object/123" }
|
81
|
+
], haltOnError: halt_on_error }.to_json).
|
82
|
+
and_return(response)
|
83
|
+
|
84
|
+
client.send(method) do |subrequests|
|
85
|
+
subrequests.create('Object', name: 'test')
|
86
|
+
subrequests.update('Object', id: '123', name: 'test')
|
87
|
+
subrequests.destroy('Object', '123')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '#batch' do
|
93
|
+
let(:method) { :batch }
|
94
|
+
let(:halt_on_error) { false }
|
95
|
+
let(:response) { double('Faraday::Response', body: { 'results' => [] }) }
|
96
|
+
it_behaves_like 'batched requests'
|
97
|
+
end
|
98
|
+
|
99
|
+
describe '#batch!' do
|
100
|
+
let(:method) { :batch! }
|
101
|
+
let(:halt_on_error) { true }
|
102
|
+
let(:response) {
|
103
|
+
double('Faraday::Response', body: { 'hasErrors' => false, 'results' => [] })
|
104
|
+
}
|
105
|
+
it_behaves_like 'batched requests'
|
106
|
+
end
|
107
|
+
end
|
@@ -13,34 +13,46 @@ describe Restforce::Middleware::RaiseError do
|
|
13
13
|
context 'when the status code is 404' do
|
14
14
|
let(:status) { 404 }
|
15
15
|
|
16
|
-
it
|
17
|
-
expect { on_complete }.to raise_error
|
16
|
+
it 'raises Restforce::NotFoundError' do
|
17
|
+
expect { on_complete }.to raise_error Restforce::NotFoundError,
|
18
18
|
'INVALID_FIELD: error_message'
|
19
19
|
end
|
20
|
+
|
21
|
+
it 'raises an error that inherits from Faraday::Error::ResourceNotFound' do
|
22
|
+
expect { on_complete }.to raise_error Faraday::Error::ResourceNotFound
|
23
|
+
end
|
20
24
|
end
|
21
25
|
|
22
26
|
context 'when the status code is 300' do
|
23
27
|
let(:status) { 300 }
|
24
28
|
|
25
|
-
it
|
26
|
-
expect { on_complete }.to raise_error
|
29
|
+
it 'raises Restforce::MatchesMultipleError' do
|
30
|
+
expect { on_complete }.to raise_error Restforce::MatchesMultipleError,
|
27
31
|
/300: The external ID provided/
|
28
32
|
end
|
33
|
+
|
34
|
+
it 'raises an error that inherits from Faraday::Error::ClientError' do
|
35
|
+
expect { on_complete }.to raise_error Faraday::Error::ClientError
|
36
|
+
end
|
29
37
|
end
|
30
38
|
|
31
39
|
context 'when the status code is 400' do
|
32
40
|
let(:status) { 400 }
|
33
41
|
|
34
|
-
it "raises an error" do
|
35
|
-
expect { on_complete }.to raise_error
|
42
|
+
it "raises an error derived from the response's errorCode" do
|
43
|
+
expect { on_complete }.to raise_error Restforce::ErrorCode::InvalidField,
|
36
44
|
'INVALID_FIELD: error_message'
|
37
45
|
end
|
46
|
+
|
47
|
+
it 'raises an error that inherits from Faraday::Error::ClientError' do
|
48
|
+
expect { on_complete }.to raise_error Faraday::Error::ClientError
|
49
|
+
end
|
38
50
|
end
|
39
51
|
|
40
52
|
context 'when the status code is 401' do
|
41
53
|
let(:status) { 401 }
|
42
54
|
|
43
|
-
it
|
55
|
+
it 'raises Restforce::UnauthorizedError' do
|
44
56
|
expect { on_complete }.to raise_error Restforce::UnauthorizedError,
|
45
57
|
'INVALID_FIELD: error_message'
|
46
58
|
end
|
@@ -49,17 +61,26 @@ describe Restforce::Middleware::RaiseError do
|
|
49
61
|
context 'when the status code is 413' do
|
50
62
|
let(:status) { 413 }
|
51
63
|
|
52
|
-
it
|
53
|
-
expect { on_complete }.to raise_error
|
64
|
+
it 'raises Restforce::EntityTooLargeError' do
|
65
|
+
expect { on_complete }.to raise_error Restforce::EntityTooLargeError,
|
54
66
|
'413: Request Entity Too Large'
|
55
67
|
end
|
68
|
+
|
69
|
+
it 'raises an error that inherits from Faraday::Error::ClientError' do
|
70
|
+
expect { on_complete }.to raise_error Faraday::Error::ClientError
|
71
|
+
end
|
56
72
|
end
|
57
73
|
|
58
74
|
context 'when status is 400+ and body is a string' do
|
59
75
|
let(:body) { 'An error occured' }
|
60
|
-
let(:status) {
|
76
|
+
let(:status) { 400 }
|
77
|
+
|
78
|
+
it 'raises a generic Restforce::ResponseError' do
|
79
|
+
expect { on_complete }.to raise_error Restforce::ResponseError,
|
80
|
+
"(error code missing): #{body}"
|
81
|
+
end
|
61
82
|
|
62
|
-
it 'raises an error
|
83
|
+
it 'raises an error that inherits from Faraday::Error::ClientError' do
|
63
84
|
expect { on_complete }.to raise_error Faraday::Error::ClientError,
|
64
85
|
"(error code missing): #{body}"
|
65
86
|
end
|
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: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric J. Holmes
|
@@ -9,28 +9,28 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2019-10-09 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
|
-
- - "<="
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: '1.0'
|
21
18
|
- - ">="
|
22
19
|
- !ruby/object:Gem::Version
|
23
20
|
version: 0.9.0
|
21
|
+
- - "<="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '1.0'
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
27
27
|
requirements:
|
28
|
-
- - "<="
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
version: '1.0'
|
31
28
|
- - ">="
|
32
29
|
- !ruby/object:Gem::Version
|
33
30
|
version: 0.9.0
|
31
|
+
- - "<="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: faraday_middleware
|
36
36
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,89 +86,89 @@ dependencies:
|
|
86
86
|
- !ruby/object:Gem::Version
|
87
87
|
version: '4.0'
|
88
88
|
- !ruby/object:Gem::Dependency
|
89
|
-
name:
|
89
|
+
name: faye
|
90
90
|
requirement: !ruby/object:Gem::Requirement
|
91
91
|
requirements:
|
92
|
-
- - "
|
92
|
+
- - ">="
|
93
93
|
- !ruby/object:Gem::Version
|
94
|
-
version:
|
94
|
+
version: '0'
|
95
95
|
type: :development
|
96
96
|
prerelease: false
|
97
97
|
version_requirements: !ruby/object:Gem::Requirement
|
98
98
|
requirements:
|
99
|
-
- - "
|
99
|
+
- - ">="
|
100
100
|
- !ruby/object:Gem::Version
|
101
|
-
version:
|
101
|
+
version: '0'
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
|
-
name:
|
103
|
+
name: rspec
|
104
104
|
requirement: !ruby/object:Gem::Requirement
|
105
105
|
requirements:
|
106
106
|
- - "~>"
|
107
107
|
- !ruby/object:Gem::Version
|
108
|
-
version:
|
108
|
+
version: 2.14.0
|
109
109
|
type: :development
|
110
110
|
prerelease: false
|
111
111
|
version_requirements: !ruby/object:Gem::Requirement
|
112
112
|
requirements:
|
113
113
|
- - "~>"
|
114
114
|
- !ruby/object:Gem::Version
|
115
|
-
version:
|
115
|
+
version: 2.14.0
|
116
116
|
- !ruby/object:Gem::Dependency
|
117
|
-
name:
|
117
|
+
name: rspec_junit_formatter
|
118
118
|
requirement: !ruby/object:Gem::Requirement
|
119
119
|
requirements:
|
120
120
|
- - "~>"
|
121
121
|
- !ruby/object:Gem::Version
|
122
|
-
version: 0.
|
122
|
+
version: 0.3.0
|
123
123
|
type: :development
|
124
124
|
prerelease: false
|
125
125
|
version_requirements: !ruby/object:Gem::Requirement
|
126
126
|
requirements:
|
127
127
|
- - "~>"
|
128
128
|
- !ruby/object:Gem::Version
|
129
|
-
version: 0.
|
129
|
+
version: 0.3.0
|
130
130
|
- !ruby/object:Gem::Dependency
|
131
131
|
name: rubocop
|
132
132
|
requirement: !ruby/object:Gem::Requirement
|
133
133
|
requirements:
|
134
134
|
- - "~>"
|
135
135
|
- !ruby/object:Gem::Version
|
136
|
-
version: 0.
|
136
|
+
version: 0.75.0
|
137
137
|
type: :development
|
138
138
|
prerelease: false
|
139
139
|
version_requirements: !ruby/object:Gem::Requirement
|
140
140
|
requirements:
|
141
141
|
- - "~>"
|
142
142
|
- !ruby/object:Gem::Version
|
143
|
-
version: 0.
|
143
|
+
version: 0.75.0
|
144
144
|
- !ruby/object:Gem::Dependency
|
145
|
-
name:
|
145
|
+
name: simplecov
|
146
146
|
requirement: !ruby/object:Gem::Requirement
|
147
147
|
requirements:
|
148
148
|
- - "~>"
|
149
149
|
- !ruby/object:Gem::Version
|
150
|
-
version: 0.
|
150
|
+
version: 0.17.1
|
151
151
|
type: :development
|
152
152
|
prerelease: false
|
153
153
|
version_requirements: !ruby/object:Gem::Requirement
|
154
154
|
requirements:
|
155
155
|
- - "~>"
|
156
156
|
- !ruby/object:Gem::Version
|
157
|
-
version: 0.
|
157
|
+
version: 0.17.1
|
158
158
|
- !ruby/object:Gem::Dependency
|
159
|
-
name:
|
159
|
+
name: webmock
|
160
160
|
requirement: !ruby/object:Gem::Requirement
|
161
161
|
requirements:
|
162
|
-
- - "
|
162
|
+
- - "~>"
|
163
163
|
- !ruby/object:Gem::Version
|
164
|
-
version:
|
164
|
+
version: 3.7.6
|
165
165
|
type: :development
|
166
166
|
prerelease: false
|
167
167
|
version_requirements: !ruby/object:Gem::Requirement
|
168
168
|
requirements:
|
169
|
-
- - "
|
169
|
+
- - "~>"
|
170
170
|
- !ruby/object:Gem::Version
|
171
|
-
version:
|
171
|
+
version: 3.7.6
|
172
172
|
description: A lightweight ruby client for the Salesforce REST API.
|
173
173
|
email:
|
174
174
|
- eric@ejholmes.net
|
@@ -197,6 +197,7 @@ files:
|
|
197
197
|
- lib/restforce/concerns/api.rb
|
198
198
|
- lib/restforce/concerns/authentication.rb
|
199
199
|
- lib/restforce/concerns/base.rb
|
200
|
+
- lib/restforce/concerns/batch_api.rb
|
200
201
|
- lib/restforce/concerns/caching.rb
|
201
202
|
- lib/restforce/concerns/canvas.rb
|
202
203
|
- lib/restforce/concerns/connection.rb
|
@@ -281,6 +282,7 @@ files:
|
|
281
282
|
- spec/unit/concerns/api_spec.rb
|
282
283
|
- spec/unit/concerns/authentication_spec.rb
|
283
284
|
- spec/unit/concerns/base_spec.rb
|
285
|
+
- spec/unit/concerns/batch_api_spec.rb
|
284
286
|
- spec/unit/concerns/caching_spec.rb
|
285
287
|
- spec/unit/concerns/canvas_spec.rb
|
286
288
|
- spec/unit/concerns/connection_spec.rb
|
@@ -323,8 +325,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
323
325
|
- !ruby/object:Gem::Version
|
324
326
|
version: '0'
|
325
327
|
requirements: []
|
326
|
-
|
327
|
-
rubygems_version: 2.6.14.1
|
328
|
+
rubygems_version: 3.0.3
|
328
329
|
signing_key:
|
329
330
|
specification_version: 4
|
330
331
|
summary: A lightweight ruby client for the Salesforce REST API.
|
@@ -379,6 +380,7 @@ test_files:
|
|
379
380
|
- spec/unit/concerns/api_spec.rb
|
380
381
|
- spec/unit/concerns/authentication_spec.rb
|
381
382
|
- spec/unit/concerns/base_spec.rb
|
383
|
+
- spec/unit/concerns/batch_api_spec.rb
|
382
384
|
- spec/unit/concerns/caching_spec.rb
|
383
385
|
- spec/unit/concerns/canvas_spec.rb
|
384
386
|
- spec/unit/concerns/connection_spec.rb
|