easypost 2.7.1 → 3.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8c4cdf8c957478f42068e095c2c3a84f6ec141c4
4
- data.tar.gz: a44a1d79a8e7c2343038f95e0cc933298e03f837
3
+ metadata.gz: c78ad14a13a665a9397b5d2ade56cdad38a669f0
4
+ data.tar.gz: e73234c20adee8cfcbc37f2b93fb1c5aa2a6843d
5
5
  SHA512:
6
- metadata.gz: eb9664b47721a6f14be45a0d7042875990e3454d7c21cde4be66d104dc7e9b8358be8ddf9106b1212086aa4cdc80d4a3bc1c32a9a2ca339edf2685112a322e52
7
- data.tar.gz: a7956f59bd5ba39691e597486fc5fbad1aa2d90d3357cc63d5f3373177f2ba34fbb3d60f9aaa0f28b5e82d6187df2f5eec5747bb97c83cb0c3130e3b0f188565
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,42 @@
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
+
19
+ === 3.0.1 2018-05-17
20
+
21
+ * Enforce TLS certificate validity by default
22
+
23
+ === 3.0.0 2018-02-09
24
+
25
+ * Require use of ruby ~> 2.0 and TLSv1.2
26
+
27
+
28
+ === 2.7.3 2017-05-25
29
+
30
+ * Fix bug with introduced around certain JSON objects with IDs (thanks vladvinnikov!)
31
+
32
+
33
+ === 2.7.2 2018-01-31
34
+
35
+ * Removed unused and unsupported code paths for Container model
36
+ * Removed unused and unsupported code path for Stamp and Barcode methods on the Shipment model
37
+ * Fixed a bug with non-model JSON object with an "id" key being treated as models and raising errors
38
+
39
+
1
40
  === 2.7.1 2017-05-25
2
41
 
3
42
  * Allow reports to be retrieved without passing a type
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
- 2.7.1
1
+ 3.1.3
@@ -1,26 +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']
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"
20
25
 
21
- spec.add_dependency 'rest-client', '>= 1.4'
22
- spec.add_dependency 'multi_json', '>= 1.3.0'
23
- spec.add_development_dependency 'bundler', '~> 1.7'
24
- spec.add_development_dependency 'rake', '~> 10.0'
25
- 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"
26
31
  end
@@ -1,158 +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/container'
27
- require 'easypost/order'
28
- require 'easypost/pickup'
29
- require 'easypost/pickup_rate'
30
- require 'easypost/printer'
31
- require 'easypost/print_job'
32
- require 'easypost/carrier_account'
33
- require 'easypost/user'
34
- require 'easypost/report'
35
- require 'easypost/webhook'
36
-
37
- 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"
38
35
 
39
36
  module EasyPost
40
- @@api_key = nil
41
- @@api_base = 'https://api.easypost.com/v2'
42
- @@api_version = nil
43
- @@open_timeout = 30
44
- @@timeout = 60
45
-
46
- def self.api_url(url='')
47
- @@api_base + url
48
- end
37
+ @api_key = nil
38
+ @api_base = "https://api.easypost.com"
49
39
 
50
40
  def self.api_key=(api_key)
51
- @@api_key = api_key
41
+ @api_key = api_key
52
42
  end
53
43
 
54
44
  def self.api_key
55
- @@api_key
45
+ @api_key
56
46
  end
57
47
 
58
48
  def self.api_base=(api_base)
59
- @@api_base = api_base
49
+ @api_base = api_base
60
50
  end
61
51
 
62
52
  def self.api_base
63
- @@api_base
53
+ @api_base
64
54
  end
65
55
 
66
- def self.api_version=(version)
67
- @@api_version = version
68
- end
56
+ def self.reset_http_config
57
+ @http_config = {
58
+ timeout: 60,
59
+ open_timeout: 30,
60
+ verify_ssl: OpenSSL::SSL::VERIFY_PEER,
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
69
 
70
- def self.api_version
71
- @@api_version
70
+ @http_config
72
71
  end
73
72
 
74
73
  def self.http_config
75
- @@http_config ||= {
76
- timeout: 60,
77
- open_timeout: 30,
78
- verify_ssl: false,
79
- ssl_version: "TLSv1",
80
- }
74
+ @http_config ||= reset_http_config
81
75
  end
82
76
 
83
77
  def self.http_config=(http_config_params)
84
- self.http_config.merge!(http_config_params)
78
+ http_config.merge!(http_config_params)
85
79
  end
86
80
 
87
- def self.request(method, url, api_key, params={}, headers={}, api_key_required=true)
88
- api_key ||= @@api_key
89
- if api_key_required
90
- raise Error.new('No API key provided.') unless api_key
91
- 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
92
104
 
93
- params = Util.objects_to_ids(params)
94
- url = self.api_url(url)
95
- case method.to_s.downcase.to_sym
96
- when :get, :head, :delete
97
- # Make params into GET parameters
98
- if params && params.count > 0
99
- query_string = Util.flatten_params(params).collect{|key, value| "#{key}=#{Util.url_encode(value)}"}.join('&')
100
- url += "#{URI.parse(url).query ? '&' : '?'}#{query_string}"
105
+ # Handled in the creation of the client.
106
+ if name == :proxy
107
+ next
101
108
  end
102
- payload = nil
103
- else
104
- payload = Util.flatten_params(params).collect{|(key, value)| "#{key}=#{Util.url_encode(value)}"}.join('&')
109
+
110
+ client.send("#{name}=", value)
105
111
  end
106
112
 
107
- headers = {
108
- :user_agent => "EasyPost/v2 RubyClient/#{VERSION}",
109
- :authorization => "Bearer #{api_key}",
110
- :content_type => 'application/x-www-form-urlencoded'
111
- }.merge(headers)
112
-
113
- opts = http_config.merge(
114
- {
115
- :method => method,
116
- :url => url,
117
- :headers => headers,
118
- :payload => payload
119
- }
120
- )
113
+ client
114
+ end
121
115
 
122
- begin
123
- response = execute_request(opts)
124
- rescue RestClient::ExceptionWithResponse => e
125
- if response_code = e.http_code and response_body = e.http_body
126
- begin
127
- response_json = MultiJson.load(response_body, :symbolize_keys => true)
128
- rescue MultiJson::DecodeError
129
- raise Error.new("Invalid response from API, unable to decode.", response_code, response_body)
130
- end
131
- begin
132
- raise NoMethodError if response_json[:error][:message] == nil
133
- raise Error.new(response_json[:error][:message], response_code, response_body, response_json)
134
- rescue NoMethodError, TypeError
135
- raise Error.new(response_json[:error], response_code, response_body, response_json)
136
- end
137
- else
138
- raise Error.new(e.message)
139
- end
140
- rescue RestClient::Exception, Errno::ECONNREFUSED => e
141
- 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))
142
122
  end
143
123
 
144
- begin
145
- response_json = MultiJson.load(response.body, :symbolize_keys => true)
146
- rescue MultiJson::DecodeError
147
- 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}:")}"
148
128
  end
149
129
 
150
- return [response_json, api_key]
151
- end
130
+ response = client.request(request)
152
131
 
153
- 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
154
136
 
155
- def self.execute_request(opts)
156
- 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
+ )
157
146
  end
158
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