easypost 3.0.1 → 3.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 6168d8faeaf5226b22bed0526e692acb11d0c29d8bcdc42d744c725112854792
4
- data.tar.gz: 6fc7826c1e0c958cee412cb9554268c0665ee7a11080ed1309d39f5fbceb9d65
2
+ SHA1:
3
+ metadata.gz: c78ad14a13a665a9397b5d2ade56cdad38a669f0
4
+ data.tar.gz: e73234c20adee8cfcbc37f2b93fb1c5aa2a6843d
5
5
  SHA512:
6
- metadata.gz: 52832eace51fd93e54fdf6117b73beb5facdeb76f6df4a5a50fea512bc4983744cb09ba06e9ed204f91979fee7f902ca9814fbfd9b104075ed99f842bc088d70
7
- data.tar.gz: a5f572caca04940e794a8f363c48713159b8a946a82bc76a0465a4408d78ecb5b3419c4e32caa152e0f0e7b7071d67cbbb50dc858fc42dc01e4e0a14c5bf5391
6
+ metadata.gz: 29e64cace8628e794a110868fbf3395fe560f1334ebe04218ccab054edf84f64631895196a09967ad06021b405162ee660eb29e86992847dfcfd45dc5b7b1549
7
+ data.tar.gz: f5e58cd6bdbe1cf61b3e272986470eb5beb7c9ba8738a4ebe05b727803c741a518ab5d64876ba2ff8bbb5ae2f331c8f6b977b4f53c1839336ebb72c3ef08337a
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2
4
+ - 2.3
5
+ - 2.4
6
+ - 2.5
7
+ - 2.6
8
+ - 2.7
9
+ script: "bundle exec rspec"
data/CHANGELOG CHANGED
@@ -1,3 +1,21 @@
1
+ === 3.1.3 2020-06-26
2
+
3
+ * Fix bug causing Authorization header to be included in User-Agent header. All users must upgrade.
4
+
5
+ === 3.1.2 2020-06-24
6
+
7
+ * Bad gem push. New version required.
8
+
9
+ === 3.1.1 2020-06-23
10
+
11
+ * Fix bug where EasyPost.http_config was invalid when not explicitly initialized.
12
+
13
+ === 3.1.0 2020-06-23
14
+
15
+ * Add Shipment Invoice and Refund Report
16
+ * Remove dependencies on `RestClient` and `MultiJson`
17
+ * Remove some deprecated endpoints
18
+
1
19
  === 3.0.1 2018-05-17
2
20
 
3
21
  * Enforce TLS certificate validity by default
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # EasyPost Ruby Client Library
2
2
 
