easypost 4.8.1 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +5 -0
  3. data/.github/workflows/ci.yml +34 -5
  4. data/.gitignore +27 -20
  5. data/CHANGELOG.md +56 -0
  6. data/Makefile +30 -11
  7. data/README.md +111 -45
  8. data/UPGRADE_GUIDE.md +119 -0
  9. data/VERSION +1 -1
  10. data/easypost.gemspec +14 -10
  11. data/lib/easypost/client.rb +178 -0
  12. data/lib/easypost/connection.rb +2 -4
  13. data/lib/easypost/constants.rb +15 -0
  14. data/lib/easypost/errors/api/api_error.rb +108 -0
  15. data/lib/easypost/errors/api/bad_request_error.rb +6 -0
  16. data/lib/easypost/errors/api/connection_error.rb +6 -0
  17. data/lib/easypost/errors/api/external_api_error.rb +18 -0
  18. data/lib/easypost/errors/api/forbidden_error.rb +6 -0
  19. data/lib/easypost/errors/api/gateway_timeout_error.rb +6 -0
  20. data/lib/easypost/errors/api/internal_server_error.rb +6 -0
  21. data/lib/easypost/errors/api/invalid_request_error.rb +6 -0
  22. data/lib/easypost/errors/api/method_not_allowed_error.rb +6 -0
  23. data/lib/easypost/errors/api/not_found_error.rb +6 -0
  24. data/lib/easypost/errors/api/payment_error.rb +6 -0
  25. data/lib/easypost/errors/api/proxy_error.rb +6 -0
  26. data/lib/easypost/errors/api/rate_limit_error.rb +6 -0
  27. data/lib/easypost/errors/api/redirect_error.rb +6 -0
  28. data/lib/easypost/errors/api/retry_error.rb +6 -0
  29. data/lib/easypost/errors/api/service_unavailable_error.rb +6 -0
  30. data/lib/easypost/errors/api/ssl_error.rb +6 -0
  31. data/lib/easypost/errors/api/timeout_error.rb +6 -0
  32. data/lib/easypost/errors/api/unauthorized_error.rb +6 -0
  33. data/lib/easypost/errors/api/unknown_api_error.rb +6 -0
  34. data/lib/easypost/errors/easy_post_error.rb +7 -0
  35. data/lib/easypost/errors/end_of_pagination_error.rb +7 -0
  36. data/lib/easypost/errors/filtering_error.rb +4 -0
  37. data/lib/easypost/errors/invalid_object_error.rb +4 -0
  38. data/lib/easypost/errors/invalid_parameter_error.rb +11 -0
  39. data/lib/easypost/errors/missing_parameter_error.rb +9 -0
  40. data/lib/easypost/errors/signature_verification_error.rb +4 -0
  41. data/lib/easypost/errors.rb +32 -0
  42. data/lib/easypost/hooks/request_context.rb +16 -0
  43. data/lib/easypost/hooks/response_context.rb +23 -0
  44. data/lib/easypost/hooks.rb +34 -0
  45. data/lib/easypost/http_client.rb +117 -0
  46. data/lib/easypost/internal_utilities.rb +66 -0
  47. data/lib/easypost/models/address.rb +5 -0
  48. data/lib/easypost/models/api_key.rb +5 -0
  49. data/lib/easypost/models/base.rb +58 -0
  50. data/lib/easypost/models/batch.rb +5 -0
  51. data/lib/easypost/models/brand.rb +5 -0
  52. data/lib/easypost/{carbon_offset.rb → models/carbon_offset.rb} +1 -1
  53. data/lib/easypost/models/carrier_account.rb +5 -0
  54. data/lib/easypost/models/customs_info.rb +5 -0
  55. data/lib/easypost/models/customs_item.rb +5 -0
  56. data/lib/easypost/models/end_shipper.rb +5 -0
  57. data/lib/easypost/models/error.rb +21 -0
  58. data/lib/easypost/models/event.rb +5 -0
  59. data/lib/easypost/{insurance.rb → models/insurance.rb} +1 -1
  60. data/lib/easypost/models/order.rb +9 -0
  61. data/lib/easypost/models/parcel.rb +5 -0
  62. data/lib/easypost/models/payload.rb +5 -0
  63. data/lib/easypost/models/payment_method.rb +5 -0
  64. data/lib/easypost/models/pickup.rb +9 -0
  65. data/lib/easypost/{pickup_rate.rb → models/pickup_rate.rb} +1 -1
  66. data/lib/easypost/{postage_label.rb → models/postage_label.rb} +1 -1
  67. data/lib/easypost/models/rate.rb +5 -0
  68. data/lib/easypost/models/referral.rb +5 -0
  69. data/lib/easypost/{refund.rb → models/refund.rb} +1 -1
  70. data/lib/easypost/models/report.rb +5 -0
  71. data/lib/easypost/models/scan_form.rb +6 -0
  72. data/lib/easypost/models/shipment.rb +10 -0
  73. data/lib/easypost/{tax_identifier.rb → models/tax_identifier.rb} +1 -1
  74. data/lib/easypost/models/tracker.rb +5 -0
  75. data/lib/easypost/models/user.rb +5 -0
  76. data/lib/easypost/models/webhook.rb +6 -0
  77. data/lib/easypost/models.rb +35 -0
  78. data/lib/easypost/services/address.rb +50 -0
  79. data/lib/easypost/services/api_key.rb +8 -0
  80. data/lib/easypost/services/base.rb +27 -0
  81. data/lib/easypost/services/batch.rb +53 -0
  82. data/lib/easypost/services/beta_rate.rb +12 -0
  83. data/lib/easypost/services/beta_referral_customer.rb +40 -0
  84. data/lib/easypost/services/billing.rb +75 -0
  85. data/lib/easypost/services/carrier_account.rb +44 -0
  86. data/lib/easypost/services/carrier_metadata.rb +22 -0
  87. data/lib/easypost/services/customs_info.rb +17 -0
  88. data/lib/easypost/services/customs_item.rb +15 -0
  89. data/lib/easypost/services/end_shipper.rb +31 -0
  90. data/lib/easypost/services/event.rb +32 -0
  91. data/lib/easypost/services/insurance.rb +26 -0
  92. data/lib/easypost/services/order.rb +30 -0
  93. data/lib/easypost/services/parcel.rb +16 -0
  94. data/lib/easypost/services/pickup.rb +40 -0
  95. data/lib/easypost/services/rate.rb +8 -0
  96. data/lib/easypost/services/referral_customer.rb +103 -0
  97. data/lib/easypost/services/refund.rb +26 -0
  98. data/lib/easypost/services/report.rb +42 -0
  99. data/lib/easypost/services/scan_form.rb +25 -0
  100. data/lib/easypost/services/shipment.rb +106 -0
  101. data/lib/easypost/services/tracker.rb +38 -0
  102. data/lib/easypost/services/user.rb +66 -0
  103. data/lib/easypost/services/webhook.rb +34 -0
  104. data/lib/easypost/services.rb +32 -0
  105. data/lib/easypost/util.rb +116 -161
  106. data/lib/easypost/utilities/constants.rb +5 -0
  107. data/lib/easypost/utilities/json.rb +23 -0
  108. data/lib/easypost/utilities/static_mapper.rb +73 -0
  109. data/lib/easypost/utilities/system.rb +36 -0
  110. data/lib/easypost.rb +14 -136
  111. metadata +177 -65
  112. data/.rubocop.yml +0 -11
  113. data/CODE_OF_CONDUCT.md +0 -16
  114. data/CONTRIBUTING.md +0 -47
  115. data/SECURITY.md +0 -7
  116. data/SUPPORT.md +0 -3
  117. data/easycop.yml +0 -180
  118. data/lib/easypost/address.rb +0 -40
  119. data/lib/easypost/api_key.rb +0 -5
  120. data/lib/easypost/batch.rb +0 -50
  121. data/lib/easypost/beta/end_shipper.rb +0 -44
  122. data/lib/easypost/beta/referral.rb +0 -110
  123. data/lib/easypost/beta.rb +0 -7
  124. data/lib/easypost/billing.rb +0 -72
  125. data/lib/easypost/brand.rb +0 -13
  126. data/lib/easypost/carrier_account.rb +0 -9
  127. data/lib/easypost/carrier_type.rb +0 -5
  128. data/lib/easypost/customs_info.rb +0 -9
  129. data/lib/easypost/customs_item.rb +0 -9
  130. data/lib/easypost/end_shipper.rb +0 -24
  131. data/lib/easypost/error.rb +0 -32
  132. data/lib/easypost/event.rb +0 -11
  133. data/lib/easypost/object.rb +0 -171
  134. data/lib/easypost/order.rb +0 -37
  135. data/lib/easypost/parcel.rb +0 -9
  136. data/lib/easypost/payment_method.rb +0 -11
  137. data/lib/easypost/pickup.rb +0 -37
  138. data/lib/easypost/rate.rb +0 -9
  139. data/lib/easypost/referral.rb +0 -102
  140. data/lib/easypost/report.rb +0 -23
  141. data/lib/easypost/resource.rb +0 -106
  142. data/lib/easypost/scan_form.rb +0 -11
  143. data/lib/easypost/shipment.rb +0 -155
  144. data/lib/easypost/tracker.rb +0 -12
  145. data/lib/easypost/user.rb +0 -71
  146. data/lib/easypost/webhook.rb +0 -57
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9ad992fe480aa1a1c8b1fc7e85dd06c7af4478bca9bcc3a2f083daaeeedcc39e
4
- data.tar.gz: f37a2a32dac1dcc1efa0121dce6b6edbf14e3aa690308d393815ecaabddedda4
3
+ metadata.gz: 74cc993ead7c401dc7dbd719667872b1317a83e31c93bf85e3489cdc5b322a51
4
+ data.tar.gz: 17095956ef150f649b12b9b974db4098b495bbfe7710fe368d594e7e6410e6ea
5
5
  SHA512:
