@commercetools/sdk-client-v2 1.1.0 → 1.4.0

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 CHANGED
@@ -1,5 +1,33 @@
1
1
  # @commercetools/sdk-client-v2
2
2
 
3
+ ## 1.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#257](https://github.com/commercetools/commercetools-sdk-typescript/pull/257) [`facc47b`](https://github.com/commercetools/commercetools-sdk-typescript/commit/facc47ba50b00056adc232d7c75a2849cdcc6689) Thanks [@ajimae](https://github.com/ajimae)! - release latest sdk
8
+
9
+ ### Patch Changes
10
+
11
+ - [#248](https://github.com/commercetools/commercetools-sdk-typescript/pull/248) [`7512c3f`](https://github.com/commercetools/commercetools-sdk-typescript/commit/7512c3f1f488645da3952f296d4f4fe3149b7fba) Thanks [@ajimae](https://github.com/ajimae)! - - add an option (`includeRequestInErrorResponse`) to include or exclude original request from error responses.
12
+
13
+ ## 1.3.0
14
+
15
+ ### Minor Changes
16
+
17
+ - [#241](https://github.com/commercetools/commercetools-sdk-typescript/pull/241) [`85f5be3`](https://github.com/commercetools/commercetools-sdk-typescript/commit/85f5be349a9b0fa46539259981bfd8d5fc2ffdc6) Thanks [@ajimae](https://github.com/ajimae)! - Releasing the TS SDK with the following changelogs
18
+
19
+ - added functionalities to extend client user agent
20
+ - custom field added to OrderFromCardDraft
21
+
22
+ ## 1.2.0
23
+
24
+ ### Minor Changes
25
+
26
+ - [#211](https://github.com/commercetools/commercetools-sdk-typescript/pull/211) [`f3c1e3e`](https://github.com/commercetools/commercetools-sdk-typescript/commit/f3c1e3ea0ca000b309eca1de6163c3ad065d526f) Thanks [@jherey](https://github.com/jherey)! - - Change Import Summaries `processingState` to `processingstate`.
27
+ - Add `sort` to `ByProjectKeyShippingMethodsMatchingLocationRequestBuilder`.
28
+ - New `MyCustomerResetPassword` model added to `ByProjectKeyMePasswordResetRequestBuilder` class.
29
+ - Other changes are detailed here: https://github.com/commercetools/commercetools-sdk-typescript/pull/192/files.
30
+
3
31
  ## 1.1.0
4
32
 
5
33
  ### Minor Changes
@@ -39,13 +39,104 @@ function validate(funcName, request, options = {
39
39
  if (!options.allowedMethods.includes(request.method)) throw new Error(`The "${funcName}" Request object requires a valid method. See https://commercetools.github.io/nodejs/sdk/Glossary.html#clientrequest`);
40
40
  }
41
41
 
42
+ let _options;
43
+
42
44
  function compose(...funcs) {
43
45
  funcs = funcs.filter(func => typeof func === 'function');
44
46
  if (funcs.length === 1) return funcs[0];
45
47
  return funcs.reduce((a, b) => (...args) => a(b(...args)));
46
48
  }
47
49
 
50
+ function process$1(request, fn, processOpt) {
51
+ validate('process', request, {
52
+ allowedMethods: ['GET']
53
+ });
54
+ if (typeof fn !== 'function') throw new Error('The "process" function accepts a "Function" as a second argument that returns a Promise. See https://commercetools.github.io/nodejs/sdk/api/sdkClient.html#processrequest-processfn-options'); // Set default process options
55
+
56
+ const opt = {
57
+ total: Number.POSITIVE_INFINITY,
58
+ accumulate: true,
59
+ ...processOpt
60
+ };
61
+ return new Promise((resolve, reject) => {
62
+ let _path,
63
+ _queryString = '';
64
+
65
+ if (request && request.uri) {
66
+ const [path, queryString] = request.uri.split('?');
67
+ _path = path;
68
+ _queryString = queryString;
69
+ }
70
+
71
+ const requestQuery = { ...qs__default["default"].parse(_queryString)
72
+ };
73
+ const query = {
74
+ // defaults
75
+ limit: 20,
76
+ // merge given query params
77
+ ...requestQuery
78
+ };
79
+ let hasFirstPageBeenProcessed = false;
80
+ let itemsToGet = opt.total;
81
+
82
+ const processPage = async (lastId, acc = []) => {
83
+ // Use the lesser value between limit and itemsToGet in query
84
+ const limit = query.limit < itemsToGet ? query.limit : itemsToGet;
85
+ const originalQueryString = qs__default["default"].stringify({ ...query,
86
+ limit
87
+ });
88
+ const enhancedQuery = {
89
+ sort: 'id asc',
90
+ withTotal: false,
91
+ ...(lastId ? {
92
+ where: `id > "${lastId}"`
93
+ } : {})
94
+ };
95
+ const enhancedQueryString = qs__default["default"].stringify(enhancedQuery);
96
+ const enhancedRequest = { ...request,
97
+ uri: `${_path}?${enhancedQueryString}&${originalQueryString}`
98
+ };
99
+
100
+ try {
101
+ const payload = await createClient(_options).execute(enhancedRequest);
102
+ const {
103
+ results,
104
+ count: resultsLength
105
+ } = payload.body;
106
+
107
+ if (!resultsLength && hasFirstPageBeenProcessed) {
108
+ return resolve(acc || []);
109
+ }
110
+
111
+ const result = await Promise.resolve(fn(payload));
112
+ let accumulated;
113
+ hasFirstPageBeenProcessed = true;
114
+ if (opt.accumulate) accumulated = acc.concat(result || []);
115
+ itemsToGet -= resultsLength; // If there are no more items to get, it means the total number
116
+ // of items in the original request have been fetched so we
117
+ // resolve the promise.
118
+ // Also, if we get less results in a page then the limit set it
119
+ // means that there are no more pages and that we can finally
120
+ // resolve the promise.
121
+
122
+ if (resultsLength < query.limit || !itemsToGet) {
123
+ return resolve(accumulated || []);
124
+ }
125
+
126
+ const last = results[resultsLength - 1];
127
+ const newLastId = last && last.id;
128
+ processPage(newLastId, accumulated);
129
+ } catch (error) {
130
+ reject(error);
131
+ }
132
+ }; // Start iterating through pages
133
+
134
+
135
+ processPage();
136
+ });
137
+ }
48
138
  function createClient(options) {
139
+ _options = options;
49
140
  if (!options) throw new Error('Missing required options');
50
141
  if (options.middlewares && !Array.isArray(options.middlewares)) throw new Error('Middlewares should be an array');
51
142
  if (!options.middlewares || !Array.isArray(options.middlewares) || !options.middlewares.length) throw new Error('You need to provide at least one middleware');
@@ -53,6 +144,8 @@ function createClient(options) {
53
144
  /**
54
145
  * Given a request object,
55
146
  */
147
+ process: process$1,
148
+
56
149
  execute(request) {
57
150
  validate('exec', request);
58
151
  return new Promise((resolve, reject) => {
@@ -81,95 +174,6 @@ function createClient(options) {
81
174
  error: undefined
82
175
  });
83
176
  });
84
- },
85
-
86
- process(request, fn, processOpt) {
87
- validate('process', request, {
88
- allowedMethods: ['GET']
89
- });
90
- if (typeof fn !== 'function') throw new Error('The "process" function accepts a "Function" as a second argument that returns a Promise. See https://commercetools.github.io/nodejs/sdk/api/sdkClient.html#processrequest-processfn-options'); // Set default process options
91
-
92
- const opt = {
93
- total: Number.POSITIVE_INFINITY,
94
- accumulate: true,
95
- ...processOpt
96
- };
97
- return new Promise((resolve, reject) => {
98
- let _path,
99
- _queryString = '';
100
-
101
- if (request && request.uri) {
102
- const [path, queryString] = request.uri.split('?');
103
- _path = path;
104
- _queryString = queryString;
105
- }
106
-
107
- const requestQuery = { ...qs__default["default"].parse(_queryString)
108
- };
109
- const query = {
110
- // defaults
111
- limit: 20,
112
- // merge given query params
113
- ...requestQuery
114
- };
115
- let hasFirstPageBeenProcessed = false;
116
- let itemsToGet = opt.total;
117
-
118
- const processPage = async (lastId, acc = []) => {
119
- // Use the lesser value between limit and itemsToGet in query
120
- const limit = query.limit < itemsToGet ? query.limit : itemsToGet;
121
- const originalQueryString = qs__default["default"].stringify({ ...query,
122
- limit
123
- });
124
- const enhancedQuery = {
125
- sort: 'id asc',
126
- withTotal: false,
127
- ...(lastId ? {
128
- where: `id > "${lastId}"`
129
- } : {})
130
- };
131
- const enhancedQueryString = qs__default["default"].stringify(enhancedQuery);
132
- const enhancedRequest = { ...request,
133
- uri: `${_path}?${enhancedQueryString}&${originalQueryString}`
134
- };
135
-
136
- try {
137
- const payload = await this.execute(enhancedRequest);
138
- const {
139
- results,
140
- count: resultsLength
141
- } = payload.body;
142
-
143
- if (!resultsLength && hasFirstPageBeenProcessed) {
144
- return resolve(acc || []);
145
- }
146
-
147
- const result = await Promise.resolve(fn(payload));
148
- let accumulated;
149
- hasFirstPageBeenProcessed = true;
150
- if (opt.accumulate) accumulated = acc.concat(result || []);
151
- itemsToGet -= resultsLength; // If there are no more items to get, it means the total number
152
- // of items in the original request have been fetched so we
153
- // resolve the promise.
154
- // Also, if we get less results in a page then the limit set it
155
- // means that there are no more pages and that we can finally
156
- // resolve the promise.
157
-
158
- if (resultsLength < query.limit || !itemsToGet) {
159
- return resolve(accumulated || []);
160
- }
161
-
162
- const last = results[resultsLength - 1];
163
- const newLastId = last && last.id;
164
- processPage(newLastId, accumulated);
165
- } catch (error) {
166
- reject(error);
167
- }
168
- }; // Start iterating through pages
169
-
170
-
171
- processPage();
172
- });
173
177
  }
174
178
 
175
179
  };
@@ -741,6 +745,7 @@ function createHttpMiddleware({
741
745
  credentialsMode,
742
746
  includeResponseHeaders,
743
747
  includeOriginalRequest,
748
+ includeRequestInErrorResponse = true,
744
749
  maskSensitiveHeaderData = true,
745
750
  enableRetry,
746
751
  timeout,
@@ -749,7 +754,8 @@ function createHttpMiddleware({
749
754
  maxRetries = 10,
750
755
  backoff = true,
751
756
  retryDelay = 200,
752
- maxDelay = Infinity
757
+ maxDelay = Infinity,
758
+ retryCodes = [503]
753
759
  } = {},
754
760
  fetch: fetcher,
755
761
  getAbortController
@@ -767,20 +773,29 @@ function createHttpMiddleware({
767
773
  fetchFunction = fetch;
768
774
  }
769
775
 
776
+ if (!Array.isArray(retryCodes)) {
777
+ throw new Error('`retryCodes` option must be an array of retry status (error) codes.');
778
+ }
779
+
770
780
  return next => (request, response) => {
771
781
  let abortController;
772
782
  if (timeout || getAbortController) abortController = (getAbortController ? getAbortController() : null) || new AbortController();
773
783
  const url = host.replace(/\/$/, '') + request.uri;
774
- const body = typeof request.body === 'string' || Buffer.isBuffer(request.body) ? request.body : // NOTE: `stringify` of `null` gives the String('null')
775
- JSON.stringify(request.body || undefined);
776
784
  const requestHeader = { ...request.headers
777
- };
785
+ }; // Unset the content-type header if explicitly asked to (passing `null` as value).
778
786
 
779
- if (!Object.prototype.hasOwnProperty.call(requestHeader, 'Content-Type')) {
780
- requestHeader['Content-Type'] = 'application/json';
787
+ if (requestHeader['Content-Type'] === null) {
788
+ delete requestHeader['Content-Type'];
781
789
  }
782
790
 
783
- if (body) {
791
+ if (!Object.prototype.hasOwnProperty.call(requestHeader, 'Content-Type') || !Object.prototype.hasOwnProperty.call(requestHeader, 'content-type')) {
792
+ requestHeader['Content-Type'] = 'application/json';
793
+ } // Ensure body is a string if content type is application/json
794
+
795
+
796
+ const body = requestHeader['Content-Type'] === 'application/json' && typeof request.body === 'string' || Buffer.isBuffer(request.body) ? request.body : JSON.stringify(request.body || undefined);
797
+
798
+ if (body && (typeof body === 'string' || Buffer.isBuffer(body))) {
784
799
  requestHeader['Content-Length'] = Buffer.byteLength(body).toString();
785
800
  }
786
801
 
@@ -849,15 +864,25 @@ function createHttpMiddleware({
849
864
  next(request, parsedResponse);
850
865
  });
851
866
  return;
852
- }
853
-
854
- if (res.status === 503 && enableRetry) if (retryCount < maxRetries) {
855
- setTimeout(executeFetch, calcDelayDuration(retryCount, retryDelay, maxRetries, backoff, maxDelay));
856
- retryCount += 1;
857
- return;
858
- } // Server responded with an error. Try to parse it as JSON, then
867
+ } // if (res.status === 503 && enableRetry)
868
+ // if (retryCount < maxRetries) {
869
+ // setTimeout(
870
+ // executeFetch,
871
+ // calcDelayDuration(
872
+ // retryCount,
873
+ // retryDelay,
874
+ // maxRetries,
875
+ // backoff,
876
+ // maxDelay
877
+ // )
878
+ // )
879
+ // retryCount += 1
880
+ // return
881
+ // }
882
+ // Server responded with an error. Try to parse it as JSON, then
859
883
  // return a proper error type with all necessary meta information.
860
884
 
885
+
861
886
  res.text().then(text => {
862
887
  // Try to parse the error response as JSON
863
888
  let parsed;
@@ -870,7 +895,9 @@ function createHttpMiddleware({
870
895
 
871
896
  const error = createError({
872
897
  statusCode: res.status,
873
- originalRequest: request,
898
+ ...(includeRequestInErrorResponse ? {
899
+ originalRequest: request
900
+ } : {}),
874
901
  retryCount,
875
902
  headers: parseHeaders(res.headers),
876
903
  ...(typeof parsed === 'object' ? {
@@ -881,6 +908,15 @@ function createHttpMiddleware({
881
908
  body: parsed
882
909
  })
883
910
  });
911
+
912
+ if (enableRetry && (retryCodes.indexOf(error.statusCode) !== -1 || (retryCodes === null || retryCodes === void 0 ? void 0 : retryCodes.indexOf(error.message)) !== -1)) {
913
+ if (retryCount < maxRetries) {
914
+ setTimeout(executeFetch, calcDelayDuration(retryCount, retryDelay, maxRetries, backoff, maxDelay));
915
+ retryCount += 1;
916
+ return;
917
+ }
918
+ }
919
+
884
920
  maskAuthData(error.originalRequest, maskSensitiveHeaderData); // Let the final resolver to reject the promise
885
921
 
886
922
  const parsedResponse = { ...response,
@@ -896,8 +932,9 @@ function createHttpMiddleware({
896
932
  retryCount += 1;
897
933
  return;
898
934
  }
899
- const error = new NetworkError(e.message, {
900
- originalRequest: request,
935
+ const error = new NetworkError(e.message, { ...(includeRequestInErrorResponse ? {
936
+ originalRequest: request
937
+ } : {}),
901
938
  retryCount
902
939
  });
903
940
  maskAuthData(error.originalRequest, maskSensitiveHeaderData);
@@ -982,7 +1019,7 @@ function createQueueMiddleware({
982
1019
 
983
1020
  var packageJson = {
984
1021
  name: "@commercetools/sdk-client-v2",
985
- version: "1.1.0",
1022
+ version: "1.4.0",
986
1023
  description: "commercetools TypeScript SDK client.",
987
1024
  keywords: [
988
1025
  "commercetools",
@@ -1029,7 +1066,7 @@ var packageJson = {
1029
1066
  devDependencies: {
1030
1067
  "abort-controller": "3.0.0",
1031
1068
  "common-tags": "1.8.2",
1032
- dotenv: "10.0.0",
1069
+ dotenv: "16.0.0",
1033
1070
  jest: "27.4.7",
1034
1071
  nock: "12.0.3",
1035
1072
  "organize-imports-cli": "0.9.0"
@@ -1073,12 +1110,14 @@ function createUserAgent(options) {
1073
1110
  let contactInfo = null;
1074
1111
  if (options.contactUrl && !options.contactEmail) contactInfo = `(+${options.contactUrl})`;else if (!options.contactUrl && options.contactEmail) contactInfo = `(+${options.contactEmail})`;else if (options.contactUrl && options.contactEmail) contactInfo = `(+${options.contactUrl}; +${options.contactEmail})`; // System info
1075
1112
 
1076
- const systemInfo = getSystemInfo();
1077
- return [baseInfo, systemInfo, libraryInfo, contactInfo].filter(Boolean).join(' ');
1113
+ const systemInfo = getSystemInfo(); // customName
1114
+
1115
+ const customAgent = options.customAgent || '';
1116
+ return [baseInfo, systemInfo, libraryInfo, contactInfo, customAgent].filter(Boolean).join(' ');
1078
1117
  }
1079
1118
 
1080
- function createUserAgentMiddleware() {
1081
- const userAgent = createUserAgent({
1119
+ function createUserAgentMiddleware(options) {
1120
+ const userAgent = createUserAgent({ ...options,
1082
1121
  name: `commercetools-sdk-javascript-v2/${packageJson.version}`
1083
1122
  });
1084
1123
  return next => (request, response) => {
@@ -1219,8 +1258,8 @@ class ClientBuilder {
1219
1258
  return this;
1220
1259
  }
1221
1260
 
1222
- withUserAgentMiddleware() {
1223
- this.userAgentMiddleware = createUserAgentMiddleware();
1261
+ withUserAgentMiddleware(options) {
1262
+ this.userAgentMiddleware = createUserAgentMiddleware(options);
1224
1263
  return this;
1225
1264
  }
1226
1265
 
@@ -1261,6 +1300,7 @@ class ClientBuilder {
1261
1300
  }
1262
1301
 
1263
1302
  exports.ClientBuilder = ClientBuilder;
1303
+ exports.Process = process$1;
1264
1304
  exports.createAuthForAnonymousSessionFlow = createAuthMiddlewareForAnonymousSessionFlow$1;
1265
1305
  exports.createAuthForClientCredentialsFlow = createAuthMiddlewareForClientCredentialsFlow$1;
1266
1306
  exports.createAuthForPasswordFlow = createAuthMiddlewareForPasswordFlow$1;