3
- [<img src="https://circleci.com/gh/EasyPost/easypost-ruby.png?circle-token=80adb5236ed1fdce20810b055af79c63c3d5796b">](https://circleci.com/gh/EasyPost/easypost-ruby)
3
+ [![Build Status](https://travis-ci.com/EasyPost/easypost-ruby.svg?branch=master)](https://travis-ci.com/EasyPost/easypost-ruby)
4
4
 
5
5
 
6
6
  EasyPost is a simple shipping API. You can sign up for an account at https://easypost.com
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.1
1
+ 3.1.3
@@ -1,27 +1,31 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
2
+
3
+ lib = File.expand_path("../lib", __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'easypost/version'
5
+ require "easypost/version"
5
6
 
6
7
  Gem::Specification.new do |spec|
7
- spec.name = 'easypost'
8
- spec.version = EasyPost::VERSION
9
- spec.date = Time.now.strftime("%Y-%m-%d")
10
- spec.summary = 'EasyPost Ruby Client Library'
11
- spec.description = 'Client library for accessing the EasyPost shipping API via Ruby.'
12
- spec.authors = ['Sawyer Bateman']
13
- spec.email = 'contact@easypost.com'
14
- spec.homepage = 'https://www.easypost.com/docs'
8
+ spec.name = "easypost"
9
+ spec.version = EasyPost::VERSION
10
+ spec.licenses = ["MIT"]
11
+ spec.date = Time.now.strftime("%Y-%m-%d")
12
+ spec.summary = "EasyPost Ruby Client Library"
13
+ spec.description = "Client library for accessing the EasyPost shipping API via Ruby."
14
+ spec.authors = ["Jake Epstein", "Andrew Tribone", "James Brown"]
15
+ spec.email = "support@easypost.com"
16
+ spec.homepage = "https://www.easypost.com/docs"
15
17
 
16
- spec.files = `git ls-files -z`.split("\x0")
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ['lib']
20
- spec.required_ruby_version = '~> 2.0'
18
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
+ f.match(%r{^(test|spec|features)/})
20
+ end
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
+ spec.require_paths = ["lib"]
24
+ spec.required_ruby_version = "~> 2.2"
21
25
 
22
- spec.add_dependency 'rest-client', '>= 1.7'
23
- spec.add_dependency 'multi_json', '>= 1.3.0'
24
- spec.add_development_dependency 'bundler', '~> 1.7'
25
- spec.add_development_dependency 'rake', '~> 10.0'
26
- spec.add_development_dependency 'rspec', '~> 2.13'
26
+ spec.add_development_dependency "pry", "~> 0.13"
27
+ spec.add_development_dependency "rake", "~> 13.0"
28
+ spec.add_development_dependency "rspec", "~> 3.9"
29
+ spec.add_development_dependency "webmock", "~> 3.8"
30
+ spec.add_development_dependency "vcr", "~> 5.1"
27
31
  end
@@ -1,157 +1,147 @@
1
- require 'cgi'
2
- require 'set'
3
- require 'openssl'
4
- require 'rest_client'
5
- require 'multi_json'
1
+ require "base64"
2
+ require "cgi"
3
+ require "net/http"
6
4
 
7
5
  # Resources
8
- require 'easypost/version'
9
- require 'easypost/util'
10
- require 'easypost/object'
11
- require 'easypost/resource'
12
- require 'easypost/address'
13
- require 'easypost/parcel'
14
- require 'easypost/customs_item'
15
- require 'easypost/customs_info'
16
- require 'easypost/shipment'
17
- require 'easypost/rate'
18
- require 'easypost/postage_label'
19
- require 'easypost/scan_form'
20
- require 'easypost/refund'
21
- require 'easypost/insurance'
22
- require 'easypost/event'
23
- require 'easypost/batch'
24
- require 'easypost/tracker'
25
- require 'easypost/item'
26
- require 'easypost/order'
27
- require 'easypost/pickup'
28
- require 'easypost/pickup_rate'
29
- require 'easypost/printer'
30
- require 'easypost/print_job'
31
- require 'easypost/carrier_account'
32
- require 'easypost/user'
33
- require 'easypost/report'
34
- require 'easypost/webhook'
35
-
36
- require 'easypost/error'
6
+ require "easypost/version"
7
+ require "easypost/util"
8
+ require "easypost/object"
9
+ require "easypost/resource"
10
+ require "easypost/address"
11
+ require "easypost/parcel"
12
+ require "easypost/customs_item"
13
+ require "easypost/customs_info"
14
+ require "easypost/shipment"
15
+ require "easypost/rate"
16
+ require "easypost/postage_label"
17
+ require "easypost/scan_form"
18
+ require "easypost/refund"
19
+ require "easypost/insurance"
20
+ require "easypost/event"
21
+ require "easypost/batch"
22
+ require "easypost/tracker"
23
+ require "easypost/item"
24
+ require "easypost/order"
25
+ require "easypost/pickup"
26
+ require "easypost/pickup_rate"
27
+ require "easypost/printer"
28
+ require "easypost/print_job"
29
+ require "easypost/carrier_account"
30
+ require "easypost/user"
31
+ require "easypost/report"
32
+ require "easypost/webhook"
33
+
34
+ require "easypost/error"
37
35
 
38
36
  module EasyPost
39
- @@api_key = nil
40
- @@api_base = 'https://api.easypost.com/v2'
41
- @@api_version = nil
42
- @@open_timeout = 30
43
- @@timeout = 60
44
-
45
- def self.api_url(url='')
46
- @@api_base + url
47
- end
37
+ @api_key = nil
38
+ @api_base = "https://api.easypost.com"
48
39
 
49
40
  def self.api_key=(api_key)
50
- @@api_key = api_key
41
+ @api_key = api_key
51
42
  end
52
43
 
53
44
  def self.api_key
54
- @@api_key
45
+ @api_key
55
46
  end
56
47
 
57
48
  def self.api_base=(api_base)
58
- @@api_base = api_base
49
+ @api_base = api_base
59
50
  end
60
51
 
61
52
  def self.api_base
62
- @@api_base
63
- end
64
-
65
- def self.api_version=(version)
66
- @@api_version = version
53
+ @api_base
67
54
  end
68
55
 
69
- def self.api_version
70
- @@api_version
71
- end
72
-
73
- def self.http_config
74
- @@http_config ||= {
56
+ def self.reset_http_config
57
+ @http_config = {
75
58
  timeout: 60,
76
59
  open_timeout: 30,
77
60
  verify_ssl: OpenSSL::SSL::VERIFY_PEER,
78
- ssl_version: :TLSv1_2,
79
61
  }
62
+
63
+ ruby_version = Gem::Version.new(RUBY_VERSION)
64
+ if ruby_version >= Gem::Version.new("2.5.0")
65
+ @http_config[:min_version] = OpenSSL::SSL::TLS1_2_VERSION
66
+ else
67
+ @http_config[:ssl_version] = :TLSv1_2
68
+ end
69
+
70
+ @http_config
71
+ end
72
+
73
+ def self.http_config
74
+ @http_config ||= reset_http_config
80
75
  end
81
76
 
82
77
  def self.http_config=(http_config_params)
83
- self.http_config.merge!(http_config_params)
78
+ http_config.merge!(http_config_params)
84
79
  end
85
80
 
86
- def self.request(method, url, api_key, params={}, headers={}, api_key_required=true)
87
- api_key ||= @@api_key
88
- if api_key_required
89
- raise Error.new('No API key provided.') unless api_key
90
- end
81
+ def self.make_client(uri)
82
+ client = if http_config[:proxy]
83
+ proxy_uri = URI(http_config[:proxy])
84
+ Net::HTTP.new(
85
+ uri.host,
86
+ uri.port,
87
+ proxy_uri.host,
88
+ proxy_uri.port,
89
+ proxy_uri.user,
90
+ proxy_uri.password
91
+ )
92
+ else
93
+ Net::HTTP.new(uri.host, uri.port)
94
+ end
95
+ client.use_ssl = true
96
+
97
+ http_config.each do |name, value|
98
+ # Discrepancies between RestClient and Net::HTTP.
99
+ if name == :verify_ssl
100
+ name = :verify_mode
101
+ elsif name == :timeout
102
+ name = :read_timeout
103
+ end
91
104
 
92
- params = Util.objects_to_ids(params)
93
- url = self.api_url(url)
94
- case method.to_s.downcase.to_sym
95
- when :get, :head, :delete
96
- # Make params into GET parameters
97
- if params && params.count > 0
98
- query_string = Util.flatten_params(params).collect{|key, value| "#{key}=#{Util.url_encode(value)}"}.join('&')
99
- url += "#{URI.parse(url).query ? '&' : '?'}#{query_string}"
105
+ # Handled in the creation of the client.
106
+ if name == :proxy
107
+ next
100
108
  end
101
- payload = nil
102
- else
103
- payload = Util.flatten_params(params).collect{|(key, value)| "#{key}=#{Util.url_encode(value)}"}.join('&')
109
+
110
+ client.send("#{name}=", value)
104
111
  end
105
112
 
106
- headers = {
107
- :user_agent => "EasyPost/v2 RubyClient/#{VERSION}",
108
- :authorization => "Bearer #{api_key}",
109
- :content_type => 'application/x-www-form-urlencoded'
110
- }.merge(headers)
111
-
112
- opts = http_config.merge(
113
- {
114
- :method => method,
115
- :url => url,
116
- :headers => headers,
117
- :payload => payload
118
- }
119
- )
113
+ client
114
+ end
120
115
 
121
- begin
122
- response = execute_request(opts)
123
- rescue RestClient::ExceptionWithResponse => e
124
- if response_code = e.http_code and response_body = e.http_body
125
- begin
126
- response_json = MultiJson.load(response_body, :symbolize_keys => true)
127
- rescue MultiJson::DecodeError
128
- raise Error.new("Invalid response from API, unable to decode.", response_code, response_body)
129
- end
130
- begin
131
- raise NoMethodError if response_json[:error][:message] == nil
132
- raise Error.new(response_json[:error][:message], response_code, response_body, response_json)
133
- rescue NoMethodError, TypeError
134
- raise Error.new(response_json[:error], response_code, response_body, response_json)
135
- end
136
- else
137
- raise Error.new(e.message)
138
- end
139
- rescue RestClient::Exception, Errno::ECONNREFUSED => e
140
- raise Error.new(e.message)
116
+ def self.make_request(method, path, api_key=nil, body=nil)
117
+ client = make_client(URI(@api_base))
118
+
119
+ request = Net::HTTP.const_get(method.capitalize).new(path)
120
+ if body
121
+ request.body = JSON.dump(Util.objects_to_ids(body))
141
122
  end
142
123
 
143
- begin
144
- response_json = MultiJson.load(response.body, :symbolize_keys => true)
145
- rescue MultiJson::DecodeError
146
- raise Error.new("Invalid response object from API, unable to decode.", response.code, response.body)
124
+ request["Content-Type"] = "application/json"
125
+ request["User-Agent"] = "EasyPost/v2 RubyClient/#{VERSION} Ruby/#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"
126
+ if api_key = api_key || @api_key
127
+ request["Authorization"] = "Basic #{Base64.strict_encode64("#{api_key}:")}"
147
128
  end
148
129
 
149
- return [response_json, api_key]
150
- end
130
+ response = client.request(request)
151
131
 
152
- private
132
+ if (400..599).include? response.code.to_i
133
+ error = JSON.parse(response.body)["error"]
134
+ raise Error.new(error["message"], response.code.to_i, error["code"], error["errors"])
135
+ end
153
136
 
154
- def self.execute_request(opts)
155
- RestClient::Request.execute(opts)
137
+ if response["Content-Type"].include? "application/json"
138
+ JSON.parse(response.body)
139
+ else
140
+ response.body
141
+ end
142
+ rescue JSON::ParserError
143
+ raise RuntimeError.new(
144
+ "Invalid response object from API, unable to decode.\n#{response.body}"
145
+ )
156
146
  end
157
147
  end
@@ -18,7 +18,7 @@ module EasyPost
18
18
  end
19
19
  end
20
20
 
21
- response, api_key = EasyPost.request(:post, url, api_key, {address: params})
21
+ response = EasyPost.make_request(:post, url, api_key, {address: params})
22
22
  return Util.convert_to_easypost_object(response, api_key)
23
23
  end
24
24
 
@@ -26,7 +26,7 @@ module EasyPost
26
26
  wrapped_params = {}
27
27
  wrapped_params[self.class_name().to_sym] = params
28
28
  wrapped_params[:carrier] = carrier
29
- response, api_key = EasyPost.request(:post, url + '/create_and_verify', api_key, wrapped_params)
29
+ response = EasyPost.make_request(:post, url + '/create_and_verify', api_key, wrapped_params)
30
30
 
31
31
  if response.has_key?(:address)
32
32
  if response.has_key?(:message)
@@ -41,13 +41,13 @@ module EasyPost
41
41
 
42
42
  def verify(params={}, carrier=nil)
43
43
  begin
44
- response, api_key = EasyPost.request(:get, url + '/verify?carrier=' + String(carrier), @api_key, params)
44
+ response = EasyPost.make_request(:get, url + '/verify?carrier=' + String(carrier), @api_key, params)
45
45
  rescue
46
46
  raise Error.new("Unable to verify address.")
47
47
  end
48
48
 
49
- if response.has_key?(:address)
50
- return EasyPost::Util::convert_to_easypost_object(response[:address], api_key)
49
+ if response.has_key?("address")
50
+ return EasyPost::Util::convert_to_easypost_object(response["address"], api_key)
51
51
  else
52
52
  raise Error.new("Unable to verify address.")
53
53
  end
@@ -4,47 +4,47 @@ module EasyPost
4
4
  def self.create_and_buy(params={}, api_key=nil)
5
5
  wrapped_params = {}
6
6
  wrapped_params[self.class_name().to_sym] = params
7
- response, api_key = EasyPost.request(:post, url + '/create_and_buy', api_key, wrapped_params)
7
+ response = EasyPost.make_request(:post, url + '/create_and_buy', api_key, wrapped_params)
8
8
 
9
9
  return Util.convert_to_easypost_object(response, api_key)
10
10
  end
11
11
 
12
12
  def buy(params={})
13
- response, api_key = EasyPost.request(:post, url + '/buy', @api_key, params)
13
+ response = EasyPost.make_request(:post, url + '/buy', @api_key, params)
14
14
  self.refresh_from(response, @api_key, true)
15
15
 
16
16
  return self
17
17
  end
18
18
 
19
19
  def label(params={})
20
- response, api_key = EasyPost.request(:post, url + '/label', @api_key, params)
20
+ response = EasyPost.make_request(:post, url + '/label', @api_key, params)
21
21
  self.refresh_from(response, @api_key, true)
22
22
 
23
23
  return self
24
24
  end
25
25
 
26
26
  def remove_shipments(params={})
27
- response, api_key = EasyPost.request(:post, url + '/remove_shipments', @api_key, params)
27
+ response = EasyPost.make_request(:post, url + '/remove_shipments', @api_key, params)
28
28
  self.refresh_from(response, @api_key, true)
29
29
 
30
30
  return self
31
31
  end
32
32
 
33
33
  def add_shipments(params={})
34
- response, api_key = EasyPost.request(:post, url + '/add_shipments', @api_key, params)
34
+ response = EasyPost.make_request(:post, url + '/add_shipments', @api_key, params)
35
35
  self.refresh_from(response, @api_key, true)
36
36
 
37
37
  return self
38
38
  end
39
39
 
40
40
  def stamp_and_barcode_by_reference(params={})
41
- response, api_key = EasyPost.request(:get, url + '/stamp_and_barcode_by_reference', @api_key, params)
41
+ response = EasyPost.make_request(:get, url + '/stamp_and_barcode_by_reference', @api_key, params)
42
42
 
43
43
  return response
44
44
  end
45
45
 
46
46
  def create_scan_form(params={})
47
- response, api_key = EasyPost.request(:post, url + '/scan_form', @api_key, params)
47
+ response = EasyPost.make_request(:post, url + '/scan_form', @api_key, params)
48
48
 
49
49
  return response
50
50
  end