6
- metadata.gz: 6f0e9c8cbfb299608c58c865a2193e163739ca3543fb5bbea44026930bbecf34ae8d772fc2377909492a89d8c7d3d1440c7a9f7ebf25935927db35bc6ba1b7c3
7
- data.tar.gz: 8b02eee4c36c0c918e4a3f4884694c48d453bbf3aba7db653669618462d67bad30c0cf0ceec96ee44de0b335626e0992b493ad06e4457feeb5f661ebe55ceb70
6
+ metadata.gz: 8708b3ed757fdcec975e84a585bbbdc5e428de0f32b34b047b3d1860fb663db7b48748a49a5841de405adb00bc3102c3bc7ffea56d7d4ff0bf7ff6a74e81015d
7
+ data.tar.gz: 4fb43956853af9c440f7b84a804250e5e817ea3261e9900f821236bf2ae4fc623d1a68a36a899628b655ca6b1833e9095b3b943d2224224a95af24fb6c732bca
data/.gitattributes CHANGED
@@ -1,4 +1,9 @@
1
1
  * text=auto
2
2
 
3
+ # Cassettes
3
4
  spec/cassettes/**/* -diff
4
5
  spec/cassettes/**/* linguist-generated
6
+
7
+ # Docs
8
+ docs/**/* -diff
9
+ docs/**/* linguist-generated
@@ -1,4 +1,4 @@
1
- name: "CI"
1
+ name: 'CI'
2
2
 
