@commercetools/ts-client 0.0.0-beta.1 → 0.0.0-beta.10

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/README.md CHANGED
@@ -16,14 +16,13 @@ yarn add @commercetools/platform-sdk
16
16
 
17
17
  ```ts
18
18
  import {
19
- type Next
19
+ type Next,
20
20
  type HttpMiddlewareOptions,
21
- type AuthMiddlewareBaseOptions
21
+ type AuthMiddlewareBaseOptions,
22
22
  type ClientRequest,
23
23
  type MiddlewareRequest,
24
24
  type MiddlewareResponse,
25
- type Client
26
-
25
+ type Client,
27
26
  ClientBuilder,
28
27
  } from '@commercetools/ts-client'
29
28
  import { createApiBuilderFromCtpClient } from '@commercetools/platform-sdk'
@@ -51,7 +50,7 @@ const retryOptions = {
51
50
  maxRetries: 3,
52
51
  retryDelay: 200,
53
52
  backoff: true,
54
- retryCodes: [200]
53
+ retryCodes: [200],
55
54
  }
56
55
 
57
56
  // custom middleware
@@ -69,8 +68,13 @@ function middleware(options) {
69
68
 
70
69
  const client: Client = new ClientBuilder()
71
70
  .withPasswordFlow(authMiddlewareOptions)
72
- .withLoggerMiddleware({ includeOriginalRequest: false, includeResponseHeaders: false })
73
- .withCorrelationIdMiddleware({ generate: () => 'fake-correlation-id' + Math.floor(Math.random() + 2) })
71
+ .withLoggerMiddleware({
72
+ includeOriginalRequest: false,
73
+ includeResponseHeaders: false,
74
+ })
75
+ .withCorrelationIdMiddleware({
76
+ generate: () => 'fake-correlation-id' + Math.floor(Math.random() + 2),
77
+ })
74
78
  .withHttpMiddleware(httpMiddlewareOptions)
75
79
  .withRetryMiddleware(retryOptions)
76
80
  .withMiddleware(middleware({})) // <<<------------------- add the custom middleware here
@@ -155,6 +155,11 @@ function mergeAuthHeader(token, req) {
155
155
  };
156
156
  }
157
157
 
158
+ function predicate$1(retryCodes, response) {
159
+ return ! // retryCodes.includes(response?.error?.message) ||
160
+ [503, ...retryCodes].includes(response?.status || response?.statusCode);
161
+ }
162
+
158
163
  async function executeHttpClientRequest(fetcher, config) {
159
164
  async function sendRequest() {
160
165
  const response = await fetcher({ ...config,
@@ -178,23 +183,68 @@ async function executor(request) {
178
183
  ...rest
179
184
  } = request;
180
185
  const data = await executeHttpClientRequest(async options => {
181
- const response = await httpClient(url, { ...rest,
182
- ...options,
183
- headers: { ...rest.headers,
184
- ...options.headers,
185
- // axios header encoding
186
- 'Accept-Encoding': 'application/json'
187
- },
188
- // for axios
189
- ...(rest.body ? {
190
- data: rest.body
191
- } : {}),
192
- withCredentials: options.credentialsMode === 'include'
193
- });
186
+ const {
187
+ enableRetry,
188
+ retryConfig
189
+ } = rest;
190
+ const {
191
+ retryCodes = [],
192
+ maxDelay = Infinity,
193
+ maxRetries = 3,
194
+ backoff = true,
195
+ retryDelay = 200
196
+ } = retryConfig || {};
197
+ let retryCount = 0; // validate the `retryCodes` option
198
+
199
+ validateRetryCodes(retryCodes);
200
+
201
+ async function execute() {
202
+ return httpClient(url, { ...rest,
203
+ ...options,
204
+ headers: { ...rest.headers,
205
+ ...options.headers,
206
+ // axios header encoding
207
+ 'Accept-Encoding': 'application/json'
208
+ },
209
+ // for axios
210
+ ...(rest.body ? {
211
+ data: rest.body
212
+ } : {}),
213
+ withCredentials: options.credentialsMode === 'include'
214
+ });
215
+ }
216
+
217
+ async function executeWithRetry() {
218
+ // first attempt
219
+ let _response = await execute();
220
+
221
+ if (predicate$1(retryCodes, _response)) return _response; // retry attempts
222
+
223
+ while (enableRetry && retryCount < maxRetries) {
224
+ retryCount++;
225
+ _response = await execute();
226
+ if (predicate$1(retryCodes, _response)) return _response; // delay next execution
227
+
228
+ const timer = calculateRetryDelay({
229
+ retryCount,
230
+ retryDelay,
231
+ maxRetries,
232
+ backoff,
233
+ maxDelay
234
+ });
235
+ await sleep(timer);
236
+ }
237
+
238
+ return _response;
239
+ }
240
+
241
+ const response = await executeWithRetry(); // parse response as json or return the data object (for axios response)
242
+
194
243
  const data = response.json && typeof response.json == 'function' ? await response.json() : response.data || response;
195
244
  return {
196
245
  data,
197
- statusCode: response.status || response.statusCode,
246
+ retryCount,
247
+ statusCode: response.status || response.statusCode || data.statusCode,
198
248
  headers: response.headers
199
249
  };
200
250
  },
@@ -215,6 +265,102 @@ function sleep(ms) {
215
265
 
216
266
  var METHODS = ['ACL', 'BIND', 'CHECKOUT', 'CONNECT', 'COPY', 'DELETE', 'GET', 'HEAD', 'LINK', 'LOCK', 'M-SEARCH', 'MERGE', 'MKACTIVITY', 'MKCALENDAR', 'MKCOL', 'MOVE', 'NOTIFY', 'OPTIONS', 'PATCH', 'POST', 'PROPFIND', 'PROPPATCH', 'PURGE', 'PUT', 'REBIND', 'REPORT', 'SEARCH', 'SOURCE', 'SUBSCRIBE', 'TRACE', 'UNBIND', 'UNLINK', 'UNLOCK', 'UNSUBSCRIBE'];
217
267
 
268
+ // class DefineError {
269
+ // name: string
270
+ // code: number
271
+ // status: number
272
+ // statusCode: number
273
+ // message: string
274
+ // constructor(statusCode: number, message: string, meta: object) {
275
+ // this.status = this.statusCode = this.code = statusCode
276
+ // this.message = message
277
+ // Object.assign(this, meta)
278
+ // this.name = this.constructor.name
279
+ // this.constructor.prototype.__proto__ = Error.prototype
280
+ // if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor)
281
+ // }
282
+ // }
283
+ function DefineError(statusCode, message, meta = {}) {
284
+ // eslint-disable-next-line no-multi-assign
285
+ this.status = this.statusCode = this.code = statusCode;
286
+ this.message = message;
287
+ Object.assign(this, meta);
288
+ this.name = this.constructor.name; // eslint-disable-next-line no-proto
289
+
290
+ this.constructor.prototype.__proto__ = Error.prototype;
291
+ if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
292
+ }
293
+
294
+ function NetworkError(...args) {
295
+ DefineError.call(this, 0, ...args);
296
+ }
297
+ function HttpError(...args) {
298
+ DefineError.call(this, ...args);
299
+ }
300
+ function BadRequest(...args) {
301
+ DefineError.call(this, 400, ...args);
302
+ }
303
+ function Unauthorized(...args) {
304
+ DefineError.call(this, 401, ...args);
305
+ }
306
+ function Forbidden(...args) {
307
+ DefineError.call(this, 403, ...args);
308
+ }
309
+ function NotFound(...args) {
310
+ DefineError.call(this, 404);
311
+ }
312
+ function ConcurrentModification(...args) {
313
+ DefineError.call(this, 409, ...args);
314
+ }
315
+ function InternalServerError(...args) {
316
+ DefineError.call(this, 500, ...args);
317
+ }
318
+ function ServiceUnavailable(...args) {
319
+ DefineError.call(this, 503, ...args);
320
+ }
321
+ function getErrorByCode(code) {
322
+ switch (code) {
323
+ case 0:
324
+ return NetworkError;
325
+
326
+ case 400:
327
+ return BadRequest;
328
+
329
+ case 401:
330
+ return Unauthorized;
331
+
332
+ case 403:
333
+ return Forbidden;
334
+
335
+ case 404:
336
+ return NotFound;
337
+
338
+ case 409:
339
+ return ConcurrentModification;
340
+
341
+ case 500:
342
+ return InternalServerError;
343
+
344
+ case 503:
345
+ return ServiceUnavailable;
346
+
347
+ default:
348
+ return undefined;
349
+ }
350
+ }
351
+
352
+ function createError({
353
+ statusCode,
354
+ message,
355
+ ...rest
356
+ }) {
357
+ let errorMessage = message || 'Unexpected non-JSON error response';
358
+ if (statusCode === 404) errorMessage = `URI not found: ${rest.originalRequest.uri}`;
359
+ const ResponseError = getErrorByCode(statusCode);
360
+ if (ResponseError) return new ResponseError(errorMessage, rest);
361
+ return new HttpError(statusCode, errorMessage, rest);
362
+ }
363
+
218
364
  /**
219
365
  * validate some essential http options
220
366
  * @param options
@@ -370,26 +516,30 @@ function createClient(middlewares) {
370
516
  const resolver = {
371
517
  async resolve(rs) {
372
518
  const {
373
- reject,
374
- resolve,
375
519
  response,
376
- retryCount,
520
+ includeOriginalRequest,
377
521
  ...rest
378
522
  } = rs;
523
+ const {
524
+ retryCount,
525
+ ...restt
526
+ } = response;
379
527
  const res = {
380
528
  body: null,
381
529
  error: null,
382
- reject,
383
- resolve,
384
- ...(retryCount ? {
385
- retryCount
530
+ reject: rs.reject,
531
+ resolve: rs.resolve,
532
+ ...restt,
533
+ ...(includeOriginalRequest ? {
534
+ originalRequest: rest
386
535
  } : {}),
387
- request: rest,
388
- ...response
389
- };
536
+ ...(response?.retryCount ? {
537
+ retryCount: response.retryCount
538
+ } : {})
539
+ }; // if (res.error) console.log(res)
390
540
 
391
541
  if (res.error) {
392
- res.reject(res);
542
+ res.reject(res.error);
393
543
  return res;
394
544
  }
395
545
 
@@ -444,13 +594,15 @@ function createCorrelationIdMiddleware$1(options) {
444
594
 
445
595
  async function executeRequest$1({
446
596
  url,
447
- clientOptions,
448
- httpClient
597
+ httpClient,
598
+ clientOptions
449
599
  }) {
450
600
  let timer;
451
601
  const {
452
602
  timeout,
453
- abortController
603
+ request,
604
+ abortController,
605
+ includeRequestInErrorResponse
454
606
  } = clientOptions;
455
607
 
456
608
  try {
@@ -470,33 +622,60 @@ async function executeRequest$1({
470
622
  if (response.statusCode >= 200 && response.statusCode < 300) {
471
623
  if (clientOptions.method == 'HEAD') {
472
624
  return {
625
+ body: null,
473
626
  statusCode: response.statusCode,
627
+ retryCount: response.retryCount,
474
628
  headers: getHeaders(response.headers)
475
629
  };
476
630
  }
477
631
 
478
632
  return {
479
- body: response.data || response,
633
+ body: response.data,
480
634
  statusCode: response.statusCode,
635
+ retryCount: response.retryCount,
481
636
  headers: getHeaders(response.headers)
482
637
  };
483
638
  }
639
+
640
+ const error = createError({
641
+ message: response.data.message || response.message,
642
+ statusCode: response.statusCode || response.data.statusCode,
643
+ headers: getHeaders(response.headers),
644
+ method: clientOptions.method,
645
+ body: response.data,
646
+ retryCount: response.retryCount,
647
+ ...(includeRequestInErrorResponse ? {
648
+ originalRequest: request
649
+ } : {})
650
+ });
484
651
  /**
485
652
  * handle non-ok (error) response
486
653
  * build error body
487
654
  */
488
655
 
489
-
490
656
  return {
491
- error: {
492
- message: response.message || response.data.message,
493
- method: clientOptions.method,
494
- ...response
495
- }
657
+ body: response.data,
658
+ code: response.statusCode,
659
+ statusCode: response.statusCode,
660
+ headers: getHeaders(response.headers),
661
+ error // error: {
662
+ // statusCode: response.statusCode || response.data.statusCode,
663
+ // message: response.data.message,
664
+ // method: clientOptions.method,
665
+ // ...response.data,
666
+ // },
667
+
496
668
  };
497
- } catch (error) {
669
+ } catch (e) {
670
+ const error = new NetworkError(e.message, {
671
+ statusCode: 0,
672
+ body: e,
673
+ error: e
674
+ });
498
675
  return {
499
676
  // We know that this is a network error
677
+ statusCode: 0,
678
+ body: error,
500
679
  error
501
680
  };
502
681
  } finally {
@@ -512,7 +691,11 @@ function createHttpMiddleware$1(options) {
512
691
  credentialsMode,
513
692
  httpClient,
514
693
  timeout,
694
+ enableRetry,
695
+ retryConfig,
515
696
  getAbortController,
697
+ includeOriginalRequest,
698
+ includeRequestInErrorResponse,
516
699
  httpClientOptions
517
700
  } = options;
518
701
  return next => {
@@ -535,8 +718,12 @@ function createHttpMiddleware$1(options) {
535
718
  }
536
719
 
537
720
  const clientOptions = {
721
+ enableRetry,
722
+ retryConfig,
723
+ request: request,
538
724
  method: request.method,
539
725
  headers: requestHeader,
726
+ includeRequestInErrorResponse,
540
727
  ...httpClientOptions
541
728
  };
542
729
 
@@ -564,6 +751,7 @@ function createHttpMiddleware$1(options) {
564
751
  httpClient
565
752
  });
566
753
  const responseWithRequest = { ...request,
754
+ includeOriginalRequest,
567
755
  response
568
756
  };
569
757
  return next(responseWithRequest);
@@ -642,21 +830,31 @@ function createRetryMiddleware$1(options) {
642
830
 
643
831
  async function executeRequest() {
644
832
  // first attenpt
833
+ // retryCount++
645
834
  response = await next(request);
646
- retryCount++;
647
835
 
648
836
  if (predicate(retryCodes, response)) {
649
- return { ...response
837
+ request.resolve({ ...response
838
+ });
839
+ return { ...response // retryCount
840
+
650
841
  };
651
842
  }
652
843
 
653
844
  while (retryCount < maxRetries) {
654
845
  // check if the response if worth retrying for subsequest calls
655
- response = await next(request);
656
846
  retryCount++;
847
+ response = await next({ ...request,
848
+ retryCount
849
+ });
657
850
 
658
851
  if (predicate(retryCodes, response)) {
659
- return { ...response
852
+ // request.resolve({
853
+ // ...response,
854
+ // retryCount
855
+ // })
856
+ return { ...response,
857
+ retryCount
660
858
  };
661
859
  } // delay next execution
662
860
 
@@ -669,7 +867,11 @@ function createRetryMiddleware$1(options) {
669
867
  maxDelay
670
868
  });
671
869
  await sleep(timer);
672
- }
870
+ } // response.reject({
871
+ // ...response,
872
+ // retryCount
873
+ // })
874
+
673
875
 
674
876
  return { ...response,
675
877
  retryCount
@@ -728,7 +930,7 @@ function createLoggerMiddleware$1(options) {
728
930
 
729
931
  var packageJson = {
730
932
  name: "@commercetools/ts-client",
731
- version: "0.0.1-beta.0",
933
+ version: "0.0.0-beta.9",
732
934
  engines: {
733
935
  node: ">=14"
734
936
  },
@@ -761,7 +963,6 @@ var packageJson = {
761
963
  url: "https://github.com/commercetools/commercetools-sdk-typescript/issues"
762
964
  },
763
965
  dependencies: {
764
- axios: "^1.2.0",
765
966
  buffer: "^6.0.3",
766
967
  "node-fetch": "^2.6.1",
767
968
  querystring: "^0.2.1"
@@ -1110,6 +1311,7 @@ async function executeRequest(options) {
1110
1311
  headers: { ...request.headers
1111
1312
  },
1112
1313
  response: {
1314
+ body: null,
1113
1315
  statusCode: error.statusCode || 0,
1114
1316
  error: { ...response,
1115
1317
  error,
@@ -1322,6 +1524,7 @@ const {
1322
1524
  createErrorMiddleware
1323
1525
  } = middleware;
1324
1526
  class ClientBuilder {
1527
+ // private retryMiddleware: Nullable<Middleware>
1325
1528
  constructor() {
1326
1529
  _defineProperty(this, "projectKey", void 0);
1327
1530
 
@@ -1337,8 +1540,6 @@ class ClientBuilder {
1337
1540
 
1338
1541
  _defineProperty(this, "queueMiddleware", void 0);
1339
1542
 
1340
- _defineProperty(this, "retryMiddleware", void 0);
1341
-
1342
1543
  _defineProperty(this, "concurrentMiddleware", void 0);
1343
1544
 
1344
1545
  _defineProperty(this, "errorMiddleware", void 0);
@@ -1433,13 +1634,13 @@ class ClientBuilder {
1433
1634
  refreshToken: options.refreshToken || null,
1434
1635
  ...options
1435
1636
  }));
1436
- }
1637
+ } // public withRetryMiddleware(options: RetryMiddlewareOptions): ClientBuilder {
1638
+ // this.retryMiddleware = createRetryMiddleware({
1639
+ // ...options,
1640
+ // })
1641
+ // return this
1642
+ // }
1437
1643
 
1438
- withRetryMiddleware(options) {
1439
- this.retryMiddleware = createRetryMiddleware({ ...options
1440
- });
1441
- return this;
1442
- }
1443
1644
 
1444
1645
  withExistingTokenFlow(authorization, options) {
1445
1646
  return this.withAuthMiddleware(createAuthMiddlewareForExistingTokenFlow(authorization, {
@@ -1501,15 +1702,16 @@ class ClientBuilder {
1501
1702
  * - add retry middleware to be used by concurrent modification
1502
1703
  * middleware if not explicitly added as part of the middleware
1503
1704
  */
1705
+ // if (!this.retryMiddleware && this.concurrentMiddleware)
1706
+ // this.withRetryMiddleware({})
1504
1707
 
1505
- if (!this.retryMiddleware && this.concurrentMiddleware) this.withRetryMiddleware({});
1506
1708
  if (this.correlationIdMiddleware) middlewares.push(this.correlationIdMiddleware);
1507
1709
  if (this.userAgentMiddleware) middlewares.push(this.userAgentMiddleware);
1508
1710
  if (this.authMiddleware) middlewares.push(this.authMiddleware);
1509
1711
  if (this.queueMiddleware) middlewares.push(this.queueMiddleware);
1510
1712
  if (this.loggerMiddleware) middlewares.push(this.loggerMiddleware);
1511
- if (this.errorMiddleware) middlewares.push(this.errorMiddleware);
1512
- if (this.retryMiddleware) middlewares.push(this.retryMiddleware);
1713
+ if (this.errorMiddleware) middlewares.push(this.errorMiddleware); // if (this.retryMiddleware) middlewares.push(this.retryMiddleware)
1714
+
1513
1715
  if (this.concurrentMiddleware) middlewares.push(this.concurrentMiddleware);
1514
1716
  if (this.httpMiddleware) middlewares.push(this.httpMiddleware);
1515
1717
  return createClient({