easypost 4.13.1 → 5.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +24 -1
- data/.gitignore +11 -11
- data/CHANGELOG.md +23 -2
- data/Makefile +15 -10
- data/README.md +49 -39
- data/UPGRADE_GUIDE.md +119 -0
- data/VERSION +1 -1
- data/easypost.gemspec +12 -10
- data/lib/easypost/client.rb +129 -0
- data/lib/easypost/connection.rb +2 -4
- data/lib/easypost/constants.rb +15 -0
- data/lib/easypost/errors/api/api_error.rb +106 -0
- data/lib/easypost/errors/api/connection_error.rb +6 -0
- data/lib/easypost/errors/api/external_api_error.rb +18 -0
- data/lib/easypost/errors/api/forbidden_error.rb +6 -0
- data/lib/easypost/errors/api/gateway_timeout_error.rb +6 -0
- data/lib/easypost/errors/api/internal_server_error.rb +6 -0
- data/lib/easypost/errors/api/invalid_request_error.rb +6 -0
- data/lib/easypost/errors/api/method_not_allowed_error.rb +6 -0
- data/lib/easypost/errors/api/not_found_error.rb +6 -0
- data/lib/easypost/errors/api/payment_error.rb +6 -0
- data/lib/easypost/errors/api/proxy_error.rb +6 -0
- data/lib/easypost/errors/api/rate_limit_error.rb +6 -0
- data/lib/easypost/errors/api/redirect_error.rb +6 -0
- data/lib/easypost/errors/api/retry_error.rb +6 -0
- data/lib/easypost/errors/api/service_unavailable_error.rb +6 -0
- data/lib/easypost/errors/api/ssl_error.rb +6 -0
- data/lib/easypost/errors/api/timeout_error.rb +6 -0
- data/lib/easypost/errors/api/unauthorized_error.rb +6 -0
- data/lib/easypost/errors/api/unknown_api_error.rb +6 -0
- data/lib/easypost/errors/easy_post_error.rb +7 -0
- data/lib/easypost/errors/end_of_pagination_error.rb +7 -0
- data/lib/easypost/errors/filtering_error.rb +4 -0
- data/lib/easypost/errors/invalid_object_error.rb +4 -0
- data/lib/easypost/errors/invalid_parameter_error.rb +11 -0
- data/lib/easypost/errors/missing_parameter_error.rb +9 -0
- data/lib/easypost/errors/signature_verification_error.rb +4 -0
- data/lib/easypost/errors.rb +31 -0
- data/lib/easypost/http_client.rb +65 -0
- data/lib/easypost/internal_utilities.rb +66 -0
- data/lib/easypost/models/address.rb +5 -0
- data/lib/easypost/models/api_key.rb +5 -0
- data/lib/easypost/models/base.rb +58 -0
- data/lib/easypost/models/batch.rb +5 -0
- data/lib/easypost/models/brand.rb +5 -0
- data/lib/easypost/{carbon_offset.rb → models/carbon_offset.rb} +1 -1
- data/lib/easypost/models/carrier_account.rb +5 -0
- data/lib/easypost/models/customs_info.rb +5 -0
- data/lib/easypost/models/customs_item.rb +5 -0
- data/lib/easypost/models/end_shipper.rb +5 -0
- data/lib/easypost/models/error.rb +21 -0
- data/lib/easypost/models/event.rb +5 -0
- data/lib/easypost/models/insurance.rb +6 -0
- data/lib/easypost/models/order.rb +9 -0
- data/lib/easypost/models/parcel.rb +5 -0
- data/lib/easypost/{payload.rb → models/payload.rb} +1 -1
- data/lib/easypost/models/payment_method.rb +5 -0
- data/lib/easypost/models/pickup.rb +9 -0
- data/lib/easypost/{pickup_rate.rb → models/pickup_rate.rb} +1 -1
- data/lib/easypost/{postage_label.rb → models/postage_label.rb} +1 -1
- data/lib/easypost/models/rate.rb +5 -0
- data/lib/easypost/models/referral.rb +5 -0
- data/lib/easypost/models/refund.rb +5 -0
- data/lib/easypost/models/report.rb +5 -0
- data/lib/easypost/models/scan_form.rb +6 -0
- data/lib/easypost/models/shipment.rb +10 -0
- data/lib/easypost/{tax_identifier.rb → models/tax_identifier.rb} +1 -1
- data/lib/easypost/models/tracker.rb +5 -0
- data/lib/easypost/models/user.rb +5 -0
- data/lib/easypost/models/webhook.rb +6 -0
- data/lib/easypost/models.rb +35 -0
- data/lib/easypost/services/address.rb +50 -0
- data/lib/easypost/services/api_key.rb +8 -0
- data/lib/easypost/services/base.rb +27 -0
- data/lib/easypost/services/batch.rb +53 -0
- data/lib/easypost/services/beta_rate.rb +12 -0
- data/lib/easypost/services/beta_referral_customer.rb +40 -0
- data/lib/easypost/services/billing.rb +75 -0
- data/lib/easypost/services/carrier_account.rb +44 -0
- data/lib/easypost/services/carrier_metadata.rb +22 -0
- data/lib/easypost/services/customs_info.rb +17 -0
- data/lib/easypost/services/customs_item.rb +15 -0
- data/lib/easypost/services/end_shipper.rb +31 -0
- data/lib/easypost/services/event.rb +32 -0
- data/lib/easypost/services/insurance.rb +26 -0
- data/lib/easypost/services/order.rb +30 -0
- data/lib/easypost/services/parcel.rb +16 -0
- data/lib/easypost/services/pickup.rb +40 -0
- data/lib/easypost/services/rate.rb +8 -0
- data/lib/easypost/services/referral_customer.rb +103 -0
- data/lib/easypost/services/refund.rb +26 -0
- data/lib/easypost/services/report.rb +42 -0
- data/lib/easypost/services/scan_form.rb +25 -0
- data/lib/easypost/services/shipment.rb +106 -0
- data/lib/easypost/services/tracker.rb +38 -0
- data/lib/easypost/services/user.rb +66 -0
- data/lib/easypost/services/webhook.rb +34 -0
- data/lib/easypost/services.rb +32 -0
- data/lib/easypost/util.rb +80 -187
- data/lib/easypost/utilities/constants.rb +5 -0
- data/lib/easypost/utilities/json.rb +23 -0
- data/lib/easypost/utilities/static_mapper.rb +73 -0
- data/lib/easypost/utilities/system.rb +36 -0
- data/lib/easypost.rb +12 -138
- metadata +147 -66
- data/.rubocop.yml +0 -11
- data/easycop.yml +0 -180
- data/lib/easypost/address.rb +0 -55
- data/lib/easypost/api_key.rb +0 -5
- data/lib/easypost/batch.rb +0 -52
- data/lib/easypost/beta/end_shipper.rb +0 -44
- data/lib/easypost/beta/payment_refund.rb +0 -5
- data/lib/easypost/beta/rate.rb +0 -14
- data/lib/easypost/beta/referral.rb +0 -158
- data/lib/easypost/beta.rb +0 -8
- data/lib/easypost/billing.rb +0 -72
- data/lib/easypost/brand.rb +0 -13
- data/lib/easypost/carrier_account.rb +0 -26
- data/lib/easypost/carrier_type.rb +0 -5
- data/lib/easypost/customs_info.rb +0 -9
- data/lib/easypost/customs_item.rb +0 -9
- data/lib/easypost/end_shipper.rb +0 -26
- data/lib/easypost/error.rb +0 -46
- data/lib/easypost/event.rb +0 -38
- data/lib/easypost/insurance.rb +0 -20
- data/lib/easypost/object.rb +0 -171
- data/lib/easypost/order.rb +0 -37
- data/lib/easypost/parcel.rb +0 -9
- data/lib/easypost/payment_method.rb +0 -12
- data/lib/easypost/pickup.rb +0 -47
- data/lib/easypost/rate.rb +0 -9
- data/lib/easypost/referral.rb +0 -117
- data/lib/easypost/refund.rb +0 -19
- data/lib/easypost/report.rb +0 -44
- data/lib/easypost/resource.rb +0 -124
- data/lib/easypost/scan_form.rb +0 -26
- data/lib/easypost/shipment.rb +0 -186
- data/lib/easypost/tracker.rb +0 -43
- data/lib/easypost/user.rb +0 -74
- data/lib/easypost/webhook.rb +0 -57
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../easy_post_error'
|
4
|
+
require 'easypost/constants'
|
5
|
+
|
6
|
+
class EasyPost::Errors::ApiError < EasyPost::Errors::EasyPostError
|
7
|
+
attr_reader :status_code, :code, :errors
|
8
|
+
|
9
|
+
def initialize(message, status_code = nil, error_code = nil, sub_errors = nil)
|
10
|
+
super message
|
11
|
+
@status_code = status_code
|
12
|
+
@code = error_code
|
13
|
+
@errors = sub_errors
|
14
|
+
end
|
15
|
+
|
16
|
+
def pretty_print
|
17
|
+
error_string = "#{code} (#{status_code}): #{message}"
|
18
|
+
errors&.each do |error|
|
19
|
+
error_string += "\nField: #{error.field}\nMessage: #{error.message}"
|
20
|
+
end
|
21
|
+
error_string
|
22
|
+
end
|
23
|
+
|
24
|
+
# Recursively traverses a JSON element to extract error messages and returns them as a comma-separated string.
|
25
|
+
def self.collect_error_messages(error_message, messages_list)
|
26
|
+
case error_message
|
27
|
+
when Hash
|
28
|
+
error_message.each_value { |value| collect_error_messages(value, messages_list) }
|
29
|
+
when Array
|
30
|
+
error_message.each { |value| collect_error_messages(value, messages_list) }
|
31
|
+
else
|
32
|
+
messages_list.push(error_message.to_s)
|
33
|
+
end
|
34
|
+
|
35
|
+
messages_list.join(', ')
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.handle_api_error(response)
|
39
|
+
status_code = response.code
|
40
|
+
status_code = status_code.to_i if status_code.is_a?(String)
|
41
|
+
|
42
|
+
if status_code >= 200 && status_code <= 299
|
43
|
+
return nil
|
44
|
+
end
|
45
|
+
|
46
|
+
# Try to parse the response body as JSON
|
47
|
+
begin
|
48
|
+
error_data = JSON.parse(response.body)['error']
|
49
|
+
|
50
|
+
error_message = error_data['message']
|
51
|
+
error_type = error_data['code']
|
52
|
+
errors = error_data['errors']&.map do |error|
|
53
|
+
EasyPost::Models::Error.from_api_error_response(error)
|
54
|
+
end
|
55
|
+
rescue StandardError
|
56
|
+
error_message = response.code.to_s
|
57
|
+
error_type = EasyPost::Constants::API_ERROR_DETAILS_PARSING_ERROR
|
58
|
+
errors = nil
|
59
|
+
end
|
60
|
+
|
61
|
+
cls = exception_cls_from_status_code(status_code)
|
62
|
+
|
63
|
+
if cls == EasyPost::Errors::UnknownApiError
|
64
|
+
return EasyPost::Errors::UnknownApiError.new(
|
65
|
+
EasyPost::Constants::UNEXPECTED_HTTP_STATUS_CODE % status_code,
|
66
|
+
status_code,
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Return (don't throw here) an instance of the appropriate error class
|
71
|
+
cls.new(error_message, status_code, error_type, errors)
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.exception_cls_from_status_code(status_code)
|
75
|
+
case status_code
|
76
|
+
when 0
|
77
|
+
EasyPost::Errors::ConnectionError
|
78
|
+
when 300, 301, 302, 303, 304, 305, 306, 307, 308
|
79
|
+
EasyPost::Errors::RedirectError
|
80
|
+
when 401
|
81
|
+
EasyPost::Errors::UnauthorizedError
|
82
|
+
when 402
|
83
|
+
EasyPost::Errors::PaymentError
|
84
|
+
when 403
|
85
|
+
EasyPost::Errors::ForbiddenError
|
86
|
+
when 404
|
87
|
+
EasyPost::Errors::NotFoundError
|
88
|
+
when 405
|
89
|
+
EasyPost::Errors::MethodNotAllowedError
|
90
|
+
when 408
|
91
|
+
EasyPost::Errors::TimeoutError
|
92
|
+
when 422
|
93
|
+
EasyPost::Errors::InvalidRequestError
|
94
|
+
when 429
|
95
|
+
EasyPost::Errors::RateLimitError
|
96
|
+
when 500
|
97
|
+
EasyPost::Errors::InternalServerError
|
98
|
+
when 502, 504
|
99
|
+
EasyPost::Errors::GatewayTimeoutError
|
100
|
+
when 503
|
101
|
+
EasyPost::Errors::ServiceUnavailableError
|
102
|
+
else
|
103
|
+
EasyPost::Errors::UnknownApiError
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class EasyPost::Errors::ExternalApiError < EasyPost::Errors::EasyPostError
|
4
|
+
attr_reader :status_code
|
5
|
+
|
6
|
+
def initialize(message, status_code = nil)
|
7
|
+
super message
|
8
|
+
@status_code = status_code
|
9
|
+
end
|
10
|
+
|
11
|
+
def pretty_print
|
12
|
+
if status_code.nil?
|
13
|
+
return message
|
14
|
+
end
|
15
|
+
|
16
|
+
"(#{status_code}): #{message}"
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'easypost/constants'
|
4
|
+
|
5
|
+
class EasyPost::Errors::InvalidParameterError < EasyPost::Errors::EasyPostError
|
6
|
+
# @param [String] parameter The name of the parameter that was invalid.
|
7
|
+
# @param [String] suggestion Optional suggestion message for a valid parameter.
|
8
|
+
def initialize(parameter, suggestion = nil)
|
9
|
+
super EasyPost::Constants::INVALID_PARAMETER % parameter + (suggestion.nil? ? '' : " #{suggestion}")
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EasyPost::Errors
|
4
|
+
end
|
5
|
+
|
6
|
+
require_relative 'errors/easy_post_error'
|
7
|
+
require_relative 'errors/end_of_pagination_error'
|
8
|
+
require_relative 'errors/api/external_api_error'
|
9
|
+
require_relative 'errors/filtering_error'
|
10
|
+
require_relative 'errors/invalid_object_error'
|
11
|
+
require_relative 'errors/invalid_parameter_error'
|
12
|
+
require_relative 'errors/missing_parameter_error'
|
13
|
+
require_relative 'errors/signature_verification_error'
|
14
|
+
require_relative 'errors/api/api_error'
|
15
|
+
require_relative 'errors/api/connection_error'
|
16
|
+
require_relative 'errors/api/forbidden_error'
|
17
|
+
require_relative 'errors/api/gateway_timeout_error'
|
18
|
+
require_relative 'errors/api/internal_server_error'
|
19
|
+
require_relative 'errors/api/invalid_request_error'
|
20
|
+
require_relative 'errors/api/method_not_allowed_error'
|
21
|
+
require_relative 'errors/api/not_found_error'
|
22
|
+
require_relative 'errors/api/payment_error'
|
23
|
+
require_relative 'errors/api/proxy_error'
|
24
|
+
require_relative 'errors/api/rate_limit_error'
|
25
|
+
require_relative 'errors/api/redirect_error'
|
26
|
+
require_relative 'errors/api/retry_error'
|
27
|
+
require_relative 'errors/api/service_unavailable_error'
|
28
|
+
require_relative 'errors/api/ssl_error'
|
29
|
+
require_relative 'errors/api/timeout_error'
|
30
|
+
require_relative 'errors/api/unauthorized_error'
|
31
|
+
require_relative 'errors/api/unknown_api_error'
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class EasyPost::HttpClient
|
4
|
+
def initialize(base_url, config, custom_client_exec = nil)
|
5
|
+
@base_url = base_url
|
6
|
+
@config = config
|
7
|
+
@custom_client_exec = custom_client_exec
|
8
|
+
end
|
9
|
+
|
10
|
+
# Execute an HTTP request to the API.
|
11
|
+
def request(
|
12
|
+
method,
|
13
|
+
path,
|
14
|
+
headers = nil,
|
15
|
+
body = nil,
|
16
|
+
api_version = EasyPost::InternalUtilities::Constants::API_VERSION
|
17
|
+
)
|
18
|
+
# Remove leading slash from path.
|
19
|
+
path = path[1..] if path[0] == '/'
|
20
|
+
|
21
|
+
uri = URI.parse("#{@base_url}/#{api_version}/#{path}")
|
22
|
+
headers = @config[:headers].merge(headers || {})
|
23
|
+
body = JSON.dump(EasyPost::InternalUtilities.objects_to_ids(body)) if body
|
24
|
+
open_timeout = @config[:open_timeout]
|
25
|
+
read_timeout = @config[:read_timeout]
|
26
|
+
|
27
|
+
# Execute the request, return the response.
|
28
|
+
|
29
|
+
if @custom_client_exec
|
30
|
+
@custom_client_exec.call(method, uri, headers, open_timeout, read_timeout, body)
|
31
|
+
else
|
32
|
+
default_request_execute(method, uri, headers, open_timeout, read_timeout, body)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def default_request_execute(method, uri, headers, open_timeout, read_timeout, body = nil)
|
37
|
+
# Create the request, set the headers and body if necessary.
|
38
|
+
request = Net::HTTP.const_get(method.capitalize).new(uri)
|
39
|
+
headers.each { |k, v| request[k] = v }
|
40
|
+
request.body = body if body
|
41
|
+
|
42
|
+
begin
|
43
|
+
# Attempt to make the request and return the response.
|
44
|
+
Net::HTTP.start(
|
45
|
+
uri.host,
|
46
|
+
uri.port,
|
47
|
+
use_ssl: true,
|
48
|
+
read_timeout: read_timeout,
|
49
|
+
open_timeout: open_timeout,
|
50
|
+
) do |http|
|
51
|
+
http.request(request)
|
52
|
+
end
|
53
|
+
rescue Net::ReadTimeout, Net::OpenTimeout, Errno::EHOSTUNREACH => e
|
54
|
+
# Raise a timeout error if the request times out.
|
55
|
+
raise EasyPost::Errors::TimeoutError.new(e.message)
|
56
|
+
rescue OpenSSL::SSL::SSLError => e
|
57
|
+
# Raise an SSL error if the request fails due to an SSL error.
|
58
|
+
raise EasyPost::Errors::SslError.new(e.message)
|
59
|
+
rescue StandardError => e
|
60
|
+
# Raise an unknown HTTP error if anything else causes the request to fail to complete
|
61
|
+
# (this is different from processing 4xx/5xx errors from the API)
|
62
|
+
raise EasyPost::Errors::UnknownApiError.new(e.message)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EasyPost::InternalUtilities
|
4
|
+
# Convert a string to snake case
|
5
|
+
def self.to_snake_case(str)
|
6
|
+
str.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
7
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
8
|
+
.downcase
|
9
|
+
end
|
10
|
+
|
11
|
+
# Form-encode a multi-layer dictionary to a one-layer dictionary.
|
12
|
+
def self.form_encode_params(hash, parent_keys = [], parent_dict = {})
|
13
|
+
result = parent_dict or {}
|
14
|
+
keys = parent_keys or []
|
15
|
+
|
16
|
+
hash.each do |key, value|
|
17
|
+
if value.instance_of?(Hash)
|
18
|
+
keys << key
|
19
|
+
result = form_encode_params(value, keys, result)
|
20
|
+
else
|
21
|
+
dict_key = build_dict_key(keys + [key])
|
22
|
+
result[dict_key] = value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
result
|
26
|
+
end
|
27
|
+
|
28
|
+
# Build a dict key from a list of keys.
|
29
|
+
# Example: [code, number] -> code[number]
|
30
|
+
def self.build_dict_key(keys)
|
31
|
+
result = keys[0].to_s
|
32
|
+
|
33
|
+
keys[1..].each do |key|
|
34
|
+
result += "[#{key}]"
|
35
|
+
end
|
36
|
+
|
37
|
+
result
|
38
|
+
end
|
39
|
+
|
40
|
+
# Converts an object to an object ID.
|
41
|
+
def self.objects_to_ids(obj)
|
42
|
+
case obj
|
43
|
+
when EasyPost::Models::EasyPostObject
|
44
|
+
{ id: obj.id }
|
45
|
+
when Hash
|
46
|
+
result = {}
|
47
|
+
obj.each { |k, v| result[k] = objects_to_ids(v) unless v.nil? }
|
48
|
+
result
|
49
|
+
when Array
|
50
|
+
obj.map { |v| objects_to_ids(v) }
|
51
|
+
else
|
52
|
+
obj
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Normalizes a list of strings.
|
57
|
+
def self.normalize_string_list(lst)
|
58
|
+
lst = lst.is_a?(String) ? lst.split(',') : Array(lst)
|
59
|
+
lst.map(&:to_s).map(&:downcase).map(&:strip)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
require_relative 'utilities/json'
|
64
|
+
require_relative 'utilities/system'
|
65
|
+
require_relative 'utilities/static_mapper'
|
66
|
+
require_relative 'utilities/constants'
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
# The base class for all JSON objects in the library.
|
6
|
+
class EasyPost::Models::Object
|
7
|
+
def initialize(data)
|
8
|
+
@values = data
|
9
|
+
add_properties(data)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Convert to a string.
|
13
|
+
def to_s(*_args)
|
14
|
+
JSON.dump(@values)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Convert object to hash
|
18
|
+
def to_hash
|
19
|
+
JSON.parse(JSON.dump(@values))
|
20
|
+
end
|
21
|
+
|
22
|
+
# Get element of an array.
|
23
|
+
def [](key)
|
24
|
+
@values[key.to_s]
|
25
|
+
end
|
26
|
+
|
27
|
+
# Set the element of an array.
|
28
|
+
def []=(key, value)
|
29
|
+
send(:"#{key}=", value)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def add_properties(values)
|
35
|
+
values.each do |key, _|
|
36
|
+
define_singleton_method(key) { handle_value(@values[key]) } # getter
|
37
|
+
define_singleton_method("#{key}=") { |v| @values[key] = handle_value(v) } # setter
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def handle_value(val)
|
42
|
+
case val
|
43
|
+
when Hash
|
44
|
+
type = EasyPost::InternalUtilities::StaticMapper::BY_TYPE[val['object']] if val['object']
|
45
|
+
prefix = EasyPost::InternalUtilities::StaticMapper::BY_PREFIX[val['id'].split('_').first] if val['id']
|
46
|
+
cls = type || prefix || EasyPost::Models::EasyPostObject
|
47
|
+
cls.new(val)
|
48
|
+
when Array
|
49
|
+
val.map { |item| handle_value(item) }
|
50
|
+
else
|
51
|
+
val
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# The base class for all API objects in the library that have an ID (plus optional timestamps).
|
57
|
+
class EasyPost::Models::EasyPostObject < EasyPost::Models::Object
|
58
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# The CarbonOffset object is a summary of carbon offset data for a given rate, including grams, price and currency
|
4
|
-
class EasyPost::CarbonOffset < EasyPost::
|
4
|
+
class EasyPost::Models::CarbonOffset < EasyPost::Models::EasyPostObject
|
5
5
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# EasyPost Error object.
|
4
|
+
class EasyPost::Models::Error
|
5
|
+
attr_reader :code, :field, :message
|
6
|
+
|
7
|
+
# Initialize a new EasyPost Error
|
8
|
+
def initialize(code, field = nil, message = nil)
|
9
|
+
@code = code
|
10
|
+
@field = field
|
11
|
+
@message = message
|
12
|
+
end
|
13
|
+
|
14
|
+
# Create an EasyPost Error from an API error response.
|
15
|
+
def self.from_api_error_response(data)
|
16
|
+
code = data['code']
|
17
|
+
field = data['field'] || nil
|
18
|
+
message = data['message'] || nil
|
19
|
+
EasyPost::Models::Error.new(code, field, message)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# An Insurance object represents insurance for packages purchased both via the EasyPost API as well
|
4
|
+
# as shipments purchased through third parties and later registered with EasyPost.
|
5
|
+
class EasyPost::Models::Insurance < EasyPost::Models::EasyPostObject
|
6
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# The Order object represents a collection of packages and can be used for Multi-Piece Shipments.
|
4
|
+
class EasyPost::Models::Order < EasyPost::Models::EasyPostObject
|
5
|
+
# Get the lowest rate of an Order (can exclude by having `'!'` as the first element of your optional filter lists).
|
6
|
+
def lowest_rate(carriers = [], services = [])
|
7
|
+
EasyPost::Util.get_lowest_object_rate(self, carriers, services)
|
8
|
+
end
|
9
|
+
end
|