3
3
  on:
4
4
  push:
@@ -11,7 +11,7 @@ jobs:
11
11
  runs-on: ubuntu-latest
12
12
  strategy:
13
13
  matrix:
14
- rubyversion: ["2.5", "2.6", "2.7", "3.0", "3.1"]
14
+ rubyversion: ['2.6', '2.7', '3.0', '3.1', '3.2']
15
15
  steps:
16
16
  - name: Checkout Repository
17
17
  uses: actions/checkout@v3
@@ -19,11 +19,18 @@ jobs:
19
19
  uses: ruby/setup-ruby@v1
20
20
  with:
21
21
  ruby-version: ${{ matrix.rubyversion }}
22
+ rubygems: '3.0.0'
22
23
  bundler-cache: true
23
24
  - name: Install Dependencies
24
25
  run: make install
25
26
  - name: run tests
26
27
  run: EASYPOST_TEST_API_KEY=123 EASYPOST_PROD_API_KEY=123 make test
28
+ - name: Coveralls
29
+ if: github.ref == 'refs/heads/master'
30
+ uses: coverallsapp/github-action@master
31
+ with:
32
+ github-token: ${{ secrets.GITHUB_TOKEN }}
33
+ path-to-lcov: './coverage/lcov/easypost-ruby.lcov'
27
34
  lint:
28
35
  runs-on: ubuntu-latest
29
36
  steps:
@@ -32,11 +39,33 @@ jobs:
32
39
  - name: Set up Ruby
33
40
  uses: ruby/setup-ruby@v1
34
41
  with:
35
- ruby-version: "3.1"
42
+ ruby-version: '3.2'
43
+ rubygems: '3.0.0'
36
44
  bundler-cache: true
37
45
  - name: Install Dependencies
38
46
  run: make install
47
+ - name: Install style guides
48
+ run: make install-styleguide
39
49
  - name: Lint Project
40
50
  run: make lint
