easypost 4.13.0 → 5.0.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 +4 -4
- data/.github/workflows/ci.yml +22 -1
- data/.gitignore +9 -11
- data/.rubocop.yml +6 -1
- data/CHANGELOG.md +21 -0
- data/Makefile +1 -1
- data/README.md +45 -38
- data/UPGRADE_GUIDE.md +119 -0
- data/VERSION +1 -1
- data/easycop.yml +3 -3
- 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 +62 -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 +15 -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 -64
- 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 -32
- 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,62 @@
|
|
|
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, use_ssl: true, read_timeout: read_timeout, open_timeout: open_timeout,
|
|
47
|
+
) do |http|
|
|
48
|
+
http.request(request)
|
|
49
|
+
end
|
|
50
|
+
rescue Net::ReadTimeout, Net::OpenTimeout, Errno::EHOSTUNREACH => e
|
|
51
|
+
# Raise a timeout error if the request times out.
|
|
52
|
+
raise EasyPost::Errors::TimeoutError.new(e.message)
|
|
53
|
+
rescue OpenSSL::SSL::SSLError => e
|
|
54
|
+
# Raise an SSL error if the request fails due to an SSL error.
|
|
55
|
+
raise EasyPost::Errors::SslError.new(e.message)
|
|
56
|
+
rescue StandardError => e
|
|
57
|
+
# Raise an unknown HTTP error if anything else causes the request to fail to complete
|
|
58
|
+
# (this is different from processing 4xx/5xx errors from the API)
|
|
59
|
+
raise EasyPost::Errors::UnknownApiError.new(e.message)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
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
|