@commercetools/ts-client 2.0.0 → 2.0.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.
- package/CHANGELOG.md +6 -0
- package/dist/commercetools-ts-client.browser.cjs.js +55 -17
- package/dist/commercetools-ts-client.browser.esm.js +55 -17
- package/dist/commercetools-ts-client.cjs.dev.js +55 -17
- package/dist/commercetools-ts-client.cjs.prod.js +55 -17
- package/dist/commercetools-ts-client.esm.js +55 -17
- package/dist/declarations/src/types/types.d.ts +2 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @commercetools/ts-client
|
|
2
2
|
|
|
3
|
+
## 2.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#767](https://github.com/commercetools/commercetools-sdk-typescript/pull/767) [`d82a9e0`](https://github.com/commercetools/commercetools-sdk-typescript/commit/d82a9e0e6666e076183172a9229ffcda8e28905a) Thanks [@ajimae](https://github.com/ajimae)! - Fix issues with request state not being reset back to default on error when fetching token.
|
|
8
|
+
|
|
3
9
|
## 2.0.0
|
|
4
10
|
|
|
5
11
|
### Major Changes
|
|
@@ -121,10 +121,11 @@ function createError({
|
|
|
121
121
|
return new HttpError(statusCode, errorMessage, rest);
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
function
|
|
125
|
-
return
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
function hasResponseRetryCode(retryCodes, response) {
|
|
125
|
+
return (
|
|
126
|
+
// retryCodes.includes(response?.error?.message) ||
|
|
127
|
+
[503, ...retryCodes].includes(response?.status || response?.statusCode)
|
|
128
|
+
);
|
|
128
129
|
}
|
|
129
130
|
async function executeHttpClientRequest(fetcher, config) {
|
|
130
131
|
async function sendRequest() {
|
|
@@ -151,14 +152,17 @@ async function executor(request) {
|
|
|
151
152
|
const data = await executeHttpClientRequest(async options => {
|
|
152
153
|
const {
|
|
153
154
|
enableRetry,
|
|
154
|
-
retryConfig
|
|
155
|
+
retryConfig,
|
|
156
|
+
abortController
|
|
155
157
|
} = rest;
|
|
156
158
|
const {
|
|
157
159
|
retryCodes = [],
|
|
158
160
|
maxDelay = Infinity,
|
|
159
161
|
maxRetries = 3,
|
|
160
162
|
backoff = true,
|
|
161
|
-
retryDelay = 200
|
|
163
|
+
retryDelay = 200,
|
|
164
|
+
// If set to true reinitialize the abort controller when the timeout is reached and apply the retry config
|
|
165
|
+
retryOnAbort = true
|
|
162
166
|
} = retryConfig || {};
|
|
163
167
|
let result,
|
|
164
168
|
data,
|
|
@@ -184,15 +188,41 @@ async function executor(request) {
|
|
|
184
188
|
});
|
|
185
189
|
}
|
|
186
190
|
async function executeWithRetry() {
|
|
191
|
+
const executeWithTryCatch = async (retryCodes, retryWhenAborted) => {
|
|
192
|
+
let _response = {};
|
|
193
|
+
try {
|
|
194
|
+
_response = await execute();
|
|
195
|
+
if (_response.status > 299 && hasResponseRetryCode(retryCodes, _response)) return {
|
|
196
|
+
_response,
|
|
197
|
+
shouldRetry: true
|
|
198
|
+
};
|
|
199
|
+
} catch (e) {
|
|
200
|
+
if (e.name.includes('AbortError') && retryWhenAborted) {
|
|
201
|
+
return {
|
|
202
|
+
_response: e,
|
|
203
|
+
shouldRetry: true
|
|
204
|
+
};
|
|
205
|
+
} else {
|
|
206
|
+
throw e;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
_response,
|
|
211
|
+
shouldRetry: false
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
const retryWhenAborted = retryOnAbort || !abortController || !abortController.signal;
|
|
187
215
|
// first attempt
|
|
188
|
-
let
|
|
189
|
-
|
|
190
|
-
|
|
216
|
+
let {
|
|
217
|
+
_response,
|
|
218
|
+
shouldRetry
|
|
219
|
+
} = await executeWithTryCatch(retryCodes, retryWhenAborted);
|
|
191
220
|
// retry attempts
|
|
192
|
-
while (enableRetry && retryCount < maxRetries) {
|
|
221
|
+
while (enableRetry && shouldRetry && retryCount < maxRetries) {
|
|
193
222
|
retryCount++;
|
|
194
|
-
|
|
195
|
-
|
|
223
|
+
const execution = await executeWithTryCatch(retryCodes, retryWhenAborted);
|
|
224
|
+
_response = execution._response;
|
|
225
|
+
shouldRetry = execution.shouldRetry;
|
|
196
226
|
|
|
197
227
|
// delay next execution
|
|
198
228
|
const timer = calculateRetryDelay({
|
|
@@ -432,7 +462,6 @@ function createUserAgent(options) {
|
|
|
432
462
|
function validateHttpOptions(options) {
|
|
433
463
|
if (!options.host) throw new Error('Request `host` or `url` is missing or invalid, please pass in a valid host e.g `host: http://a-valid-host-url`');
|
|
434
464
|
if (!options.httpClient && typeof options.httpClient !== 'function') throw new Error('An `httpClient` is not available, please pass in a `fetch` or `axios` instance as an option or have them globally available.');
|
|
435
|
-
if (options.timeout && !options.getAbortController) throw new Error('`AbortController` is not available. Please pass in `getAbortController` as an option or have AbortController globally available when using timeout.');
|
|
436
465
|
}
|
|
437
466
|
|
|
438
467
|
/**
|
|
@@ -638,7 +667,10 @@ async function executeRequest$1(options) {
|
|
|
638
667
|
* and there's either no token or the token is expired
|
|
639
668
|
*/
|
|
640
669
|
if (tokenCacheObject && tokenCacheObject.refreshToken && (!tokenCacheObject.token || tokenCacheObject.token && Date.now() > tokenCacheObject.expirationTime)) {
|
|
641
|
-
if (!userOption)
|
|
670
|
+
if (!userOption) {
|
|
671
|
+
requestState.set(false);
|
|
672
|
+
throw new Error('Missing required options.');
|
|
673
|
+
}
|
|
642
674
|
const opt = {
|
|
643
675
|
...buildRequestForRefreshTokenFlow({
|
|
644
676
|
...userOption,
|
|
@@ -711,8 +743,10 @@ async function executeRequest$1(options) {
|
|
|
711
743
|
const error = new Error(response.data.message ? response.data.message : JSON.stringify(response.data));
|
|
712
744
|
/**
|
|
713
745
|
* reject the error immediately
|
|
714
|
-
* and free up the middleware chain
|
|
746
|
+
* and free up the middleware chain and
|
|
747
|
+
* release the requestState by setting it to false
|
|
715
748
|
*/
|
|
749
|
+
requestState.set(false);
|
|
716
750
|
request.reject({
|
|
717
751
|
...request,
|
|
718
752
|
headers: {
|
|
@@ -727,6 +761,10 @@ async function executeRequest$1(options) {
|
|
|
727
761
|
}
|
|
728
762
|
});
|
|
729
763
|
} catch (error) {
|
|
764
|
+
/**
|
|
765
|
+
* on error release the state by setting it to false
|
|
766
|
+
*/
|
|
767
|
+
requestState.set(false);
|
|
730
768
|
return {
|
|
731
769
|
...request,
|
|
732
770
|
headers: {
|
|
@@ -1224,7 +1262,7 @@ function createQueueMiddleware$1({
|
|
|
1224
1262
|
|
|
1225
1263
|
var packageJson = {
|
|
1226
1264
|
name: "@commercetools/ts-client",
|
|
1227
|
-
version: "2.0.
|
|
1265
|
+
version: "2.0.1",
|
|
1228
1266
|
engines: {
|
|
1229
1267
|
node: ">=14"
|
|
1230
1268
|
},
|
|
@@ -1260,7 +1298,7 @@ var packageJson = {
|
|
|
1260
1298
|
"abort-controller": "3.0.0",
|
|
1261
1299
|
buffer: "^6.0.3",
|
|
1262
1300
|
"node-fetch": "^2.6.1",
|
|
1263
|
-
uuid: "
|
|
1301
|
+
uuid: "10.0.0"
|
|
1264
1302
|
},
|
|
1265
1303
|
files: [
|
|
1266
1304
|
"dist",
|
|
@@ -112,10 +112,11 @@ function createError({
|
|
|
112
112
|
return new HttpError(statusCode, errorMessage, rest);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
function
|
|
116
|
-
return
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
function hasResponseRetryCode(retryCodes, response) {
|
|
116
|
+
return (
|
|
117
|
+
// retryCodes.includes(response?.error?.message) ||
|
|
118
|
+
[503, ...retryCodes].includes(response?.status || response?.statusCode)
|
|
119
|
+
);
|
|
119
120
|
}
|
|
120
121
|
async function executeHttpClientRequest(fetcher, config) {
|
|
121
122
|
async function sendRequest() {
|
|
@@ -142,14 +143,17 @@ async function executor(request) {
|
|
|
142
143
|
const data = await executeHttpClientRequest(async options => {
|
|
143
144
|
const {
|
|
144
145
|
enableRetry,
|
|
145
|
-
retryConfig
|
|
146
|
+
retryConfig,
|
|
147
|
+
abortController
|
|
146
148
|
} = rest;
|
|
147
149
|
const {
|
|
148
150
|
retryCodes = [],
|
|
149
151
|
maxDelay = Infinity,
|
|
150
152
|
maxRetries = 3,
|
|
151
153
|
backoff = true,
|
|
152
|
-
retryDelay = 200
|
|
154
|
+
retryDelay = 200,
|
|
155
|
+
// If set to true reinitialize the abort controller when the timeout is reached and apply the retry config
|
|
156
|
+
retryOnAbort = true
|
|
153
157
|
} = retryConfig || {};
|
|
154
158
|
let result,
|
|
155
159
|
data,
|
|
@@ -175,15 +179,41 @@ async function executor(request) {
|
|
|
175
179
|
});
|
|
176
180
|
}
|
|
177
181
|
async function executeWithRetry() {
|
|
182
|
+
const executeWithTryCatch = async (retryCodes, retryWhenAborted) => {
|
|
183
|
+
let _response = {};
|
|
184
|
+
try {
|
|
185
|
+
_response = await execute();
|
|
186
|
+
if (_response.status > 299 && hasResponseRetryCode(retryCodes, _response)) return {
|
|
187
|
+
_response,
|
|
188
|
+
shouldRetry: true
|
|
189
|
+
};
|
|
190
|
+
} catch (e) {
|
|
191
|
+
if (e.name.includes('AbortError') && retryWhenAborted) {
|
|
192
|
+
return {
|
|
193
|
+
_response: e,
|
|
194
|
+
shouldRetry: true
|
|
195
|
+
};
|
|
196
|
+
} else {
|
|
197
|
+
throw e;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
_response,
|
|
202
|
+
shouldRetry: false
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
const retryWhenAborted = retryOnAbort || !abortController || !abortController.signal;
|
|
178
206
|
// first attempt
|
|
179
|
-
let
|
|
180
|
-
|
|
181
|
-
|
|
207
|
+
let {
|
|
208
|
+
_response,
|
|
209
|
+
shouldRetry
|
|
210
|
+
} = await executeWithTryCatch(retryCodes, retryWhenAborted);
|
|
182
211
|
// retry attempts
|
|
183
|
-
while (enableRetry && retryCount < maxRetries) {
|
|
212
|
+
while (enableRetry && shouldRetry && retryCount < maxRetries) {
|
|
184
213
|
retryCount++;
|
|
185
|
-
|
|
186
|
-
|
|
214
|
+
const execution = await executeWithTryCatch(retryCodes, retryWhenAborted);
|
|
215
|
+
_response = execution._response;
|
|
216
|
+
shouldRetry = execution.shouldRetry;
|
|
187
217
|
|
|
188
218
|
// delay next execution
|
|
189
219
|
const timer = calculateRetryDelay({
|
|
@@ -423,7 +453,6 @@ function createUserAgent(options) {
|
|
|
423
453
|
function validateHttpOptions(options) {
|
|
424
454
|
if (!options.host) throw new Error('Request `host` or `url` is missing or invalid, please pass in a valid host e.g `host: http://a-valid-host-url`');
|
|
425
455
|
if (!options.httpClient && typeof options.httpClient !== 'function') throw new Error('An `httpClient` is not available, please pass in a `fetch` or `axios` instance as an option or have them globally available.');
|
|
426
|
-
if (options.timeout && !options.getAbortController) throw new Error('`AbortController` is not available. Please pass in `getAbortController` as an option or have AbortController globally available when using timeout.');
|
|
427
456
|
}
|
|
428
457
|
|
|
429
458
|
/**
|
|
@@ -629,7 +658,10 @@ async function executeRequest$1(options) {
|
|
|
629
658
|
* and there's either no token or the token is expired
|
|
630
659
|
*/
|
|
631
660
|
if (tokenCacheObject && tokenCacheObject.refreshToken && (!tokenCacheObject.token || tokenCacheObject.token && Date.now() > tokenCacheObject.expirationTime)) {
|
|
632
|
-
if (!userOption)
|
|
661
|
+
if (!userOption) {
|
|
662
|
+
requestState.set(false);
|
|
663
|
+
throw new Error('Missing required options.');
|
|
664
|
+
}
|
|
633
665
|
const opt = {
|
|
634
666
|
...buildRequestForRefreshTokenFlow({
|
|
635
667
|
...userOption,
|
|
@@ -702,8 +734,10 @@ async function executeRequest$1(options) {
|
|
|
702
734
|
const error = new Error(response.data.message ? response.data.message : JSON.stringify(response.data));
|
|
703
735
|
/**
|
|
704
736
|
* reject the error immediately
|
|
705
|
-
* and free up the middleware chain
|
|
737
|
+
* and free up the middleware chain and
|
|
738
|
+
* release the requestState by setting it to false
|
|
706
739
|
*/
|
|
740
|
+
requestState.set(false);
|
|
707
741
|
request.reject({
|
|
708
742
|
...request,
|
|
709
743
|
headers: {
|
|
@@ -718,6 +752,10 @@ async function executeRequest$1(options) {
|
|
|
718
752
|
}
|
|
719
753
|
});
|
|
720
754
|
} catch (error) {
|
|
755
|
+
/**
|
|
756
|
+
* on error release the state by setting it to false
|
|
757
|
+
*/
|
|
758
|
+
requestState.set(false);
|
|
721
759
|
return {
|
|
722
760
|
...request,
|
|
723
761
|
headers: {
|
|
@@ -1215,7 +1253,7 @@ function createQueueMiddleware$1({
|
|
|
1215
1253
|
|
|
1216
1254
|
var packageJson = {
|
|
1217
1255
|
name: "@commercetools/ts-client",
|
|
1218
|
-
version: "2.0.
|
|
1256
|
+
version: "2.0.1",
|
|
1219
1257
|
engines: {
|
|
1220
1258
|
node: ">=14"
|
|
1221
1259
|
},
|
|
@@ -1251,7 +1289,7 @@ var packageJson = {
|
|
|
1251
1289
|
"abort-controller": "3.0.0",
|
|
1252
1290
|
buffer: "^6.0.3",
|
|
1253
1291
|
"node-fetch": "^2.6.1",
|
|
1254
|
-
uuid: "
|
|
1292
|
+
uuid: "10.0.0"
|
|
1255
1293
|
},
|
|
1256
1294
|
files: [
|
|
1257
1295
|
"dist",
|
|
@@ -121,10 +121,11 @@ function createError({
|
|
|
121
121
|
return new HttpError(statusCode, errorMessage, rest);
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
function
|
|
125
|
-
return
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
function hasResponseRetryCode(retryCodes, response) {
|
|
125
|
+
return (
|
|
126
|
+
// retryCodes.includes(response?.error?.message) ||
|
|
127
|
+
[503, ...retryCodes].includes(response?.status || response?.statusCode)
|
|
128
|
+
);
|
|
128
129
|
}
|
|
129
130
|
async function executeHttpClientRequest(fetcher, config) {
|
|
130
131
|
async function sendRequest() {
|
|
@@ -151,14 +152,17 @@ async function executor(request) {
|
|
|
151
152
|
const data = await executeHttpClientRequest(async options => {
|
|
152
153
|
const {
|
|
153
154
|
enableRetry,
|
|
154
|
-
retryConfig
|
|
155
|
+
retryConfig,
|
|
156
|
+
abortController
|
|
155
157
|
} = rest;
|
|
156
158
|
const {
|
|
157
159
|
retryCodes = [],
|
|
158
160
|
maxDelay = Infinity,
|
|
159
161
|
maxRetries = 3,
|
|
160
162
|
backoff = true,
|
|
161
|
-
retryDelay = 200
|
|
163
|
+
retryDelay = 200,
|
|
164
|
+
// If set to true reinitialize the abort controller when the timeout is reached and apply the retry config
|
|
165
|
+
retryOnAbort = true
|
|
162
166
|
} = retryConfig || {};
|
|
163
167
|
let result,
|
|
164
168
|
data,
|
|
@@ -184,15 +188,41 @@ async function executor(request) {
|
|
|
184
188
|
});
|
|
185
189
|
}
|
|
186
190
|
async function executeWithRetry() {
|
|
191
|
+
const executeWithTryCatch = async (retryCodes, retryWhenAborted) => {
|
|
192
|
+
let _response = {};
|
|
193
|
+
try {
|
|
194
|
+
_response = await execute();
|
|
195
|
+
if (_response.status > 299 && hasResponseRetryCode(retryCodes, _response)) return {
|
|
196
|
+
_response,
|
|
197
|
+
shouldRetry: true
|
|
198
|
+
};
|
|
199
|
+
} catch (e) {
|
|
200
|
+
if (e.name.includes('AbortError') && retryWhenAborted) {
|
|
201
|
+
return {
|
|
202
|
+
_response: e,
|
|
203
|
+
shouldRetry: true
|
|
204
|
+
};
|
|
205
|
+
} else {
|
|
206
|
+
throw e;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
_response,
|
|
211
|
+
shouldRetry: false
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
const retryWhenAborted = retryOnAbort || !abortController || !abortController.signal;
|
|
187
215
|
// first attempt
|
|
188
|
-
let
|
|
189
|
-
|
|
190
|
-
|
|
216
|
+
let {
|
|
217
|
+
_response,
|
|
218
|
+
shouldRetry
|
|
219
|
+
} = await executeWithTryCatch(retryCodes, retryWhenAborted);
|
|
191
220
|
// retry attempts
|
|
192
|
-
while (enableRetry && retryCount < maxRetries) {
|
|
221
|
+
while (enableRetry && shouldRetry && retryCount < maxRetries) {
|
|
193
222
|
retryCount++;
|
|
194
|
-
|
|
195
|
-
|
|
223
|
+
const execution = await executeWithTryCatch(retryCodes, retryWhenAborted);
|
|
224
|
+
_response = execution._response;
|
|
225
|
+
shouldRetry = execution.shouldRetry;
|
|
196
226
|
|
|
197
227
|
// delay next execution
|
|
198
228
|
const timer = calculateRetryDelay({
|
|
@@ -432,7 +462,6 @@ function createUserAgent(options) {
|
|
|
432
462
|
function validateHttpOptions(options) {
|
|
433
463
|
if (!options.host) throw new Error('Request `host` or `url` is missing or invalid, please pass in a valid host e.g `host: http://a-valid-host-url`');
|
|
434
464
|
if (!options.httpClient && typeof options.httpClient !== 'function') throw new Error('An `httpClient` is not available, please pass in a `fetch` or `axios` instance as an option or have them globally available.');
|
|
435
|
-
if (options.timeout && !options.getAbortController) throw new Error('`AbortController` is not available. Please pass in `getAbortController` as an option or have AbortController globally available when using timeout.');
|
|
436
465
|
}
|
|
437
466
|
|
|
438
467
|
/**
|
|
@@ -638,7 +667,10 @@ async function executeRequest$1(options) {
|
|
|
638
667
|
* and there's either no token or the token is expired
|
|
639
668
|
*/
|
|
640
669
|
if (tokenCacheObject && tokenCacheObject.refreshToken && (!tokenCacheObject.token || tokenCacheObject.token && Date.now() > tokenCacheObject.expirationTime)) {
|
|
641
|
-
if (!userOption)
|
|
670
|
+
if (!userOption) {
|
|
671
|
+
requestState.set(false);
|
|
672
|
+
throw new Error('Missing required options.');
|
|
673
|
+
}
|
|
642
674
|
const opt = {
|
|
643
675
|
...buildRequestForRefreshTokenFlow({
|
|
644
676
|
...userOption,
|
|
@@ -711,8 +743,10 @@ async function executeRequest$1(options) {
|
|
|
711
743
|
const error = new Error(response.data.message ? response.data.message : JSON.stringify(response.data));
|
|
712
744
|
/**
|
|
713
745
|
* reject the error immediately
|
|
714
|
-
* and free up the middleware chain
|
|
746
|
+
* and free up the middleware chain and
|
|
747
|
+
* release the requestState by setting it to false
|
|
715
748
|
*/
|
|
749
|
+
requestState.set(false);
|
|
716
750
|
request.reject({
|
|
717
751
|
...request,
|
|
718
752
|
headers: {
|
|
@@ -727,6 +761,10 @@ async function executeRequest$1(options) {
|
|
|
727
761
|
}
|
|
728
762
|
});
|
|
729
763
|
} catch (error) {
|
|
764
|
+
/**
|
|
765
|
+
* on error release the state by setting it to false
|
|
766
|
+
*/
|
|
767
|
+
requestState.set(false);
|
|
730
768
|
return {
|
|
731
769
|
...request,
|
|
732
770
|
headers: {
|
|
@@ -1224,7 +1262,7 @@ function createQueueMiddleware$1({
|
|
|
1224
1262
|
|
|
1225
1263
|
var packageJson = {
|
|
1226
1264
|
name: "@commercetools/ts-client",
|
|
1227
|
-
version: "2.0.
|
|
1265
|
+
version: "2.0.1",
|
|
1228
1266
|
engines: {
|
|
1229
1267
|
node: ">=14"
|
|
1230
1268
|
},
|
|
@@ -1260,7 +1298,7 @@ var packageJson = {
|
|
|
1260
1298
|
"abort-controller": "3.0.0",
|
|
1261
1299
|
buffer: "^6.0.3",
|
|
1262
1300
|
"node-fetch": "^2.6.1",
|
|
1263
|
-
uuid: "
|
|
1301
|
+
uuid: "10.0.0"
|
|
1264
1302
|
},
|
|
1265
1303
|
files: [
|
|
1266
1304
|
"dist",
|
|
@@ -121,10 +121,11 @@ function createError({
|
|
|
121
121
|
return new HttpError(statusCode, errorMessage, rest);
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
function
|
|
125
|
-
return
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
function hasResponseRetryCode(retryCodes, response) {
|
|
125
|
+
return (
|
|
126
|
+
// retryCodes.includes(response?.error?.message) ||
|
|
127
|
+
[503, ...retryCodes].includes(response?.status || response?.statusCode)
|
|
128
|
+
);
|
|
128
129
|
}
|
|
129
130
|
async function executeHttpClientRequest(fetcher, config) {
|
|
130
131
|
async function sendRequest() {
|
|
@@ -151,14 +152,17 @@ async function executor(request) {
|
|
|
151
152
|
const data = await executeHttpClientRequest(async options => {
|
|
152
153
|
const {
|
|
153
154
|
enableRetry,
|
|
154
|
-
retryConfig
|
|
155
|
+
retryConfig,
|
|
156
|
+
abortController
|
|
155
157
|
} = rest;
|
|
156
158
|
const {
|
|
157
159
|
retryCodes = [],
|
|
158
160
|
maxDelay = Infinity,
|
|
159
161
|
maxRetries = 3,
|
|
160
162
|
backoff = true,
|
|
161
|
-
retryDelay = 200
|
|
163
|
+
retryDelay = 200,
|
|
164
|
+
// If set to true reinitialize the abort controller when the timeout is reached and apply the retry config
|
|
165
|
+
retryOnAbort = true
|
|
162
166
|
} = retryConfig || {};
|
|
163
167
|
let result,
|
|
164
168
|
data,
|
|
@@ -184,15 +188,41 @@ async function executor(request) {
|
|
|
184
188
|
});
|
|
185
189
|
}
|
|
186
190
|
async function executeWithRetry() {
|
|
191
|
+
const executeWithTryCatch = async (retryCodes, retryWhenAborted) => {
|
|
192
|
+
let _response = {};
|
|
193
|
+
try {
|
|
194
|
+
_response = await execute();
|
|
195
|
+
if (_response.status > 299 && hasResponseRetryCode(retryCodes, _response)) return {
|
|
196
|
+
_response,
|
|
197
|
+
shouldRetry: true
|
|
198
|
+
};
|
|
199
|
+
} catch (e) {
|
|
200
|
+
if (e.name.includes('AbortError') && retryWhenAborted) {
|
|
201
|
+
return {
|
|
202
|
+
_response: e,
|
|
203
|
+
shouldRetry: true
|
|
204
|
+
};
|
|
205
|
+
} else {
|
|
206
|
+
throw e;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
_response,
|
|
211
|
+
shouldRetry: false
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
const retryWhenAborted = retryOnAbort || !abortController || !abortController.signal;
|
|
187
215
|
// first attempt
|
|
188
|
-
let
|
|
189
|
-
|
|
190
|
-
|
|
216
|
+
let {
|
|
217
|
+
_response,
|
|
218
|
+
shouldRetry
|
|
219
|
+
} = await executeWithTryCatch(retryCodes, retryWhenAborted);
|
|
191
220
|
// retry attempts
|
|
192
|
-
while (enableRetry && retryCount < maxRetries) {
|
|
221
|
+
while (enableRetry && shouldRetry && retryCount < maxRetries) {
|
|
193
222
|
retryCount++;
|
|
194
|
-
|
|
195
|
-
|
|
223
|
+
const execution = await executeWithTryCatch(retryCodes, retryWhenAborted);
|
|
224
|
+
_response = execution._response;
|
|
225
|
+
shouldRetry = execution.shouldRetry;
|
|
196
226
|
|
|
197
227
|
// delay next execution
|
|
198
228
|
const timer = calculateRetryDelay({
|
|
@@ -432,7 +462,6 @@ function createUserAgent(options) {
|
|
|
432
462
|
function validateHttpOptions(options) {
|
|
433
463
|
if (!options.host) throw new Error('Request `host` or `url` is missing or invalid, please pass in a valid host e.g `host: http://a-valid-host-url`');
|
|
434
464
|
if (!options.httpClient && typeof options.httpClient !== 'function') throw new Error('An `httpClient` is not available, please pass in a `fetch` or `axios` instance as an option or have them globally available.');
|
|
435
|
-
if (options.timeout && !options.getAbortController) throw new Error('`AbortController` is not available. Please pass in `getAbortController` as an option or have AbortController globally available when using timeout.');
|
|
436
465
|
}
|
|
437
466
|
|
|
438
467
|
/**
|
|
@@ -638,7 +667,10 @@ async function executeRequest$1(options) {
|
|
|
638
667
|
* and there's either no token or the token is expired
|
|
639
668
|
*/
|
|
640
669
|
if (tokenCacheObject && tokenCacheObject.refreshToken && (!tokenCacheObject.token || tokenCacheObject.token && Date.now() > tokenCacheObject.expirationTime)) {
|
|
641
|
-
if (!userOption)
|
|
670
|
+
if (!userOption) {
|
|
671
|
+
requestState.set(false);
|
|
672
|
+
throw new Error('Missing required options.');
|
|
673
|
+
}
|
|
642
674
|
const opt = {
|
|
643
675
|
...buildRequestForRefreshTokenFlow({
|
|
644
676
|
...userOption,
|
|
@@ -711,8 +743,10 @@ async function executeRequest$1(options) {
|
|
|
711
743
|
const error = new Error(response.data.message ? response.data.message : JSON.stringify(response.data));
|
|
712
744
|
/**
|
|
713
745
|
* reject the error immediately
|
|
714
|
-
* and free up the middleware chain
|
|
746
|
+
* and free up the middleware chain and
|
|
747
|
+
* release the requestState by setting it to false
|
|
715
748
|
*/
|
|
749
|
+
requestState.set(false);
|
|
716
750
|
request.reject({
|
|
717
751
|
...request,
|
|
718
752
|
headers: {
|
|
@@ -727,6 +761,10 @@ async function executeRequest$1(options) {
|
|
|
727
761
|
}
|
|
728
762
|
});
|
|
729
763
|
} catch (error) {
|
|
764
|
+
/**
|
|
765
|
+
* on error release the state by setting it to false
|
|
766
|
+
*/
|
|
767
|
+
requestState.set(false);
|
|
730
768
|
return {
|
|
731
769
|
...request,
|
|
732
770
|
headers: {
|
|
@@ -1224,7 +1262,7 @@ function createQueueMiddleware$1({
|
|
|
1224
1262
|
|
|
1225
1263
|
var packageJson = {
|
|
1226
1264
|
name: "@commercetools/ts-client",
|
|
1227
|
-
version: "2.0.
|
|
1265
|
+
version: "2.0.1",
|
|
1228
1266
|
engines: {
|
|
1229
1267
|
node: ">=14"
|
|
1230
1268
|
},
|
|
@@ -1260,7 +1298,7 @@ var packageJson = {
|
|
|
1260
1298
|
"abort-controller": "3.0.0",
|
|
1261
1299
|
buffer: "^6.0.3",
|
|
1262
1300
|
"node-fetch": "^2.6.1",
|
|
1263
|
-
uuid: "
|
|
1301
|
+
uuid: "10.0.0"
|
|
1264
1302
|
},
|
|
1265
1303
|
files: [
|
|
1266
1304
|
"dist",
|
|
@@ -112,10 +112,11 @@ function createError({
|
|
|
112
112
|
return new HttpError(statusCode, errorMessage, rest);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
function
|
|
116
|
-
return
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
function hasResponseRetryCode(retryCodes, response) {
|
|
116
|
+
return (
|
|
117
|
+
// retryCodes.includes(response?.error?.message) ||
|
|
118
|
+
[503, ...retryCodes].includes(response?.status || response?.statusCode)
|
|
119
|
+
);
|
|
119
120
|
}
|
|
120
121
|
async function executeHttpClientRequest(fetcher, config) {
|
|
121
122
|
async function sendRequest() {
|
|
@@ -142,14 +143,17 @@ async function executor(request) {
|
|
|
142
143
|
const data = await executeHttpClientRequest(async options => {
|
|
143
144
|
const {
|
|
144
145
|
enableRetry,
|
|
145
|
-
retryConfig
|
|
146
|
+
retryConfig,
|
|
147
|
+
abortController
|
|
146
148
|
} = rest;
|
|
147
149
|
const {
|
|
148
150
|
retryCodes = [],
|
|
149
151
|
maxDelay = Infinity,
|
|
150
152
|
maxRetries = 3,
|
|
151
153
|
backoff = true,
|
|
152
|
-
retryDelay = 200
|
|
154
|
+
retryDelay = 200,
|
|
155
|
+
// If set to true reinitialize the abort controller when the timeout is reached and apply the retry config
|
|
156
|
+
retryOnAbort = true
|
|
153
157
|
} = retryConfig || {};
|
|
154
158
|
let result,
|
|
155
159
|
data,
|
|
@@ -175,15 +179,41 @@ async function executor(request) {
|
|
|
175
179
|
});
|
|
176
180
|
}
|
|
177
181
|
async function executeWithRetry() {
|
|
182
|
+
const executeWithTryCatch = async (retryCodes, retryWhenAborted) => {
|
|
183
|
+
let _response = {};
|
|
184
|
+
try {
|
|
185
|
+
_response = await execute();
|
|
186
|
+
if (_response.status > 299 && hasResponseRetryCode(retryCodes, _response)) return {
|
|
187
|
+
_response,
|
|
188
|
+
shouldRetry: true
|
|
189
|
+
};
|
|
190
|
+
} catch (e) {
|
|
191
|
+
if (e.name.includes('AbortError') && retryWhenAborted) {
|
|
192
|
+
return {
|
|
193
|
+
_response: e,
|
|
194
|
+
shouldRetry: true
|
|
195
|
+
};
|
|
196
|
+
} else {
|
|
197
|
+
throw e;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
_response,
|
|
202
|
+
shouldRetry: false
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
const retryWhenAborted = retryOnAbort || !abortController || !abortController.signal;
|
|
178
206
|
// first attempt
|
|
179
|
-
let
|
|
180
|
-
|
|
181
|
-
|
|
207
|
+
let {
|
|
208
|
+
_response,
|
|
209
|
+
shouldRetry
|
|
210
|
+
} = await executeWithTryCatch(retryCodes, retryWhenAborted);
|
|
182
211
|
// retry attempts
|
|
183
|
-
while (enableRetry && retryCount < maxRetries) {
|
|
212
|
+
while (enableRetry && shouldRetry && retryCount < maxRetries) {
|
|
184
213
|
retryCount++;
|
|
185
|
-
|
|
186
|
-
|
|
214
|
+
const execution = await executeWithTryCatch(retryCodes, retryWhenAborted);
|
|
215
|
+
_response = execution._response;
|
|
216
|
+
shouldRetry = execution.shouldRetry;
|
|
187
217
|
|
|
188
218
|
// delay next execution
|
|
189
219
|
const timer = calculateRetryDelay({
|
|
@@ -423,7 +453,6 @@ function createUserAgent(options) {
|
|
|
423
453
|
function validateHttpOptions(options) {
|
|
424
454
|
if (!options.host) throw new Error('Request `host` or `url` is missing or invalid, please pass in a valid host e.g `host: http://a-valid-host-url`');
|
|
425
455
|
if (!options.httpClient && typeof options.httpClient !== 'function') throw new Error('An `httpClient` is not available, please pass in a `fetch` or `axios` instance as an option or have them globally available.');
|
|
426
|
-
if (options.timeout && !options.getAbortController) throw new Error('`AbortController` is not available. Please pass in `getAbortController` as an option or have AbortController globally available when using timeout.');
|
|
427
456
|
}
|
|
428
457
|
|
|
429
458
|
/**
|
|
@@ -629,7 +658,10 @@ async function executeRequest$1(options) {
|
|
|
629
658
|
* and there's either no token or the token is expired
|
|
630
659
|
*/
|
|
631
660
|
if (tokenCacheObject && tokenCacheObject.refreshToken && (!tokenCacheObject.token || tokenCacheObject.token && Date.now() > tokenCacheObject.expirationTime)) {
|
|
632
|
-
if (!userOption)
|
|
661
|
+
if (!userOption) {
|
|
662
|
+
requestState.set(false);
|
|
663
|
+
throw new Error('Missing required options.');
|
|
664
|
+
}
|
|
633
665
|
const opt = {
|
|
634
666
|
...buildRequestForRefreshTokenFlow({
|
|
635
667
|
...userOption,
|
|
@@ -702,8 +734,10 @@ async function executeRequest$1(options) {
|
|
|
702
734
|
const error = new Error(response.data.message ? response.data.message : JSON.stringify(response.data));
|
|
703
735
|
/**
|
|
704
736
|
* reject the error immediately
|
|
705
|
-
* and free up the middleware chain
|
|
737
|
+
* and free up the middleware chain and
|
|
738
|
+
* release the requestState by setting it to false
|
|
706
739
|
*/
|
|
740
|
+
requestState.set(false);
|
|
707
741
|
request.reject({
|
|
708
742
|
...request,
|
|
709
743
|
headers: {
|
|
@@ -718,6 +752,10 @@ async function executeRequest$1(options) {
|
|
|
718
752
|
}
|
|
719
753
|
});
|
|
720
754
|
} catch (error) {
|
|
755
|
+
/**
|
|
756
|
+
* on error release the state by setting it to false
|
|
757
|
+
*/
|
|
758
|
+
requestState.set(false);
|
|
721
759
|
return {
|
|
722
760
|
...request,
|
|
723
761
|
headers: {
|
|
@@ -1215,7 +1253,7 @@ function createQueueMiddleware$1({
|
|
|
1215
1253
|
|
|
1216
1254
|
var packageJson = {
|
|
1217
1255
|
name: "@commercetools/ts-client",
|
|
1218
|
-
version: "2.0.
|
|
1256
|
+
version: "2.0.1",
|
|
1219
1257
|
engines: {
|
|
1220
1258
|
node: ">=14"
|
|
1221
1259
|
},
|
|
@@ -1251,7 +1289,7 @@ var packageJson = {
|
|
|
1251
1289
|
"abort-controller": "3.0.0",
|
|
1252
1290
|
buffer: "^6.0.3",
|
|
1253
1291
|
"node-fetch": "^2.6.1",
|
|
1254
|
-
uuid: "
|
|
1292
|
+
uuid: "10.0.0"
|
|
1255
1293
|
},
|
|
1256
1294
|
files: [
|
|
1257
1295
|
"dist",
|
|
@@ -222,7 +222,7 @@ export type HttpMiddlewareOptions = {
|
|
|
222
222
|
retryConfig?: RetryOptions
|
|
223
223
|
httpClient: Function
|
|
224
224
|
getAbortController?: () => AbortController
|
|
225
|
-
httpClientOptions?: object
|
|
225
|
+
httpClientOptions?: object // will be passed as a second argument to your httpClient function for configuration
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
export type RetryOptions = RetryMiddlewareOptions
|
|
@@ -242,6 +242,7 @@ export type RetryMiddlewareOptions = {
|
|
|
242
242
|
maxRetries?: number
|
|
243
243
|
retryDelay?: number
|
|
244
244
|
maxDelay?: typeof Infinity
|
|
245
|
+
retryOnAbort?: boolean
|
|
245
246
|
retryCodes?: Array<number | string>
|
|
246
247
|
}
|
|
247
248
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commercetools/ts-client",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=14"
|
|
6
6
|
},
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"abort-controller": "3.0.0",
|
|
37
37
|
"buffer": "^6.0.3",
|
|
38
38
|
"node-fetch": "^2.6.1",
|
|
39
|
-
"uuid": "
|
|
39
|
+
"uuid": "10.0.0"
|
|
40
40
|
},
|
|
41
41
|
"files": ["dist", "CHANGELOG.md"],
|
|
42
42
|
"author": "Chukwuemeka Ajima <meeky.ae@gmail.com>",
|