41
- - name: Run security analysis
42
- run: make scan
51
+ docs:
52
+ if: github.ref == 'refs/heads/master'
53
+ runs-on: ubuntu-latest
54
+ steps:
55
+ - name: Checkout Repository
56
+ uses: actions/checkout@v3
57
+ - name: Set up Ruby
58
+ uses: ruby/setup-ruby@v1
59
+ with:
60
+ ruby-version: '3.2'
61
+ rubygems: '3.0.0'
62
+ bundler-cache: true
63
+ - name: Install Dependencies
64
+ run: make install
65
+ - name: Generate Docs
66
+ run: make docs
67
+ - name: Deploy docs
68
+ uses: peaceiris/actions-gh-pages@v3
69
+ with:
70
+ github_token: ${{ secrets.GITHUB_TOKEN }}
71
+ publish_dir: docs
data/.gitignore CHANGED
@@ -1,9 +1,20 @@
1
- *.gem
2
- *.rbc
1
+ ._*
2
+ .AppleDouble
3
3
  .bundle
4
4
  .config
5
- Gemfile.lock
5
+ .DS_Store
6
+ .env
7
+ .idea/
8
+ .LSOverride
9
+ .Spotlight-V100
10
+ .Trashes
11
+ *.gem
12
+ *.rbc
6
13
  coverage
14
+ dist
15
+ docs
16
+ Gemfile.lock
17
+ Icon
7
18
  InstalledFiles
8
19
  lib/bundler/man
9
20
  pkg
@@ -12,21 +23,17 @@ spec/reports
12
23
  test/tmp
13
24
  test/version_tmp
14
25
  tmp
15
- .idea/
16
- dist
17
-
18
- # YARD artifacts
19
- .yardoc
20
- _yardoc
21
- doc/
22
-
23
- # iOS
24
- .DS_Store
25
- .AppleDouble
26
- .LSOverride
27
- Icon
28
- ._*
29
- .Spotlight-V100
30
- .Trashes
31
26
  vendor/
