Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# CHANGELOG

## Next Release
## v8.0.0 (2025-04-28)

See our [Upgrade Guide](UPGRADE_GUIDE.md#upgrading-from-7x-to-80) for more details.

- Adds `WebhookCustomHeader` model, allowing `custom_headers` to be passed when creating/updating a webhook
- Adds the following functions to assist ReferralCustomers add credit cards and bank accounts:
Expand All @@ -11,19 +13,23 @@
- Adds missing tracker props
- Adds `tracking_codes` param to tracker index endpoint
- Routes `AmazonShippingAccount` to the correct endpoint
- Corrects payload wrapping for updating a webhook
- Fixes error parsing
- Allows for alternative format of `errors` field (previously we deserialized the `errors` field into a list of `Error` objects; however, sometimes the errors are simply a list of strings. This change make the `errors` field a list of `Object` allowing for either the new `FieldError` object or a list of strings. Users will need to check for the type of error returned and handle appropriately)
- Removed the unused `Error` model
- Added an explicit `AddressVerificationFieldError` model
- The `BetaPaymentRefund` now uses a list of `FieldError` instead of `Error` for the `errors` field
- Removes deprecated functions
- `TimeInTransit.getSmartRateAccuracy` (use `TimeInTransit.getSmartrateAccuracy` instead)
- `paymentMethod.all` (use `billing.retrievePaymentMethods` instead)
- `shipment.getSmartrates` (use `shipment.smartrates` instead)
- String overload for `shipment.lowestSmartRate`, 3rd param requires a valid `SmartrateAccuracy`
- `user.apiKeys` (use `apiKey.retrieveApiKeysForUser` instead)
- `utilities.getLowestSmartRate` (use `utilities.findLowestSmartrate` instead)
- Corrects payload wrapping for updating a webhook
- Replaces deprecated functions
- `shipment.lowestSmartRate` (3rd param expects a valid `SmartRateAccuracy`)
- `utilities.findLowestSmartRate` (3rd param expects a valid `SmartRateAccuracy`)
- Renames
- `SmartrateAccuracy` is now `SmartRateAccuracy`
- `SmartrateCollection` is now `SmartRateCollection`
- `shipment.smartrates` is now `shipment.smartRates`
- `TimeInTransit.getBySmartrateAccuracy` is now `TimeInTransit.getSmartRateAccuracy`
- Bumps dependencies

## v7.4.4 (2025-01-03)
Expand Down Expand Up @@ -79,6 +85,8 @@

## v7.0.0 (2023-12-06)

See our [Upgrade Guide](UPGRADE_GUIDE.md#upgrading-from-6x-to-70) for more details.

- Removes `withCarbonOffset` parameter from `create`, `buy`, and `regenerateRates` functions of the Shipment service as EasyPost now offers Carbon Neutral shipments by default for free
- Removes the undocumented `createAndBuy` function from the Batch service. The proper usage is to create a batch first and buy it separately
- Changes return type of `all()` in webhook service from `WebhookCollection` to `a list of webhooks`
Expand Down Expand Up @@ -149,6 +157,8 @@

## v6.0.0 (2023-01-05)

See our [Upgrade Guide](UPGRADE_GUIDE.md#upgrading-from-5x-to-60) for more details.

Includes all the changes from `v6.0.0-rc1` listed below in addition to the following:

- All constants are now defined in the top-level `Constants` class (`com.easypost.Constants`)
Expand Down Expand Up @@ -292,7 +302,7 @@ Includes all the changes from `v6.0.0-rc1` listed below in addition to the follo

## v5.0.0 (2022-01-14)

Upgrading major versions of this project? Refer to the [Upgrade Guide](UPGRADE_GUIDE.md).
See our [Upgrade Guide](UPGRADE_GUIDE.md#upgrading-from-4x-to-50) for more details.

- Bump minimum Java version from 1.5 to 8
- Changed PUT/POST request bodies from url-form encoded to JSON encoded
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Add this to your project's POM:
<dependency>
<groupId>com.easypost</groupId>
<artifactId>easypost-api-client</artifactId>
<version>7.4.4</version>
<version>8.0.0</version>
</dependency>
```

Expand All @@ -25,7 +25,7 @@ Add this to your project's POM:
Add this to your project's build file:

```groovy
implementation "com.easypost:easypost-api-client:7.4.4"
implementation "com.easypost:easypost-api-client:8.0.0"
```

**NOTE:** [Google Gson](http://code.google.com/p/google-gson/) is required.
Expand Down
43 changes: 43 additions & 0 deletions UPGRADE_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,55 @@

Use the following guide to assist in the upgrade process of the `easypost-java` library between major versions.

- [Upgrading from 7.x to 8.x](#upgrading-from-7x-to-80)
- [Upgrading from 6.x to 7.x](#upgrading-from-6x-to-70)
- [Upgrading from 5.x to 6.0](#upgrading-from-5x-to-60)
- [Upgrading from 4.x to 5.0](#upgrading-from-4x-to-50)

## Upgrading from 7.x to 8.0

### 8.0 High Impact Changes

- [Error Parsing](#80-error-parsing)

### 8.0 Medium Impact Changes

- [Deprecations](#80-deprecations)

## 8.0 Error Parsing

*Likelihood of Impact: **High***

The `errors` key of an error response can return either a list of `FieldError` objects or a list of strings. The error parsing has been expanded to include both formats. As such, you will now need to check for the format of the `errors` field and handle the errors appropriately for the type that is returned.

The `Error` model has been removed since it is unused and we directly assign properties of an error response to the `ApiError` type.

The `BetaPaymentRefund` now uses a list of `FieldError` instead of `Error` for the `errors` field.

See the `CHANGELOG` for more details.

## 8.0 Deprecations

*Likelihood of Impact: **Medium***

The following functions have changed:

- Removed deprecated functions
- `paymentMethod.all` (use `billing.retrievePaymentMethods` instead)
- `user.apiKeys` (use `apiKey.retrieveApiKeysForUser` instead)
- Changed deprecated functions
- `shipment.lowestSmartRate` (3rd param expects a valid `SmartRateAccuracy`)
- `utilities.findLowestSmartRate` (3rd param expects a valid `SmartRateAccuracy`)
- Renames
- `SmartrateAccuracy` is now `SmartRateAccuracy`
- `SmartrateCollection` is now `SmartRateCollection`
- `shipment.smartrates` is now `shipment.smartRates`
- `TimeInTransit.getBySmartrateAccuracy` is now `TimeInTransit.getSmartRateAccuracy`

## Upgrading from 6.x to 7.0

**NOTICE:** v7 is deprecated.

### 7.0 High Impact Changes

- [Carbon Offset Removed](#70-carbon-offset-removed)
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.4.4
8.0.0
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<groupId>com.easypost</groupId>
<artifactId>easypost-api-client</artifactId>

<version>7.4.4</version>
<version>8.0.0</version>
<packaging>jar</packaging>

<name>com.easypost:easypost-api-client</name>
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/com/easypost/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import com.easypost.model.AddressVerification;
import com.easypost.model.AddressVerificationDeserializer;
import com.easypost.model.ErrorDeserializer;
import com.easypost.model.SmartrateCollection;
import com.easypost.model.SmartrateCollectionDeserializer;
import com.easypost.model.SmartRateCollection;
import com.easypost.model.SmartRateCollectionDeserializer;
import com.easypost.model.StatelessRate;
import com.easypost.model.StatelessRateDeserializer;
import com.easypost.model.Webhook;
Expand Down Expand Up @@ -83,7 +83,7 @@ public abstract static class Http {
public static final Gson GSON = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.registerTypeAdapter(HashMap.class, new HashMapSerializer())
.registerTypeAdapter(SmartrateCollection.class, new SmartrateCollectionDeserializer())
.registerTypeAdapter(SmartRateCollection.class, new SmartRateCollectionDeserializer())
.registerTypeAdapter(APIException.class, new ErrorDeserializer())
.registerTypeAdapter(AddressVerification.class, new AddressVerificationDeserializer())
.registerTypeAdapter(StatelessRate[].class, new StatelessRateDeserializer())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ public final class AddressVerificationDeserializer implements JsonDeserializer<A
* @param typeOfT Type of the object to deserialize.
* @param context Deserialization context.
* @return Deserialized AddressVerification object.
* @throws JsonParseException if the JSON object is not a valid SmartrateCollection.
* @throws JsonParseException if the JSON object is not a valid
* SmartRateCollection.
*/
@Override
public AddressVerification deserialize(final JsonElement json, final Type typeOfT,
final JsonDeserializationContext context) throws JsonParseException {
final JsonDeserializationContext context) throws JsonParseException {
JsonObject jo = json.getAsJsonObject();

AddressVerification addressVerification = new AddressVerification();
Expand Down
17 changes: 9 additions & 8 deletions src/main/java/com/easypost/model/ErrorDeserializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@

public final class ErrorDeserializer implements JsonDeserializer<APIException> {
/**
* Recursively traverse an error JSON element and its sub-element(s), and extracts all
* Recursively traverse an error JSON element and its sub-element(s), and
* extracts all
* error string values found into the specified string list.
*
* @param element the JSON element to traverse
* @param element the JSON element to traverse
* @param messagesList the list of strings to append found values to
*/
private void traverseJsonElement(JsonElement element, ArrayList<String> messagesList) {
Expand All @@ -45,11 +46,12 @@ private void traverseJsonElement(JsonElement element, ArrayList<String> messages
* @param typeOfT Type of the object to deserialize.
* @param context Deserialization context.
* @return Deserialized APIException object.
* @throws JsonParseException if the JSON object is not a valid SmartrateCollection.
* @throws JsonParseException if the JSON object is not a valid
* SmartRateCollection.
*/
@Override
public APIException deserialize(final JsonElement json, final Type typeOfT,
final JsonDeserializationContext context) throws JsonParseException {
final JsonDeserializationContext context) throws JsonParseException {
JsonObject jo = json.getAsJsonObject();

String message = null;
Expand Down Expand Up @@ -83,7 +85,6 @@ public APIException deserialize(final JsonElement json, final Type typeOfT,
}

JsonElement errorsAsJson = errorData.get("errors");
List<Object> errorList = new ArrayList<>();
if (errorsAsJson != null) {
JsonArray errorsAsArray = errorsAsJson.getAsJsonArray();
for (JsonElement errorAsJson : errorsAsArray) {
Expand All @@ -106,13 +107,13 @@ public APIException deserialize(final JsonElement json, final Type typeOfT,
fieldError.setSuggestion(suggestion.getAsString());
}

errorList.add(fieldError);
errors.add(fieldError);
} else {
errorList.add(errorAsJson.getAsString());
errors.add(errorAsJson.getAsString());
}
}
}

return new APIException(message, code, errorList);
return new APIException(message, code, errors);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import lombok.Getter;

@Getter
public enum SmartrateAccuracy {
public enum SmartRateAccuracy {
Percentile50("percentile_50"),
Percentile75("percentile_75"),
Percentile85("percentile_85"),
Expand All @@ -22,7 +22,7 @@ public enum SmartrateAccuracy {
*
* @param keyName the internal key name
*/
SmartrateAccuracy(String keyName) {
SmartRateAccuracy(String keyName) {
this.keyName = keyName;
}

Expand All @@ -33,8 +33,8 @@ public enum SmartrateAccuracy {
* @return the enum value
* @throws EasyPostException if the key name is not found
*/
public static SmartrateAccuracy getByKeyName(String keyName) throws EasyPostException {
for (SmartrateAccuracy smartrateAccuracy : values()) {
public static SmartRateAccuracy getByKeyName(String keyName) throws EasyPostException {
for (SmartRateAccuracy smartrateAccuracy : values()) {
if (smartrateAccuracy.getKeyName().equals(keyName)) {
return smartrateAccuracy;
}
Expand Down
51 changes: 51 additions & 0 deletions src/main/java/com/easypost/model/SmartRateCollection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.easypost.model;

import java.util.ArrayList;
import java.util.List;

public final class SmartRateCollection {
private List<SmartRate> smartRates;

/**
* Get this SmartRateCollection's Smartrate objects.
*
* @return List of Smartrate objects.
*/
public List<SmartRate> getSmartRates() {
return this.smartRates;
}

/**
* Set this SmartRateCollection's Smartrate objects.
*
* @param smartRates List of Smartrate objects.
*/
public void setSmartRates(final List<SmartRate> smartRates) {
this.smartRates = smartRates;
}

/**
* Constructor.
*/
public SmartRateCollection() {
this.smartRates = new ArrayList<SmartRate>();
}

/**
* Create a SmartRateCollection from a list of rates.
*
* @param smartRates List of Smartrate objects
*/
public SmartRateCollection(final List<SmartRate> smartRates) {
setSmartRates(smartRates);
}

/**
* Add a SmartRate object to this SmartRateCollection.
*
* @param rate Rate object
*/
public void addRate(final SmartRate rate) {
smartRates.add(rate);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,29 @@

import java.lang.reflect.Type;

public final class SmartrateCollectionDeserializer implements JsonDeserializer<SmartrateCollection> {
public final class SmartRateCollectionDeserializer implements JsonDeserializer<SmartRateCollection> {
/**
* Deserialize a SmartrateCollection from a JSON object.
* Deserialize a SmartRateCollection from a JSON object.
*
* @param json JSON object to deserialize.
* @param typeOfT Type of the object to deserialize.
* @param context Deserialization context.
* @return Deserialized SmartrateCollection object.
* @throws JsonParseException if the JSON object is not a valid SmartrateCollection.
* @return Deserialized SmartRateCollection object.
* @throws JsonParseException if the JSON object is not a valid
* SmartRateCollection.
*/
@Override
public SmartrateCollection deserialize(final JsonElement json, final Type typeOfT,
final JsonDeserializationContext context) throws JsonParseException {
SmartrateCollection smartrateCollection = new SmartrateCollection();
public SmartRateCollection deserialize(final JsonElement json, final Type typeOfT,
final JsonDeserializationContext context) throws JsonParseException {
SmartRateCollection smartrateCollection = new SmartRateCollection();

JsonObject jo = (JsonObject) json;
JsonElement results = jo.get("result");

if (results == null || !results.isJsonArray()) {
return smartrateCollection;
// return empty collection if "results" key does not exist or corresponding value is not an array
// return empty collection if "results" key does not exist or corresponding
// value is not an array
}
// the JsonDeserializationContext should have access to the other type adapters,
// so we can tap into the RateDeserializer from here
Expand Down
Loading
Loading