easypost 5.0.1 → 5.1.1
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 +0 -2
- data/.gitignore +12 -1
- data/CHANGELOG.md +9 -0
- data/Makefile +18 -12
- data/README.md +48 -6
- data/VERSION +1 -1
- data/lib/easypost/client.rb +49 -0
- data/lib/easypost/errors/api/api_error.rb +2 -0
- data/lib/easypost/errors/api/bad_request_error.rb +6 -0
- data/lib/easypost/errors.rb +1 -0
- data/lib/easypost/hooks/request_context.rb +16 -0
- data/lib/easypost/hooks/response_context.rb +23 -0
- data/lib/easypost/hooks.rb +34 -0
- data/lib/easypost/http_client.rb +57 -5
- data/lib/easypost/services/carrier_account.rb +1 -1
- data/lib/easypost.rb +3 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 05dcc6dfaedaea7f8e6bbe28ab7bf510db31211cf664fcef76b42736929eeda6
|
4
|
+
data.tar.gz: 4c70e841f3fc6c6542928cfed6bbb848f53200e80a77157cabcfd42438a72d3c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85306184880d3bd91c1232c7e5a360f21755de6889f075aa0155b91b1a8601abda4951ff4f9ac4f879a7159da805b40093e1f2625274606773b4feb868ec2f0b
|
7
|
+
data.tar.gz: 88d77f2ec9743baaecdeba5556ff95161aa1817384043132bfb8a1334bb03adab3699f4375d37d75625a86bb41161e082c3dc0d8d40459c32a040cf138021510
|
data/.github/workflows/ci.yml
CHANGED
data/.gitignore
CHANGED
@@ -25,4 +25,15 @@ test/version_tmp
|
|
25
25
|
tmp
|
26
26
|
vendor/
|
27
27
|
/easycop.yml
|
28
|
-
/.rubocop.yml
|
28
|
+
/.rubocop.yml
|
29
|
+
[._]*.s[a-v][a-z]
|
30
|
+
[._]*.sw[a-p]
|
31
|
+
[._]s[a-rt-v][a-z]
|
32
|
+
[._]ss[a-gi-z]
|
33
|
+
[._]sw[a-p]
|
34
|
+
Session.vim
|
35
|
+
Sessionx.vim
|
36
|
+
.netrwhist
|
37
|
+
*~
|
38
|
+
tags
|
39
|
+
[._]*.un~
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## v5.1.1 (2023-09-05)
|
4
|
+
|
5
|
+
- Fix endpoint for creating a FedEx Smartpost carrier account
|
6
|
+
|
7
|
+
## v5.1.0 (2023-07-28)
|
8
|
+
|
9
|
+
- Adds hooks to introspect the request and response of API calls (see `HTTP Hooks` section in the README for more details)
|
10
|
+
- Maps 400 status code responses to the new `BadRequestError` class
|
11
|
+
|
3
12
|
## v5.0.1 (2023-06-20)
|
4
13
|
|
5
14
|
- Fixes a bug where the params of a `customs_info` on create weren't wrapped properly which led to an empty set of `customs_items`
|
data/Makefile
CHANGED
@@ -20,10 +20,6 @@ coverage:
|
|
20
20
|
docs:
|
21
21
|
bundle exec rdoc lib -o docs --title "EasyPost Ruby Docs"
|
22
22
|
|
23
|
-
## format - Fix Rubocop errors
|
24
|
-
format:
|
25
|
-
bundle exec rubocop -a
|
26
|
-
|
27
23
|
## install-styleguide - Import the style guides (Unix only)
|
28
24
|
install-styleguide: | update-examples-submodule
|
29
25
|
sh examples/symlink_directory_files.sh examples/style_guides/ruby .
|
@@ -32,14 +28,11 @@ install-styleguide: | update-examples-submodule
|
|
32
28
|
install: | update-examples-submodule
|
33
29
|
bundle install
|
34
30
|
|
35
|
-
## update-examples-submodule - Update the examples submodule
|
36
|
-
update-examples-submodule:
|
37
|
-
git submodule init
|
38
|
-
git submodule update --remote
|
39
|
-
|
40
31
|
## lint - Lint the project
|
41
|
-
lint:
|
42
|
-
|
32
|
+
lint: rubocop scan
|
33
|
+
|
34
|
+
## lint-fix - Fix Rubocop errors
|
35
|
+
lint-fix: rubocop-fix
|
43
36
|
|
44
37
|
## publish - Publishes the built gem to Rubygems
|
45
38
|
publish:
|
@@ -50,6 +43,14 @@ publish:
|
|
50
43
|
release:
|
51
44
|
gh release create ${tag} dist/*
|
52
45
|
|
46
|
+
## rubocop - lints the project with rubocop
|
47
|
+
rubocop:
|
48
|
+
bundle exec rubocop
|
49
|
+
|
50
|
+
## rubocop-fix - fix rubocop errors
|
51
|
+
rubocop-fix:
|
52
|
+
bundle exec rubocop -a
|
53
|
+
|
53
54
|
## scan - Runs security analysis on the project with Brakeman
|
54
55
|
scan:
|
55
56
|
bundle exec brakeman lib --force
|
@@ -61,4 +62,9 @@ test:
|
|
61
62
|
## update - Updates dependencies
|
62
63
|
update: | update-examples-submodule
|
63
64
|
|
64
|
-
|
65
|
+
## update-examples-submodule - Update the examples submodule
|
66
|
+
update-examples-submodule:
|
67
|
+
git submodule init
|
68
|
+
git submodule update --remote
|
69
|
+
|
70
|
+
.PHONY: help build clean coverage docs install install-styleguide lint lint-fix publish release rubocop rubocop-fix scan test update update-examples-submodule
|
data/README.md
CHANGED
@@ -61,6 +61,7 @@ puts bought_shipment
|
|
61
61
|
### Custom Connections
|
62
62
|
|
63
63
|
Pass in a lambda function as `custom_client_exec` when initializing a client that responds to `call(method, uri, headers, open_timeout, read_timeout, body = nil)` where:
|
64
|
+
|
64
65
|
- `uri` is the fully-qualified URL of the EasyPost endpoint, including query parameters (`Uri` object)
|
65
66
|
- `method` is the lowercase name of the HTTP method being used for the request (e.g. `:get`, `:post`, `:put`, `:delete`)
|
66
67
|
- `headers` is a hash with all headers needed for the request pre-populated, including authorization (`Hash` object)
|
@@ -69,7 +70,8 @@ Pass in a lambda function as `custom_client_exec` when initializing a client tha
|
|
69
70
|
- `body` is a string of the body data to be included in the request, or nil (e.g. GET or DELETE request) (string or `nil`)
|
70
71
|
|
71
72
|
The lambda function should return an object with `code` and `body` attributes, where:
|
72
|
-
|
73
|
+
|
74
|
+
- `code` is the HTTP response status code (integer)
|
73
75
|
- `body` is the response body (string)
|
74
76
|
|
75
77
|
#### Faraday
|
@@ -116,6 +118,49 @@ my_client = described_class.new(
|
|
116
118
|
)
|
117
119
|
```
|
118
120
|
|
121
|
+
### HTTP Hooks
|
122
|
+
|
123
|
+
Users can audit HTTP requests and responses being made by the library by subscribing to request and response events. To do so, pass a block to the `subscribe_request_hook` and `subscribe_response_hook` methods of an instance of `EasyPost::Client`:
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
require 'easypost'
|
127
|
+
|
128
|
+
client = EasyPost::Client.new(api_key: ENV['EASYPOST_API_KEY'])
|
129
|
+
|
130
|
+
# Returns a randomly-generated symbol which you can use to later unsubscribe the request hook
|
131
|
+
client.subscribe_request_hook do |request_data|
|
132
|
+
# Your code goes here
|
133
|
+
end
|
134
|
+
# Returns a randomly-generated symbol which you can use to later unsubscribe the response hook
|
135
|
+
client.subscribe_response_hook do |response_data|
|
136
|
+
# Your code goes here
|
137
|
+
end
|
138
|
+
```
|
139
|
+
|
140
|
+
You can also name your hook subscriptions by providing an optional parameter to the methods above:
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
require 'easypost'
|
144
|
+
|
145
|
+
client = EasyPost::Client.new(api_key: ENV['EASYPOST_API_KEY'])
|
146
|
+
|
147
|
+
request_hook = client.subscribe_request_hook(:my_request_hook) do |request_data|
|
148
|
+
# Your code goes here
|
149
|
+
end
|
150
|
+
response_hook = client.subscribe_response_hook(:my_response_hook) do |response_data|
|
151
|
+
# Your code goes here
|
152
|
+
end
|
153
|
+
|
154
|
+
puts request_hook # :my_request_hook
|
155
|
+
puts response_hook # :my_response_hook
|
156
|
+
```
|
157
|
+
|
158
|
+
Keep in mind that subscribing a hook with the same name of an existing hook will replace the existing hook with the new one. A request hook and a response hook can share the same name.
|
159
|
+
|
160
|
+
#### Custom HTTP Connections with HTTP Hooks
|
161
|
+
|
162
|
+
If you're using a custom HTTP connection, keep in mind that the `response_data` parameter that a response hook receives *will not be hydrated* with all the response data. You will have to inspect the `client_response_object` property in `response_data` to inspect the response code, response headers and response body.
|
163
|
+
|
119
164
|
## Documentation
|
120
165
|
|
121
166
|
API documentation can be found at: <https://easypost.com/docs/api>.
|
@@ -141,9 +186,7 @@ make install-style
|
|
141
186
|
|
142
187
|
# Lint project
|
143
188
|
make lint
|
144
|
-
|
145
|
-
# Fix linting errors
|
146
|
-
make format
|
189
|
+
make lint-fix
|
147
190
|
|
148
191
|
# Run tests (coverage is generated on a successful test suite run)
|
149
192
|
EASYPOST_TEST_API_KEY=123... EASYPOST_PROD_API_KEY=123... make test
|
@@ -155,8 +198,7 @@ make scan
|
|
155
198
|
make docs
|
156
199
|
|
157
200
|
# Update submodules
|
158
|
-
|
159
|
-
git submodule update --remote
|
201
|
+
make update-examples-submodule
|
160
202
|
```
|
161
203
|
|
162
204
|
### Testing
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
5.
|
1
|
+
5.1.1
|
data/lib/easypost/client.rb
CHANGED
@@ -4,6 +4,7 @@ require_relative 'services'
|
|
4
4
|
require_relative 'http_client'
|
5
5
|
require_relative 'internal_utilities'
|
6
6
|
require 'json'
|
7
|
+
require 'securerandom'
|
7
8
|
|
8
9
|
class EasyPost::Client
|
9
10
|
attr_reader :open_timeout, :read_timeout, :api_base
|
@@ -90,6 +91,54 @@ class EasyPost::Client
|
|
90
91
|
EasyPost::InternalUtilities::Json.convert_json_to_object(response.body, cls)
|
91
92
|
end
|
92
93
|
|
94
|
+
# Subscribe a request hook
|
95
|
+
#
|
96
|
+
# @param name [Symbol] the name of the hook. Defaults ot a ranom hexadecimal-based symbol
|
97
|
+
# @param block [Block] a code block that will be executed before a request is made
|
98
|
+
# @return [Symbol] the name of the request hook
|
99
|
+
def subscribe_request_hook(name = SecureRandom.hex.to_sym, &block)
|
100
|
+
EasyPost::Hooks.subscribe(:request, name, block)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Unsubscribe a request hook
|
104
|
+
#
|
105
|
+
# @param name [Symbol] the name of the hook
|
106
|
+
# @return [Block] the hook code block
|
107
|
+
def unsubscribe_request_hook(name)
|
108
|
+
EasyPost::Hooks.unsubscribe(:request, name)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Unsubscribe all request hooks
|
112
|
+
#
|
113
|
+
# @return [Hash] a hash containing all request hook subscriptions
|
114
|
+
def unsubscribe_all_request_hooks
|
115
|
+
EasyPost::Hooks.unsubscribe_all(:request)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Subscribe a response hook
|
119
|
+
#
|
120
|
+
# @param name [Symbol] the name of the hook. Defaults ot a ranom hexadecimal-based symbol
|
121
|
+
# @param block [Block] a code block that will be executed upon receiving the response from a request
|
122
|
+
# @return [Symbol] the name of the response hook
|
123
|
+
def subscribe_response_hook(name = SecureRandom.hex.to_sym, &block)
|
124
|
+
EasyPost::Hooks.subscribe(:response, name, block)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Unsubscribe a response hook
|
128
|
+
#
|
129
|
+
# @param name [Symbol] the name of the hook
|
130
|
+
# @return [Block] the hook code block
|
131
|
+
def unsubscribe_response_hook(name)
|
132
|
+
EasyPost::Hooks.unsubscribe(:response, name)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Unsubscribe all response hooks
|
136
|
+
#
|
137
|
+
# @return [Hash] a hash containing all response hook subscriptions
|
138
|
+
def unsubscribe_all_response_hooks
|
139
|
+
EasyPost::Hooks.unsubscribe_all(:response)
|
140
|
+
end
|
141
|
+
|
93
142
|
private
|
94
143
|
|
95
144
|
def http_config
|
@@ -77,6 +77,8 @@ class EasyPost::Errors::ApiError < EasyPost::Errors::EasyPostError
|
|
77
77
|
EasyPost::Errors::ConnectionError
|
78
78
|
when 300, 301, 302, 303, 304, 305, 306, 307, 308
|
79
79
|
EasyPost::Errors::RedirectError
|
80
|
+
when 400
|
81
|
+
EasyPost::Errors::BadRequestError
|
80
82
|
when 401
|
81
83
|
EasyPost::Errors::UnauthorizedError
|
82
84
|
when 402
|
data/lib/easypost/errors.rb
CHANGED
@@ -12,6 +12,7 @@ require_relative 'errors/invalid_parameter_error'
|
|
12
12
|
require_relative 'errors/missing_parameter_error'
|
13
13
|
require_relative 'errors/signature_verification_error'
|
14
14
|
require_relative 'errors/api/api_error'
|
15
|
+
require_relative 'errors/api/bad_request_error'
|
15
16
|
require_relative 'errors/api/connection_error'
|
16
17
|
require_relative 'errors/api/forbidden_error'
|
17
18
|
require_relative 'errors/api/gateway_timeout_error'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class EasyPost::Hooks::RequestContext
|
4
|
+
attr_reader :method, :path, :headers, :request_body, :request_timestamp, :request_uuid
|
5
|
+
|
6
|
+
def initialize(method:, path:, headers:, request_body:, request_timestamp:, request_uuid:)
|
7
|
+
@method = method
|
8
|
+
@path = path
|
9
|
+
@headers = headers
|
10
|
+
@request_body = request_body
|
11
|
+
@request_timestamp = request_timestamp
|
12
|
+
@request_uuid = request_uuid
|
13
|
+
|
14
|
+
freeze
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class EasyPost::Hooks::ResponseContext
|
4
|
+
attr_reader :http_status, :method, :path, :headers, :response_body,
|
5
|
+
:request_timestamp, :response_timestamp, :request_uuid,
|
6
|
+
:client_response_object
|
7
|
+
|
8
|
+
def initialize(http_status:, method:, path:, headers:, response_body:,
|
9
|
+
request_timestamp:, response_timestamp:, request_uuid:,
|
10
|
+
client_response_object:)
|
11
|
+
@http_status = http_status
|
12
|
+
@method = method
|
13
|
+
@path = path
|
14
|
+
@headers = headers
|
15
|
+
@response_body = response_body
|
16
|
+
@request_timestamp = request_timestamp
|
17
|
+
@response_timestamp = response_timestamp
|
18
|
+
@request_uuid = request_uuid
|
19
|
+
@client_response_object = client_response_object
|
20
|
+
|
21
|
+
freeze
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EasyPost::Hooks
|
4
|
+
def self.subscribe(type, name, block)
|
5
|
+
subscribers[type][name] = block
|
6
|
+
|
7
|
+
name
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.unsubscribe(type, name)
|
11
|
+
subscribers[type].delete(name)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.unsubscribe_all(type)
|
15
|
+
subscribers.delete(type)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.notify(type, context)
|
19
|
+
subscribers[type].each_value { |subscriber| subscriber.call(context) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.any_subscribers?(type)
|
23
|
+
!subscribers[type].empty?
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.subscribers
|
27
|
+
@subscribers ||= Hash.new { |hash, key| hash[key] = {} }
|
28
|
+
end
|
29
|
+
|
30
|
+
private_class_method :subscribers
|
31
|
+
end
|
32
|
+
|
33
|
+
require_relative 'hooks/request_context'
|
34
|
+
require_relative 'hooks/response_context'
|
data/lib/easypost/http_client.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'securerandom'
|
4
|
+
|
3
5
|
class EasyPost::HttpClient
|
4
6
|
def initialize(base_url, config, custom_client_exec = nil)
|
5
7
|
@base_url = base_url
|
@@ -20,17 +22,67 @@ class EasyPost::HttpClient
|
|
20
22
|
|
21
23
|
uri = URI.parse("#{@base_url}/#{api_version}/#{path}")
|
22
24
|
headers = @config[:headers].merge(headers || {})
|
23
|
-
|
25
|
+
serialized_body = JSON.dump(EasyPost::InternalUtilities.objects_to_ids(body)) if body
|
24
26
|
open_timeout = @config[:open_timeout]
|
25
27
|
read_timeout = @config[:read_timeout]
|
28
|
+
request_timestamp = Time.now
|
29
|
+
request_uuid = SecureRandom.uuid
|
30
|
+
|
31
|
+
if EasyPost::Hooks.any_subscribers?(:request)
|
32
|
+
request_context = EasyPost::Hooks::RequestContext.new(
|
33
|
+
method: method,
|
34
|
+
path: uri.to_s,
|
35
|
+
headers: headers,
|
36
|
+
request_body: body,
|
37
|
+
request_timestamp: request_timestamp,
|
38
|
+
request_uuid: request_uuid,
|
39
|
+
)
|
40
|
+
EasyPost::Hooks.notify(:request, request_context)
|
41
|
+
end
|
26
42
|
|
27
43
|
# Execute the request, return the response.
|
28
44
|
|
29
|
-
if @custom_client_exec
|
30
|
-
|
31
|
-
|
32
|
-
|
45
|
+
response = if @custom_client_exec
|
46
|
+
@custom_client_exec.call(method, uri, headers, open_timeout, read_timeout, serialized_body)
|
47
|
+
else
|
48
|
+
default_request_execute(method, uri, headers, open_timeout, read_timeout, serialized_body)
|
49
|
+
end
|
50
|
+
response_timestamp = Time.now
|
51
|
+
|
52
|
+
if EasyPost::Hooks.any_subscribers?(:response)
|
53
|
+
response_context = {
|
54
|
+
http_status: nil,
|
55
|
+
method: method,
|
56
|
+
path: uri.to_s,
|
57
|
+
headers: nil,
|
58
|
+
response_body: nil,
|
59
|
+
request_timestamp: request_timestamp,
|
60
|
+
response_timestamp: response_timestamp,
|
61
|
+
client_response_object: response,
|
62
|
+
request_uuid: request_uuid,
|
63
|
+
}
|
64
|
+
|
65
|
+
# If using a custom HTTP client, the user will have to infer these from the raw
|
66
|
+
# client_response_object attribute
|
67
|
+
if response.is_a?(Net::HTTPResponse)
|
68
|
+
response_body = begin
|
69
|
+
JSON.parse(response.body)
|
70
|
+
rescue JSON::ParseError
|
71
|
+
response.body
|
72
|
+
end
|
73
|
+
response_context.merge!(
|
74
|
+
{
|
75
|
+
http_status: response.code.to_i,
|
76
|
+
headers: response.each_header.to_h,
|
77
|
+
response_body: response_body,
|
78
|
+
},
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
EasyPost::Hooks.notify(:response, EasyPost::Hooks::ResponseContext.new(**response_context))
|
33
83
|
end
|
84
|
+
|
85
|
+
response
|
34
86
|
end
|
35
87
|
|
36
88
|
def default_request_execute(method, uri, headers, open_timeout, read_timeout, body = nil)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class EasyPost::Services::CarrierAccount < EasyPost::Services::Service
|
4
|
-
CUSTOM_WORKFLOW_CARRIER_TYPES = %w[UpsAccount FedexAccount].freeze
|
4
|
+
CUSTOM_WORKFLOW_CARRIER_TYPES = %w[UpsAccount FedexAccount FedexSmartpostAccount].freeze
|
5
5
|
MODEL_CLASS = EasyPost::Models::CarrierAccount
|
6
6
|
|
7
7
|
# Create a carrier account
|
data/lib/easypost.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easypost
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- EasyPost Developers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: brakeman
|
@@ -237,6 +237,7 @@ files:
|
|
237
237
|
- lib/easypost/constants.rb
|
238
238
|
- lib/easypost/errors.rb
|
239
239
|
- lib/easypost/errors/api/api_error.rb
|
240
|
+
- lib/easypost/errors/api/bad_request_error.rb
|
240
241
|
- lib/easypost/errors/api/connection_error.rb
|
241
242
|
- lib/easypost/errors/api/external_api_error.rb
|
242
243
|
- lib/easypost/errors/api/forbidden_error.rb
|
@@ -262,6 +263,9 @@ files:
|
|
262
263
|
- lib/easypost/errors/invalid_parameter_error.rb
|
263
264
|
- lib/easypost/errors/missing_parameter_error.rb
|
264
265
|
- lib/easypost/errors/signature_verification_error.rb
|
266
|
+
- lib/easypost/hooks.rb
|
267
|
+
- lib/easypost/hooks/request_context.rb
|
268
|
+
- lib/easypost/hooks/response_context.rb
|
265
269
|
- lib/easypost/http_client.rb
|
266
270
|
- lib/easypost/internal_utilities.rb
|
267
271
|
- lib/easypost/models.rb
|