32
- .env
27
+ /easycop.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,61 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v5.1.0 (2023-07-28)
4
+
5
+ - Adds hooks to introspect the request and response of API calls (see `HTTP Hooks` section in the README for more details)
6
+ - Maps 400 status code responses to the new `BadRequestError` class
7
+
8
+ ## v5.0.1 (2023-06-20)
9
+
10
+ - 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`
11
+
12
+ ## v5.0.0 (2023-06-06)
13
+
14
+ See our [Upgrade Guide](UPGRADE_GUIDE.md#upgrading-from-4x-to-50) for more details.
15
+
16
+ - Library is now thread-safe. Closes GitHub Issue ([#183](https://github.com/EasyPost/easypost-ruby/issues/183))
17
+ - Initialize a `Client` object with an API key. Optionally set open and read timeout params
18
+ - Previous classes have been diverted into `Services` and `Models`
19
+ - All methods (i.e. `create`, `retrieve`, `all`) exist in services, accessed via property of the client (eg: `client.shipment.create()`)
20
+ - E.g. `bought_shipment = client.shipment.buy(shipment_id, rate)`
21
+ - Beta namespace changed from `easypost.beta.x` to `client.beta_x`
22
+ - References to `Referral` are now `ReferralCustomer` and `referral_customer` to match the API and docs
23
+ - References to `smartrate` are now `SmartRate` and `smart_rate` to match the API and docs
24
+ - Rename function `get_smartrates` to `get_smart_rates`
25
+ - Rename function `get_lowest_smartrate` to `get_lowest_smart_rate`
26
+ - Empty API response functions for `delete` return `true` instead of empty object
27
+ - Drops support for Ruby 2.5
28
+ - Bumps all dev dependencies
29
+ - Improves Error Deserialization to dynamically handle edge cases that have a bad format
30
+ - Adds `retrieve_estimated_delivery_date` function in Shipment
31
+ - Removes deprecated `endshipper` beta class, please use the GA one `EasyPost::Services::EndShipper`
32
+
33
+ ## v4.13.0 (2023-04-04)
34
+
35
+ - Adds `get_next_page` function to each object which retrieves the next page of a collection when the `has_more` key is present in the response
36
+
37
+ ## v4.12.0 (2023-02-21)
38
+
39
+ - Adds beta `retrieve_stateless_rates` function
40
+ - Adds `get_lowest_stateless_rate` utility
41
+
42
+ ## v4.11.0 (2023-01-18)
43
+
44
+ - Added function to retrieve all pickups, accessible via `EasyPost::Pickup.all`
45
+ - Added payload functions `retrieve_all_payloads` and `retrieve_payload` to retrieve all payloads or a specific payload for an event.
46
+
47
+ ## v4.10.0 (2023-01-11)
48
+
49
+ - Added new beta billing functionality for referral customer users, accessible via `EasyPost::Beta::Referral`
50
+ - `add_payment_method` to add an existing Stripe bank account or credit card to your EasyPost account
51
+ - `refund_by_amount` refunds you wallet balance by a specified amount
52
+ - `refund_by_payment_log` refunds you wallet balance by a specified payment log
53
+ - Fix bug where bank account and credit card payment methods were not deserializing to the `EasyPost::PaymentMethod` class
54
+
55
+ ## v4.9.0 (2022-12-07)
56
+
57
+ - Routes requests for creating a carrier account with a custom workflow (eg: FedEx, UPS) to the correct endpoint when using the `create` function
58
+
3
59
  ## v4.8.1 (2022-10-24)
4
60
 
5
61
  - Concatenates `error.message` if it incorrectly comes back from the API as an array
data/Makefile CHANGED
@@ -12,19 +12,27 @@ build:
12
12
  clean:
13
13
  rm -rf coverage doc *.gem dist
14
14
 
15
- ## fix - Fix Rubocop errors
16
- fix:
17
- bundle exec rubocop -A
15
+ ## coverage - Generate a test coverage report
16
+ coverage:
17
+ make test
18
+
19
+ ## docs - Generate documentation for the library
20
+ docs:
21
+ bundle exec rdoc lib -o docs --title "EasyPost Ruby Docs"
22
+
23
+ ## install-styleguide - Import the style guides (Unix only)
24
+ install-styleguide: | update-examples-submodule
25
+ sh examples/symlink_directory_files.sh examples/style_guides/ruby .
18
26
 
19
27
  ## install - Install globally from source
20
- install:
21
- git submodule init
22
- git submodule update
28
+ install: | update-examples-submodule
23
29
  bundle install
24
30
 
25
31
  ## lint - Lint the project
26
- lint:
27
- bundle exec rubocop
32
+ lint: rubocop scan
33
+
34
+ ## lint-fix - Fix Rubocop errors
35
+ lint-fix: rubocop-fix
28
36
 
29
37
  ## publish - Publishes the built gem to Rubygems
30
38
  publish:
@@ -35,17 +43,28 @@ publish:
35
43
  release:
36
44
  gh release create ${tag} dist/*
37
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
+
38
54
  ## scan - Runs security analysis on the project with Brakeman
39
55
  scan:
40
56
  bundle exec brakeman lib --force
41
57
 
42
58
  ## test - Test the project (and ignore warnings for test output)
43
59
  test:
44
- RUBYOPT="-W0" bundle exec rspec
60
+ bundle exec rspec
45
61
 
46
62
  ## update - Updates dependencies
47
- update:
63
+ update: | update-examples-submodule
64
+
65
+ ## update-examples-submodule - Update the examples submodule
66
+ update-examples-submodule:
48
67
  git submodule init
49
68
  git submodule update --remote
50
69
 
51
- .PHONY: help build clean fix install lint publish release scan test update
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
@@ -1,6 +1,7 @@
1
1
  # EasyPost Ruby Client Library
2
2
 
3
3
  [![Build Status](https://github.com/EasyPost/easypost-ruby/workflows/CI/badge.svg)](https://github.com/EasyPost/easypost-ruby/actions?query=workflow%3ACI)
4
+ [![Coverage Status](https://coveralls.io/repos/github/EasyPost/easypost-ruby/badge.svg?branch=master)](https://coveralls.io/github/EasyPost/easypost-ruby?branch=master)
4
5
  [![Gem Version](https://badge.fury.io/rb/easypost.svg)](https://badge.fury.io/rb/easypost)
5
6
 
6
7
  EasyPost, the simple shipping solution. You can sign up for an account at <https://easypost.com>.
@@ -23,9 +24,9 @@ A simple create & buy shipment example:
23
24
  ```ruby
24
25
  require 'easypost'
25
26
 
26
- EasyPost.api_key = ENV['EASYPOST_API_KEY']
27
+ client = EasyPost::Client.new(api_key: ENV['EASYPOST_TEST_API_KEY'])
27
28
 
