restforce 2.5.4 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.circleci/config.yml +56 -0
- data/.rubocop.yml +18 -3
- data/.rubocop_todo.yml +8 -8
- data/CHANGELOG.md +12 -3
- data/CONTRIBUTING.md +3 -3
- data/Gemfile +4 -2
- data/Guardfile +3 -1
- data/LICENSE +1 -1
- data/README.md +22 -16
- data/Rakefile +2 -1
- data/lib/restforce.rb +2 -0
- data/lib/restforce/abstract_client.rb +2 -0
- data/lib/restforce/attachment.rb +2 -0
- data/lib/restforce/client.rb +2 -0
- data/lib/restforce/collection.rb +3 -1
- data/lib/restforce/concerns/api.rb +11 -8
- data/lib/restforce/concerns/authentication.rb +2 -0
- data/lib/restforce/concerns/base.rb +2 -0
- data/lib/restforce/concerns/caching.rb +4 -2
- data/lib/restforce/concerns/canvas.rb +2 -0
- data/lib/restforce/concerns/connection.rb +26 -20
- data/lib/restforce/concerns/picklists.rb +7 -5
- data/lib/restforce/concerns/streaming.rb +2 -0
- data/lib/restforce/concerns/verbs.rb +3 -1
- data/lib/restforce/config.rb +3 -1
- data/lib/restforce/data/client.rb +2 -0
- data/lib/restforce/document.rb +2 -0
- data/lib/restforce/mash.rb +2 -0
- data/lib/restforce/middleware.rb +2 -0
- data/lib/restforce/middleware/authentication.rb +8 -6
- data/lib/restforce/middleware/authentication/password.rb +2 -0
- data/lib/restforce/middleware/authentication/token.rb +2 -0
- data/lib/restforce/middleware/authorization.rb +3 -1
- data/lib/restforce/middleware/caching.rb +3 -1
- data/lib/restforce/middleware/custom_headers.rb +2 -0
- data/lib/restforce/middleware/gzip.rb +5 -3
- data/lib/restforce/middleware/instance_url.rb +7 -3
- data/lib/restforce/middleware/logger.rb +2 -0
- data/lib/restforce/middleware/mashify.rb +2 -0
- data/lib/restforce/middleware/multipart.rb +7 -4
- data/lib/restforce/middleware/raise_error.rb +2 -0
- data/lib/restforce/patches/parts.rb +2 -0
- data/lib/restforce/signed_request.rb +2 -0
- data/lib/restforce/sobject.rb +2 -0
- data/lib/restforce/tooling/client.rb +2 -0
- data/lib/restforce/upload_io.rb +2 -0
- data/lib/restforce/version.rb +3 -1
- data/restforce.gemspec +17 -10
- data/spec/fixtures/sobject/sobject_describe_success_response.json +48 -1
- data/spec/integration/abstract_client_spec.rb +9 -6
- data/spec/integration/data/client_spec.rb +24 -5
- data/spec/spec_helper.rb +2 -0
- data/spec/support/client_integration.rb +2 -0
- data/spec/support/concerns.rb +2 -0
- data/spec/support/event_machine.rb +2 -0
- data/spec/support/fixture_helpers.rb +2 -0
- data/spec/support/matchers.rb +2 -0
- data/spec/support/middleware.rb +3 -1
- data/spec/support/mock_cache.rb +4 -2
- data/spec/unit/abstract_client_spec.rb +2 -0
- data/spec/unit/attachment_spec.rb +2 -0
- data/spec/unit/collection_spec.rb +5 -3
- data/spec/unit/concerns/api_spec.rb +30 -11
- data/spec/unit/concerns/authentication_spec.rb +4 -2
- data/spec/unit/concerns/base_spec.rb +2 -0
- data/spec/unit/concerns/caching_spec.rb +2 -0
- data/spec/unit/concerns/canvas_spec.rb +3 -1
- data/spec/unit/concerns/connection_spec.rb +5 -3
- data/spec/unit/concerns/streaming_spec.rb +3 -1
- data/spec/unit/config_spec.rb +10 -8
- data/spec/unit/data/client_spec.rb +2 -0
- data/spec/unit/document_spec.rb +2 -0
- data/spec/unit/mash_spec.rb +3 -1
- data/spec/unit/middleware/authentication/password_spec.rb +2 -0
- data/spec/unit/middleware/authentication/token_spec.rb +2 -0
- data/spec/unit/middleware/authentication_spec.rb +3 -1
- data/spec/unit/middleware/authorization_spec.rb +2 -0
- data/spec/unit/middleware/custom_headers_spec.rb +3 -1
- data/spec/unit/middleware/gzip_spec.rb +4 -2
- data/spec/unit/middleware/instance_url_spec.rb +2 -0
- data/spec/unit/middleware/logger_spec.rb +2 -0
- data/spec/unit/middleware/mashify_spec.rb +3 -1
- data/spec/unit/middleware/raise_error_spec.rb +2 -0
- data/spec/unit/signed_request_spec.rb +2 -0
- data/spec/unit/sobject_spec.rb +5 -3
- data/spec/unit/tooling/client_spec.rb +2 -0
- metadata +35 -19
- data/.travis.yml +0 -16
- data/Gemfile.travis +0 -8
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Restforce
|
2
4
|
module Concerns
|
3
5
|
module Caching
|
@@ -6,9 +8,9 @@ module Restforce
|
|
6
8
|
# block - A query/describe/etc.
|
7
9
|
#
|
8
10
|
# Returns the result of the block
|
9
|
-
def without_caching
|
11
|
+
def without_caching
|
10
12
|
options[:use_cache] = false
|
11
|
-
|
13
|
+
yield
|
12
14
|
ensure
|
13
15
|
options.delete(:use_cache)
|
14
16
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Restforce
|
2
4
|
module Concerns
|
3
5
|
module Connection
|
@@ -13,7 +15,7 @@ module Restforce
|
|
13
15
|
def middleware
|
14
16
|
connection.builder
|
15
17
|
end
|
16
|
-
|
18
|
+
alias builder middleware
|
17
19
|
|
18
20
|
private
|
19
21
|
|
@@ -22,40 +24,44 @@ module Restforce
|
|
22
24
|
@connection ||= Faraday.new(options[:instance_url],
|
23
25
|
connection_options) do |builder|
|
24
26
|
# Parses JSON into Hashie::Mash structures.
|
25
|
-
unless
|
26
|
-
builder.use
|
27
|
+
unless options[:mashify] == false
|
28
|
+
builder.use Restforce::Middleware::Mashify, self, options
|
27
29
|
end
|
28
30
|
|
29
31
|
# Handles multipart file uploads for blobs.
|
30
|
-
builder.use
|
32
|
+
builder.use Restforce::Middleware::Multipart
|
31
33
|
# Converts the request into JSON.
|
32
|
-
builder.request
|
34
|
+
builder.request :json
|
33
35
|
# Handles reauthentication for 403 responses.
|
34
36
|
if authentication_middleware
|
35
|
-
builder.use
|
37
|
+
builder.use authentication_middleware, self, options
|
36
38
|
end
|
37
39
|
# Sets the oauth token in the headers.
|
38
|
-
builder.use
|
40
|
+
builder.use Restforce::Middleware::Authorization, self, options
|
39
41
|
# Ensures the instance url is set.
|
40
|
-
builder.use
|
42
|
+
builder.use Restforce::Middleware::InstanceURL, self, options
|
41
43
|
# Caches GET requests.
|
42
|
-
builder.use
|
44
|
+
builder.use Restforce::Middleware::Caching, cache, options if cache
|
43
45
|
# Follows 30x redirects.
|
44
|
-
builder.use
|
46
|
+
builder.use FaradayMiddleware::FollowRedirects
|
45
47
|
# Raises errors for 40x responses.
|
46
|
-
builder.use
|
48
|
+
builder.use Restforce::Middleware::RaiseError
|
47
49
|
# Parses returned JSON response into a hash.
|
48
50
|
builder.response :json, content_type: /\bjson$/
|
49
51
|
# Compress/Decompress the request/response
|
50
|
-
|
52
|
+
unless adapter == :httpclient
|
53
|
+
builder.use Restforce::Middleware::Gzip, self, options
|
54
|
+
end
|
51
55
|
# Inject custom headers into requests
|
52
|
-
builder.use
|
56
|
+
builder.use Restforce::Middleware::CustomHeaders, self, options
|
53
57
|
# Log request/responses
|
54
|
-
|
55
|
-
|
56
|
-
|
58
|
+
if Restforce.log?
|
59
|
+
builder.use Restforce::Middleware::Logger,
|
60
|
+
Restforce.configuration.logger,
|
61
|
+
options
|
62
|
+
end
|
57
63
|
|
58
|
-
builder.adapter
|
64
|
+
builder.adapter adapter
|
59
65
|
end
|
60
66
|
end
|
61
67
|
|
@@ -67,10 +73,10 @@ module Restforce
|
|
67
73
|
def connection_options
|
68
74
|
{ request: {
|
69
75
|
timeout: options[:timeout],
|
70
|
-
open_timeout: options[:timeout]
|
76
|
+
open_timeout: options[:timeout]
|
77
|
+
},
|
71
78
|
proxy: options[:proxy_uri],
|
72
|
-
ssl: options[:ssl]
|
73
|
-
}
|
79
|
+
ssl: options[:ssl] }
|
74
80
|
end
|
75
81
|
|
76
82
|
# Internal: Returns true if the middlware stack includes the
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Restforce
|
2
4
|
module Concerns
|
3
5
|
module Picklists
|
@@ -26,8 +28,6 @@ module Restforce
|
|
26
28
|
PicklistValues.new(describe(sobject)['fields'], field, options)
|
27
29
|
end
|
28
30
|
|
29
|
-
private
|
30
|
-
|
31
31
|
class PicklistValues < Array
|
32
32
|
def initialize(fields, field, options = {})
|
33
33
|
@fields = fields
|
@@ -60,7 +60,9 @@ module Restforce
|
|
60
60
|
|
61
61
|
def controlling_picklist
|
62
62
|
@_controlling_picklist ||= controlling_field['picklistValues'].
|
63
|
-
|
63
|
+
find do |picklist_entry|
|
64
|
+
picklist_entry['value'] == @valid_for
|
65
|
+
end
|
64
66
|
end
|
65
67
|
|
66
68
|
def index
|
@@ -81,8 +83,8 @@ module Restforce
|
|
81
83
|
# cribesobjects_describesobjectresult.htm
|
82
84
|
def valid?(picklist_entry)
|
83
85
|
valid_for = picklist_entry['validFor'].ljust(16, 'A').unpack('m').first.
|
84
|
-
|
85
|
-
(valid_for[index >> 3] & (0x80 >> index % 8))
|
86
|
+
unpack('C*')
|
87
|
+
(valid_for[index >> 3] & (0x80 >> index % 8)).positive?
|
86
88
|
end
|
87
89
|
end
|
88
90
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Restforce
|
2
4
|
module Concerns
|
3
5
|
module Verbs
|
@@ -34,7 +36,7 @@ module Restforce
|
|
34
36
|
begin
|
35
37
|
connection.send(verb, *args, &block)
|
36
38
|
rescue Restforce::UnauthorizedError
|
37
|
-
if retries
|
39
|
+
if retries.positive?
|
38
40
|
retries -= 1
|
39
41
|
connection.url_prefix = options[:instance_url]
|
40
42
|
retry
|
data/lib/restforce/config.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'logger'
|
2
4
|
|
3
5
|
module Restforce
|
@@ -60,7 +62,7 @@ module Restforce
|
|
60
62
|
private
|
61
63
|
|
62
64
|
attr_reader :default
|
63
|
-
|
65
|
+
alias default_provided? default
|
64
66
|
|
65
67
|
def write_attribute
|
66
68
|
configuration.send :attr_accessor, name
|
data/lib/restforce/document.rb
CHANGED
data/lib/restforce/mash.rb
CHANGED
data/lib/restforce/middleware.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Restforce
|
2
4
|
# Faraday middleware that allows for on the fly authentication of requests.
|
3
5
|
# When a request fails (a status of 401 is returned), the middleware
|
@@ -31,9 +33,7 @@ module Restforce
|
|
31
33
|
@options[:instance_url] = response.body['instance_url']
|
32
34
|
@options[:oauth_token] = response.body['access_token']
|
33
35
|
|
34
|
-
|
35
|
-
@options[:authentication_callback].call(response.body)
|
36
|
-
end
|
36
|
+
@options[:authentication_callback]&.call(response.body)
|
37
37
|
|
38
38
|
response.body
|
39
39
|
end
|
@@ -50,9 +50,11 @@ module Restforce
|
|
50
50
|
builder.use Restforce::Middleware::Mashify, nil, @options
|
51
51
|
builder.response :json
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
|
53
|
+
if Restforce.log?
|
54
|
+
builder.use Restforce::Middleware::Logger,
|
55
|
+
Restforce.configuration.logger,
|
56
|
+
@options
|
57
|
+
end
|
56
58
|
|
57
59
|
builder.adapter @options[:adapter]
|
58
60
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Restforce
|
2
4
|
# Piece of middleware that simply injects the OAuth token into the request
|
3
5
|
# headers.
|
4
6
|
class Middleware::Authorization < Restforce::Middleware
|
5
|
-
AUTH_HEADER = 'Authorization'
|
7
|
+
AUTH_HEADER = 'Authorization'
|
6
8
|
|
7
9
|
def call(env)
|
8
10
|
env[:request_headers][AUTH_HEADER] = %(OAuth #{token})
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Restforce
|
2
4
|
class Middleware::Caching < FaradayMiddleware::Caching
|
3
5
|
def call(env)
|
@@ -6,7 +8,7 @@ module Restforce
|
|
6
8
|
end
|
7
9
|
|
8
10
|
def expire(key)
|
9
|
-
cache
|
11
|
+
cache&.delete(key)
|
10
12
|
end
|
11
13
|
|
12
14
|
# We don't want to cache requests for different clients, so append the
|
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'zlib'
|
2
4
|
|
3
5
|
module Restforce
|
4
6
|
# Middleware to uncompress GZIP compressed responses from Salesforce.
|
5
7
|
class Middleware::Gzip < Restforce::Middleware
|
6
|
-
ACCEPT_ENCODING_HEADER = 'Accept-Encoding'
|
7
|
-
CONTENT_ENCODING_HEADER = 'Content-Encoding'
|
8
|
-
ENCODING = 'gzip'
|
8
|
+
ACCEPT_ENCODING_HEADER = 'Accept-Encoding'
|
9
|
+
CONTENT_ENCODING_HEADER = 'Content-Encoding'
|
10
|
+
ENCODING = 'gzip'
|
9
11
|
|
10
12
|
def call(env)
|
11
13
|
env[:request_headers][ACCEPT_ENCODING_HEADER] = ENCODING if @options[:compress]
|
@@ -1,16 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Restforce
|
2
4
|
# Middleware which asserts that the instance_url is always set
|
3
5
|
class Middleware::InstanceURL < Restforce::Middleware
|
4
6
|
def call(env)
|
5
7
|
# If the connection url_prefix isn't set, we must not be authenticated.
|
6
|
-
|
7
|
-
|
8
|
+
unless url_prefix_set?
|
9
|
+
raise Restforce::UnauthorizedError,
|
10
|
+
'Connection prefix not set'
|
11
|
+
end
|
8
12
|
|
9
13
|
@app.call(env)
|
10
14
|
end
|
11
15
|
|
12
16
|
def url_prefix_set?
|
13
|
-
!!(connection.url_prefix
|
17
|
+
!!(connection.url_prefix&.host)
|
14
18
|
end
|
15
19
|
end
|
16
20
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Restforce
|
2
4
|
class Middleware::Multipart < Faraday::Request::UrlEncoded
|
3
|
-
self.mime_type = 'multipart/form-data'
|
4
|
-
DEFAULT_BOUNDARY = "--boundary_string"
|
5
|
-
JSON_CONTENT_TYPE = { "Content-Type" => "application/json" }
|
5
|
+
self.mime_type = 'multipart/form-data'
|
6
|
+
DEFAULT_BOUNDARY = "--boundary_string"
|
7
|
+
JSON_CONTENT_TYPE = { "Content-Type" => "application/json" }.freeze
|
6
8
|
|
7
9
|
def call(env)
|
8
10
|
match_content_type(env) do |params|
|
@@ -46,9 +48,10 @@ module Restforce
|
|
46
48
|
|
47
49
|
# Files
|
48
50
|
params.each do |k, v|
|
51
|
+
next unless v.respond_to? :content_type
|
49
52
|
parts << Faraday::Parts::Part.new(boundary,
|
50
53
|
k.to_s,
|
51
|
-
v)
|
54
|
+
v)
|
52
55
|
end
|
53
56
|
|
54
57
|
parts << Faraday::Parts::EpiloguePart.new(boundary)
|
data/lib/restforce/sobject.rb
CHANGED
data/lib/restforce/upload_io.rb
CHANGED
data/lib/restforce/version.rb
CHANGED
data/restforce.gemspec
CHANGED
@@ -1,24 +1,30 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require File.expand_path('../lib/restforce/version', __FILE__)
|
3
4
|
|
4
5
|
Gem::Specification.new do |gem|
|
5
6
|
gem.authors = ["Eric J. Holmes", "Tim Rogers"]
|
6
7
|
gem.email = ["eric@ejholmes.net", "tim@gocardless.com"]
|
7
|
-
gem.description =
|
8
|
-
gem.summary =
|
8
|
+
gem.description = 'A lightweight ruby client for the Salesforce REST API.'
|
9
|
+
gem.summary = 'A lightweight ruby client for the Salesforce REST API.'
|
9
10
|
gem.homepage = "http://restforce.org/"
|
10
11
|
gem.license = "MIT"
|
11
12
|
|
12
|
-
gem.files = `git ls-files`.split(
|
13
|
-
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
|
14
|
+
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
14
15
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
15
16
|
gem.name = "restforce"
|
16
17
|
gem.require_paths = ["lib"]
|
17
18
|
gem.version = Restforce::VERSION
|
18
19
|
|
19
|
-
gem.
|
20
|
+
gem.metadata = {
|
21
|
+
'source_code_uri' => 'https://github.com/restforce/restforce',
|
22
|
+
'changelog_uri' => 'https://github.com/restforce/restforce/blob/master/CHANGELOG.md'
|
23
|
+
}
|
24
|
+
|
25
|
+
gem.required_ruby_version = '>= 2.3'
|
20
26
|
|
21
|
-
gem.add_dependency 'faraday',
|
27
|
+
gem.add_dependency 'faraday', '<= 1.0', '>= 0.9.0'
|
22
28
|
gem.add_dependency 'faraday_middleware', ['>= 0.8.8', '<= 1.0']
|
23
29
|
|
24
30
|
gem.add_dependency 'json', '>= 1.7.5'
|
@@ -26,8 +32,9 @@ Gem::Specification.new do |gem|
|
|
26
32
|
gem.add_dependency 'hashie', ['>= 1.2.0', '< 4.0']
|
27
33
|
|
28
34
|
gem.add_development_dependency 'rspec', '~> 2.14.0'
|
29
|
-
gem.add_development_dependency 'webmock', '~>
|
30
|
-
gem.add_development_dependency 'simplecov', '~> 0.
|
31
|
-
gem.add_development_dependency 'rubocop', '~> 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
|
+
gem.add_development_dependency 'rspec_junit_formatter', '~> 0.3.0'
|
32
39
|
gem.add_development_dependency 'faye' unless RUBY_PLATFORM == 'java'
|
33
40
|
end
|