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
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ This optional parameter allows you to define some default behavior of the api:
| rememberMe | *boolean* | Determines whether or not to store the credentials/session in the datastore | `true` |
| timeout | *number* | The length of time the wrapper will wait for a response from the server (in seconds) | `3` |
| newCredentialStore | *object* | Overrides the default datastore for remembered credentials/sessions | `false` |
| fullResponse | *boolean* | Removes error handling and provides full [Axios Response Object](https://github.com/axios/axios#response-schema). More information in the **Axios Response section** | `false` |
| fullResponse | *boolean* | Removes error handling and provides the full [Http Server Response](https://nodejs.org/api/http.html#class-httpserverresponse) when in a node environment or the full [Fetch Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) when in a browser environment. More information in the **Full Response** section | `false` |

Example options object:

Expand All @@ -111,7 +111,7 @@ At minimum, the datastore must have the following methods:

## Methods

By default, all methods and callbacks will return the results of the call directly. Errors are also handled by the wrapper. If you need more control over the call results, see the **Axios Response** section below.
By default, all methods and callbacks will return the results of the call directly. Errors are also handled by the wrapper. If you need more control over the call results, see the **Full Response** section below.

```javascript
api.call('Get', { typeName: 'Device', resultsLimit: 100 })
Expand Down Expand Up @@ -143,7 +143,7 @@ function callbackError(message, error){
console.log(error.data);
}
```
For more information on the error JSON structure returned from MyGeotab API, see [here](https://geotab.github.io/sdk/software/guides/concepts/#results-and-errors).
For more information on the error JSON structure returned from MyGeotab API, see [here](https://developers.geotab.com/myGeotab/guides/concepts#result-and-errors).

Note: `error` parameter in a `.catch` statement always returns an instance of `Error`.

Expand Down Expand Up @@ -269,9 +269,9 @@ api.getSession(function (result) {
});
```

## Axios Responses
## Full Responses
**Note:** *This will disable all error checking in the GeotabApi wrapper*
In an effort to give you more control over the actual responses, the wrapper can be configured to return an [Axios Response Object](https://github.com/axios/axios#response-schema). This object contains several bits of information about the request and it's response. Response data will be held in the `data` section of the response.
In an effort to give you more control over the actual responses, the wrapper can be configured to return the full [Http Server Response](https://nodejs.org/api/http.html#class-httpserverresponse) when in a node environment and the full [Fetch Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) when in a browser environment. This object contains several bits of information about the request and it's response. Response data will be held in the `data` section of the response.

To enable full response data, simply add the `fullResponse: true` to the options object when constructing the `GeotabApi` object:
```javascript
Expand All @@ -286,7 +286,7 @@ If the call to the database is successful, but there is an error with the call i

```javascript
api.call('Get', {typeName: 'Device', resultsLimit: 10})
.then( response => response.data ) // response is the Axios response object
.then( response => response.data ) // response is the full http/fetch response object
.then( data => {
// This is the server response
data.result; // The successful Call - device information
Expand All @@ -299,6 +299,8 @@ api.call('Get', {typeName: 'Device', resultsLimit: 10})

As of v2.0.0, there are several noteable changes that will cause previous implementations of the api wrapper to fail.

As of v3.0.0, Axios is no longer being used to make requests and the `fullResponse` option no longer returns an [Axios Response Object](https://github.com/axios/axios#response-schema), refer to the **Full Response** section for more detail.

#### GeotabApi credential callback

Using a credentials callback to instantiate `GeotabApi` is no longer an option. All credentials must be passed as an authentication object described above
Expand Down
2 changes: 1 addition & 1 deletion dist/api.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/api.min.js.map

Large diffs are not rendered by default.

52 changes: 26 additions & 26 deletions lib/ApiHelper.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const LocalStorageCredentialStore = require('./LocalStorageCredentialStore.js').default;
const AxiosCall = require('./AxiosCall.js').default;
const HttpCall = require('./HttpCall.js').default;

/**
* Helper method for GeotabApi.
Expand Down Expand Up @@ -121,12 +121,12 @@ class ApiHelper {
/**
* When the user doesn't have fullResposne enabled, we put some promises in front of the call
* to return only data.result to the user
* @param {Promise} call Axios call
* @param {Promise} call Http call
*/
parseAxiosResponse(call) {
parseHttpResponse(call) {
return call
.then(response => {
// Error handling has already taken errors out in either errorHandle() or AxiosCall.send()
// Error handling has already taken errors out in either errorHandle() or HttpCall.send()
if (response.data.result) {
return response.data.result;
}
Expand All @@ -136,40 +136,40 @@ class ApiHelper {

/**
* Error handling - only called if fullresponse isn't enabled, and if the user hasn't provided a callback
* @param {Promise} call Axios call
* @param {Promise} call Http call
* @param {function} callbackError Optional callback for unsuccessful calls
*/
errorHandle(call, callbackError) {
// User hasn't asked for the full axios object, so we should error check
function dispatchError(message, errorDetails) {
let error = new Error(message);
if (callbackError) {
callbackError(error.toString(), errorDetails || error);
} else {
throw error;
}
}
// User hasn't asked for the full http object, so we should error check
return call
.then(response => {
if (response.status !== 200) {
let error = new Error(`Response ${response.status} - ${response.statusText}`);

if (callbackError) {
callbackError(error.toString(), error);
} else {
throw error;
}
if (response.status && response.status !== 200) {
dispatchError(`Response ${response.status} - ${response.statusText}`, null);
}
// node http/https returns a different response schema
if (response.statusCode && response.statusCode !== 200) {
dispatchError(`Response ${response.statusCode} - ${response.statusMessage}`, null);
}
return response;
})
.then(response => {
if (response.data.error) {
let error = new Error(`${response.data.error.data.type}: ${response.data.error.message}`);

if (callbackError) {
callbackError(error.toString(), response.data.error);
} else {
throw error;
}
if (response.data && response.data.error) {
dispatchError(`${response.data.error.data.type}: ${response.data.error.message}`, response.data.error);
}
return response;
});
}

/**
* Creates a new AxiosCall and returns it to the user. If the call fails,
* Creates a new HttpCall and returns it to the user. If the call fails,
* and the call isn't an authentication, the call will attempt to
* refresh the credentials
*
Expand All @@ -180,8 +180,8 @@ class ApiHelper {
* @param {function} authenticate authentication function. Context binded to GeotabApi
* @param {boolean} rememberMe should store authentication results
*/
async sendAxiosCall(method, params, callbackSuccess, callbackError, authenticate, rememberMe) {
let call = new AxiosCall(method, this.server, params, callbackSuccess).send(this.options.timeout);
async sendHttpCall(method, params, callbackSuccess, callbackError, authenticate, rememberMe) {
let call = new HttpCall(method, this.server, params, callbackSuccess).send(this.options.timeout);
// We don't want to continue retrying if we fail authentication
if (method !== 'Authenticate') {
call = call.then(async response => {
Expand All @@ -196,7 +196,7 @@ class ApiHelper {
.then(auth => {
params.credentials = auth;
});
return new AxiosCall(method, this.server, params, callbackSuccess).send(this.options.timeout);
return new HttpCall(method, this.server, params, callbackSuccess).send(this.options.timeout);
}
}
return response;
Expand Down
65 changes: 0 additions & 65 deletions lib/AxiosCall.js

This file was deleted.

38 changes: 18 additions & 20 deletions lib/GeotabApi.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
const { AxiosError } = require('axios');

const ApiHelper = require('./ApiHelper.js').default;

/**
Expand Down Expand Up @@ -27,12 +25,12 @@ class GeotabApi {
}

/**
* Authenticates the user against the server. Gets the sessionId and other relevant session information
*
* @param {function} callbackSuccess optional callback for successful authentications
* @param {function} callbackError optional callback for unsuccessful authentications
* @returns {promise} Call promise - result will be either response.data.error or response.data.result
*/
* Authenticates the user against the server. Gets the sessionId and other relevant session information
*
* @param {function} callbackSuccess optional callback for successful authentications
* @param {function} callbackError optional callback for unsuccessful authentications
* @returns {promise} Call promise - result will be either response.data.error or response.data.result
*/
async authenticate(callbackSuccess, callbackError) {
if (callbackSuccess && !callbackError) {
throw new Error(`If callbackSuccess is supplied so must callbackError`);
Expand All @@ -52,14 +50,14 @@ class GeotabApi {
}

/**
* Constructs an API call to MyGeotab
*
* @param {string} method method name for the API call
* @param {Object} params method's parameters
* @param {function} callbackSuccess Optional callback for successful calls
* @param {function} callbackError Optional callback for unsuccessful calls
* @returns {promise} an axios promise which will resolve to either data.error or data.result
*/
* Constructs an API call to MyGeotab
*
* @param {string} method method name for the API call
* @param {Object} params method's parameters
* @param {function} callbackSuccess Optional callback for successful calls
* @param {function} callbackError Optional callback for unsuccessful calls
* @returns {promise} an http/fetch promise which will resolve to either data.error or data.result
*/
async call(method, params, callbackSuccess, callbackError) {
if (callbackSuccess && !callbackError) {
throw new Error(`If callbackSuccess is supplied so must callbackError`);
Expand All @@ -79,7 +77,7 @@ class GeotabApi {
* @param {Object} params method's parameters
* @param {function} callbackSuccess Optional callback for successful calls
* @param {function} callbackError Optional callback for unsuccessful calls
* @returns {promise} an axios promise which will resolve to either data.error or data.result
* @returns {promise} an http/fetch promise which will resolve to either data.error or data.result
*/
async callimpl(method, params, callbackSuccess, callbackError) {
// Defining our credentials
Expand Down Expand Up @@ -110,11 +108,11 @@ class GeotabApi {
});
}
// Creating the actual call
let call = this._helper.sendAxiosCall(method, params, callbackSuccess, callbackError, this.authenticate, this._helper.rememberMe);
// Seeing if the user wants the axios response object, or default error handling
let call = this._helper.sendHttpCall(method, params, callbackSuccess, callbackError, this.authenticate, this._helper.rememberMe);
// Seeing if the user wants the full response object, or default error handling
if (!this._helper.fullResponse) {
call = this._helper.errorHandle(call, callbackError);
call = this._helper.parseAxiosResponse(call);
call = this._helper.parseHttpResponse(call);
}
// Returning call to user
return call;
Expand Down
Loading