28
- shipment = EasyPost::Shipment.create(
29
+ shipment = client.shipment.create(
29
30
  from_address: {
30
31
  company: 'EasyPost',
31
32
  street1: '118 2nd Street',
@@ -52,39 +53,47 @@ shipment = EasyPost::Shipment.create(
52
53
  },
53
54
  )
54
55
 
55
- shipment.buy(rate: shipment.lowest_rate)
56
+ bought_shipment = client.shipment.buy(shipment.id, rate: shipment.lowest_rate)
56
57
 
57
- puts shipment
58
+ puts bought_shipment
58
59
  ```
59
60
 
60
61
  ### Custom Connections
61
62
 
62
- Set `EasyPost.default_connection` to an object that responds to `call(method, path, api_key = nil, body = nil)`
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
+
65
+ - `uri` is the fully-qualified URL of the EasyPost endpoint, including query parameters (`Uri` object)
66
+ - `method` is the lowercase name of the HTTP method being used for the request (e.g. `:get`, `:post`, `:put`, `:delete`)
67
+ - `headers` is a hash with all headers needed for the request pre-populated, including authorization (`Hash` object)
68
+ - `open_timeout` is the number of seconds to wait for the connection to open (integer)
69
+ - `read_timeout` is the number of seconds to wait for one block to be read (integer)
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`)
71
+
72
+ The lambda function should return an object with `code` and `body` attributes, where:
73
+
74
+ - `code` is the HTTP response status code (integer)
75
+ - `body` is the response body (string)
63
76
 
64
77
  #### Faraday
65
78
 
66
79
  ```ruby
67
80
  require 'faraday'
68
- require 'faraday/response/logger'
69
- require 'logger'
70
-
71
- EasyPost.default_connection = lambda do |method, path, api_key = nil, body = nil|
72
- Faraday
73
- .new(url: EasyPost.api_base, headers: EasyPost.default_headers) { |builder|
74
- builder.use Faraday::Response::Logger, Logger.new(STDOUT), {bodies: true, headers: true}
75
- builder.adapter :net_http
76
- }
77
- .public_send(method, path) { |request|
78
- request.headers['Authorization'] = EasyPost.authorization(api_key)
79
- request.body = JSON.dump(EasyPost::Util.objects_to_ids(body)) if body
80
- }.yield_self { |response|
81
- EasyPost.parse_response(
82
- status: response.status,
83
- body: response.body,
84
- json: response.headers['Content-Type'].start_with?('application/json'),
85
- )
86
- }
87
- end
81
+
82
+ custom_connection = lambda { |method, uri, headers, _open_timeout, _read_timeout, body = nil|
83
+ conn = Faraday.new(url: uri.to_s, headers: headers) do |faraday|
84
+ faraday.adapter Faraday.default_adapter
85
+ end
86
+ conn.public_send(method, uri.path) { |request|
87
+ request.body = body if body
88
+ }.yield_self do |response|
89
+ OpenStruct.new(code: response.status, body: response.body)
90
+ end
91
+ }
92
+
93
+ my_client = described_class.new(
94
+ api_key: ENV['EASYPOST_API_KEY'],
95
+ custom_client_exec: custom_connection,
96
+ )
88
97
  ```
89
98
 
90
99
  #### Typhoeus
@@ -92,25 +101,79 @@ end
92
101
  ```ruby
93
102
  require 'typhoeus'
94
103
 
95
- EasyPost.default_connection = lambda do |method, path, api_key = nil, body = nil|
104
+ custom_connection = lambda { |method, uri, headers, _open_timeout, _read_timeout, body = nil|
96
105
  Typhoeus.public_send(
97
106
  method,
98
- File.join(EasyPost.api_base, path),
99
- headers: EasyPost.default_headers.merge('Authorization' => EasyPost.authorization(api_key)),
100
- body: body.nil? ? nil : JSON.dump(EasyPost::Util.objects_to_ids(body)),
101
- ).yield_self { |response|
102
- EasyPost.parse_response(
103
- status: response.code,
104
- body: response.body,
105
- json: response.headers['Content-Type'].start_with?('application/json'),
106
- )
107
- }
107
+ uri.to_s,
108
+ headers: headers,
109
+ body: body,
110
+ ).yield_self do |response|
111
+ OpenStruct.new(code: response.code, body: response.body)
112
+ end
113
+ }
114
+
115
+ my_client = described_class.new(
116
+ api_key: ENV['EASYPOST_API_KEY'],
117
+ custom_client_exec: custom_connection,
118
+ )
119
+ ```
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
108
137
  end
109
138
  ```
110
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
+
111
164
  ## Documentation
112
165
 
113
- API Documentation can be found at: <https://easypost.com/docs/api>.
166
+ API documentation can be found at: <https://easypost.com/docs/api>.
167
+
168
+ Library documentation can be found on the web at: <https://easypost.github.io/easypost-ruby/> or by building them locally via the `make docs` command.
169
+
170
+ Upgrading major versions of this project? Refer to the [Upgrade Guide](UPGRADE_GUIDE.md).
171
+
172
+ ## Support
173
+
174
+ New features and bug fixes are released on the latest major release of this library. If you are on an older major release of this library, we recommend upgrading to the most recent release to take advantage of new features, bug fixes, and security patches. Older versions of this library will continue to work and be available as long as the API version they are tied to remains active; however, they will not receive updates and are considered EOL.
175
+
176
+ For additional support, see our [org-wide support policy](https://github.com/EasyPost/.github/blob/main/SUPPORT.md).
114
177
 
115
178
  ## Development
116
179
 
@@ -118,11 +181,12 @@ API Documentation can be found at: <https://easypost.com/docs/api>.
118
181
  # Install dependencies
119
182
  make install
120
183
 
184
+ # Install style guide (Unix only)
185
+ make install-style
186
+
121
187
  # Lint project
122
188
  make lint
123
-
124
- # Fix linting errors
125
- make fix
189
+ make lint-fix
126
190
 
127
191
  # Run tests (coverage is generated on a successful test suite run)
128
192
  EASYPOST_TEST_API_KEY=123... EASYPOST_PROD_API_KEY=123... make test
@@ -130,14 +194,16 @@ EASYPOST_TEST_API_KEY=123... EASYPOST_PROD_API_KEY=123... make test
130
194
  # Run security analysis
131
195
  make scan
132
196
 
197
+ # Generate library documentation
198
+ make docs
199
+
133
200
  # Update submodules
134
- git submodule init
135
- git submodule update --remote
201
+ make update-examples-submodule
136
202
  ```
137
203
 
138
204
  ### Testing
139
205
 
140
- The test suite in this project was specifically built to produce consistent results on every run, regardless of when they run or who is running them. This project uses [VCR](https://github.com/vcr/vcr) to record and replay HTTP requests and responses via "cassettes". When the suite is run, the HTTP requests and responses for each test function will be saved to a cassette if they do not exist already and replayed from this saved file if they do, which saves the need to make live API calls on every test run.
206
+ The test suite in this project was specifically built to produce consistent results on every run, regardless of when they run or who is running them. This project uses [VCR](https://github.com/vcr/vcr) to record and replay HTTP requests and responses via "cassettes". When the suite is run, the HTTP requests and responses for each test function will be saved to a cassette if they do not exist already and replayed from this saved file if they do, which saves the need to make live API calls on every test run. If you receive errors about a cassette expiring, delete and re-record the cassette to ensure the data is up-to-date.
141
207
 
142
208
  **Sensitive Data:** We've made every attempt to include scrubbers for sensitive data when recording cassettes so that PII or sensitive info does not persist in version control; however, please ensure when recording or re-recording cassettes that prior to committing your changes, no PII or sensitive information gets persisted by inspecting the cassette.
143
209
 
@@ -155,5 +221,5 @@ The following are required on every test run:
155
221
  Some tests may require an EasyPost user with a particular set of enabled features such as a `Partner` user when creating referrals. We have attempted to call out these functions in their respective docstrings. The following are required when you need to re-record cassettes for applicable tests:
156
222
 
157
223
  - `USPS_CARRIER_ACCOUNT_ID` (eg: one-call buying a shipment for non-EasyPost employees)
158
- - `PARTNER_USER_PROD_API_KEY` (eg: creating a referral user)
159
- - `REFERRAL_USER_PROD_API_KEY` (eg: adding a credit card to a referral user)
224
+ - `PARTNER_USER_PROD_API_KEY` (eg: creating a referral customer)
225
+ - `REFERRAL_CUSTOMER_PROD_API_KEY` (eg: adding a credit card to a referral customer)
data/UPGRADE_GUIDE.md CHANGED
@@ -2,8 +2,127 @@
2
2
 
3
3
  Use the following guide to assist in the upgrade process of the `easypost-ruby` library between major versions.
4
4
 
5
+ - [Upgrading from 4.x to 5.0](#upgrading-from-4x-to-50)
6
+ - [Upgrading from 3.x to 4.0](#upgrading-from-3x-to-40)
7
+
8
+ ## Upgrading from 4.x to 5.0
9
+
10
+ ### 5.0 High Impact Changes
11
+
12
+ - [New Client object](#50-thread-safe-with-client-object)
13
+ - [Updated Dependencies](#50-updated-dependencies)
14
+ - [Improved Error Handling](#50-improved-error-handling)
15
+
16
+ ### 5.0 Medium Impact Changes
17
+
18
+ - [Corrected Naming Conventions](#50-corrected-naming-conventions)
19
+
20
+ ### 5.0 Low Impact Changes
21
+
22
+ - [Beta Namespace Changed](#50-beta-namespace-changed)
23
+
24
+ ## 5.0 Thread-Safe with Client Object
25
+
26
+ Likelihood of Impact: High
27
+
28
+ This library is now thread-safe with the introduction of a new `Client` object. Instead of defining a global API key that all requests use, you now create an `Client` object and pass your API key to it with optional open and read timeout params. You then call your desired functions against a `service` which are called against a `Client` object:
29
+
30
+ ```ruby
31
+ # Old way
32
+ EasyPost.api_key = ENV['EASYPOST_API_KEY']
33
+ shipment = EasyPost::Shipment.retrieve('shp_...')
34
+
35
+ # New way
36
+ client = EasyPost::Client.new(api_key: ENV['EASYPOST_TEST_API_KEY'])
37
+ shipment = client.shipment.retrieve('shp_...')
38
+ ```
39
+
40
+ All instance methods are now static with the exception of `lowest_rate` as these make API calls and require the Client object(EasyPost objects do not contain an API key to make API calls with).
41
+
42
+ Previously used `.save()` instance methods are now static `.update()` functions where you specify first the ID of the object you are updating and second, the parameters that need updating.
43
+
44
+ ## 5.0 Updated Dependencies
45
+
46
+ Likelihood of Impact: High
47
+
48
+ **Ruby 2.6 Required**
49
+
50
+ easypost-ruby now requires Ruby 2.6 or greater.
51
+
52
+ **Dependencies**
53
+
54
+ All dependencies had minor version bumps.
55
+
56
+ ## 5.0 Improved Error Handling
57
+
58
+ Likelihood of Impact: High
59
+
60
+ There are ~2 dozen new error types that extend either `ApiError` or `EasyPostError`.
61
+
62
+ New ApiErrors (extends EasyPostError):
63
+
64
+ - `ApiError`
65
+ - `ConnectionError`
66
+ - `ExternalApiError`
67
+ - `ForbiddenError`
68
+ - `GatewayTimeoutError`
69
+ - `InternalServerError`
70
+ - `InvalidRequestError`
71
+ - `MethodNotAllowedError`
72
+ - `NotFoundError`
73
+ - `PaymentError`
74
+ - `ProxyError`
75
+ - `RateLimitError`
76
+ - `RedirectError`
77
+ - `RetryError`
78
+ - `ServiceUnavailableError`
79
+ - `SSLError`
80
+ - `TimeoutError`
81
+ - `UnauthorizedError`
82
+ - `UnknownApiError`
83
+
84
+ New EasyPostErrors (extends builtin Exception):
85
+
86
+ - `EasyPostError`
87
+ - `EndOfPaginationError`
88
+ - `FilteringError`
89
+ - `InvalidObjectError`
90
+ - `InvalidParameterError`
91
+ - `MissingParameterError`
92
+ - `SignatureVerificationError`
93
+
94
+ ApiErrors will behave like the previous Error class did. They will include a `message`, `http_status`, and `http_body`. Additionally, a new `code` and `errors` keys are present and populate when available. This class extends the more generic `EasyPostError` which only contains a message, used for errors thrown directly from this library.
95
+
96
+ ## 5.0 Corrected Naming Conventions
97
+
98
+ Likelihood of Impact: Medium
99
+
100
+ Occurances of `referral` are now `referral_customer` and `Referral` are now `ReferralCustomer` to match the documentation and API.
101
+
102
+ Occurances of `smartrate` are now `smart_rate` and `Smartrate` are now `SmartRate` to match the documentation and API.
103
+
104
+ Occurances of `scanform` are now `scan_form` and `Scanform` are now `ScanForm` to match the documentation and API.
105
+
106
+ Rename function `get_smartrates` to `get_smart_rates`
107
+
108
+ Rename function `get_lowest_smartrate` to `get_lowest_smart_rate`
109
+
110
+ ## 5.0 Beta Namespace Changed
111
+
112
+ Likelihood of Impact: Low
113
+
114
+ Previously, the beta namespace was found at `easypost.beta.x` where `x` is the name of your model. Now, the beta namespace is simply prepended to the name of your service: `client.beta_x`. for instance, you can call `client.beta_referral_customer.add_payment_method()`.
115
+
116
+ ## 5.0 Return True For Empty API Response
117
+
118
+ Likelihood of Impact: Low
119
+
120
+ Empty API response functions for `delete` return `true` instead of empty object
121
+
5
122
  ## Upgrading from 3.x to 4.0
6
123
 
124
+ **NOTICE:** v4 is deprecated.
125
+
7
126
  ### 4.0 High Impact Changes
8
127
 
9
128
  * [Updating Dependencies](#40-updating-dependencies)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 4.8.1
1
+ 5.1.0