@commercetools/ts-client 0.0.0-beta.9 → 1.1.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/LICENSE +1 -1
  3. package/dist/commercetools-ts-client.browser.cjs.js +1669 -0
  4. package/dist/commercetools-ts-client.browser.esm.js +1647 -0
  5. package/dist/commercetools-ts-client.cjs.d.ts +1 -11
  6. package/dist/commercetools-ts-client.cjs.dev.js +1669 -0
  7. package/dist/commercetools-ts-client.cjs.js +6 -15
  8. package/dist/commercetools-ts-client.cjs.prod.js +1669 -0
  9. package/dist/commercetools-ts-client.esm.js +1647 -0
  10. package/dist/declarations/src/client/builder.d.ts +31 -0
  11. package/dist/declarations/src/client/client.d.ts +3 -0
  12. package/dist/declarations/src/client/index.d.ts +2 -0
  13. package/dist/declarations/src/index.d.ts +3 -0
  14. package/dist/declarations/src/middleware/auth-middleware/anonymous-session-flow.d.ts +2 -0
  15. package/dist/declarations/src/middleware/auth-middleware/auth-request-builder.d.ts +24 -0
  16. package/dist/declarations/src/middleware/auth-middleware/auth-request-executor.d.ts +2 -0
  17. package/dist/declarations/src/middleware/auth-middleware/client-credentials-flow.d.ts +2 -0
  18. package/dist/declarations/src/middleware/auth-middleware/existing-token-flow.d.ts +2 -0
  19. package/dist/declarations/src/middleware/auth-middleware/index.d.ts +6 -0
  20. package/dist/declarations/src/middleware/auth-middleware/password-flow.d.ts +2 -0
  21. package/dist/declarations/src/middleware/auth-middleware/refresh-token-flow.d.ts +2 -0
  22. package/dist/declarations/src/middleware/create-concurrent-modification-middleware.d.ts +2 -0
  23. package/dist/declarations/src/middleware/create-correlation-id-middleware.d.ts +2 -0
  24. package/dist/declarations/src/middleware/create-error-middleware.d.ts +2 -0
  25. package/dist/declarations/src/middleware/create-http-middleware.d.ts +2 -0
  26. package/dist/declarations/src/middleware/create-logger-middleware.d.ts +2 -0
  27. package/dist/declarations/src/middleware/create-queue-middleware.d.ts +2 -0
  28. package/dist/declarations/src/middleware/create-user-agent-middleware.d.ts +2 -0
  29. package/dist/declarations/src/middleware/index.d.ts +8 -0
  30. package/dist/declarations/src/types/types.d.ts +329 -0
  31. package/dist/declarations/src/utils/constants.d.ts +5 -0
  32. package/dist/declarations/src/utils/createError.d.ts +8 -0
  33. package/dist/declarations/src/utils/errors.d.ts +10 -0
  34. package/dist/declarations/src/utils/executor.d.ts +2 -0
  35. package/dist/declarations/src/utils/generateID.d.ts +1 -0
  36. package/dist/declarations/src/utils/headers.d.ts +2 -0
  37. package/dist/declarations/src/utils/index.d.ts +18 -0
  38. package/dist/declarations/src/utils/isBuffer.d.ts +1 -0
  39. package/dist/declarations/src/utils/maskAuthData.d.ts +2 -0
  40. package/dist/declarations/src/utils/mergeAuthHeader.d.ts +2 -0
  41. package/dist/declarations/src/utils/methods.d.ts +2 -0
  42. package/dist/declarations/src/utils/retryDelay.d.ts +8 -0
  43. package/dist/declarations/src/utils/sleep.d.ts +1 -0
  44. package/dist/declarations/src/utils/tokenCacheKey.d.ts +2 -0
  45. package/dist/declarations/src/utils/tokenExpirationTime.d.ts +1 -0
  46. package/dist/declarations/src/utils/tokenStore.d.ts +2 -0
  47. package/dist/declarations/src/utils/url.d.ts +2 -0
  48. package/dist/declarations/src/utils/userAgent.d.ts +2 -0
  49. package/dist/declarations/src/utils/validate.d.ts +25 -0
  50. package/package.json +5 -6
@@ -0,0 +1,1647 @@
1
+ import fetch$1 from 'node-fetch';
2
+ import crytpo from 'crypto';
3
+ import { Buffer } from 'buffer/';
4
+ import AbortController from 'abort-controller';
5
+
6
+ function _toPrimitive(input, hint) {
7
+ if (typeof input !== "object" || input === null) return input;
8
+ var prim = input[Symbol.toPrimitive];
9
+ if (prim !== undefined) {
10
+ var res = prim.call(input, hint || "default");
11
+ if (typeof res !== "object") return res;
12
+ throw new TypeError("@@toPrimitive must return a primitive value.");
13
+ }
14
+ return (hint === "string" ? String : Number)(input);
15
+ }
16
+
17
+ function _toPropertyKey(arg) {
18
+ var key = _toPrimitive(arg, "string");
19
+ return typeof key === "symbol" ? key : String(key);
20
+ }
21
+
22
+ function _defineProperty(obj, key, value) {
23
+ key = _toPropertyKey(key);
24
+ if (key in obj) {
25
+ Object.defineProperty(obj, key, {
26
+ value: value,
27
+ enumerable: true,
28
+ configurable: true,
29
+ writable: true
30
+ });
31
+ } else {
32
+ obj[key] = value;
33
+ }
34
+ return obj;
35
+ }
36
+
37
+ const HEADERS_CONTENT_TYPES = ['application/json', 'application/graphql'];
38
+ const CONCURRENCT_REQUEST = 20;
39
+ const CTP_API_URL = 'https://api.europe-west1.gcp.commercetools.com';
40
+ const CTP_AUTH_URL = 'https://auth.europe-west1.gcp.commercetools.com';
41
+ const DEFAULT_HEADERS = ['content-type', 'access-control-allow-origin', 'access-control-allow-headers', 'access-control-allow-methods', 'access-control-expose-headers', 'access-control-max-ag', 'x-correlation-id', 'server-timing', 'date', 'server', 'transfer-encoding', 'access-control-max-age', 'content-encoding', 'x-envoy-upstream-service-time', 'via', 'alt-svc', 'connection'];
42
+
43
+ function DefineError(statusCode, message, meta = {}) {
44
+ // eslint-disable-next-line no-multi-assign
45
+ this.status = this.statusCode = this.code = statusCode;
46
+ this.message = message;
47
+ Object.assign(this, meta);
48
+ this.name = this.constructor.name;
49
+ // eslint-disable-next-line no-proto
50
+ this.constructor.prototype.__proto__ = Error.prototype;
51
+ if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
52
+ }
53
+ function NetworkError(...args) {
54
+ DefineError.call(this, 0, ...args);
55
+ }
56
+ function HttpError(...args) {
57
+ DefineError.call(this, ...args);
58
+ }
59
+ function BadRequest(...args) {
60
+ DefineError.call(this, 400, ...args);
61
+ }
62
+ function Unauthorized(...args) {
63
+ DefineError.call(this, 401, ...args);
64
+ }
65
+ function Forbidden(...args) {
66
+ DefineError.call(this, 403, ...args);
67
+ }
68
+ function NotFound(...args) {
69
+ DefineError.call(this, 404, ...args);
70
+ }
71
+ function ConcurrentModification(...args) {
72
+ DefineError.call(this, 409, ...args);
73
+ }
74
+ function InternalServerError(...args) {
75
+ DefineError.call(this, 500, ...args);
76
+ }
77
+ function ServiceUnavailable(...args) {
78
+ DefineError.call(this, 503, ...args);
79
+ }
80
+ function getErrorByCode(code) {
81
+ switch (code) {
82
+ case 0:
83
+ return NetworkError;
84
+ case 400:
85
+ return BadRequest;
86
+ case 401:
87
+ return Unauthorized;
88
+ case 403:
89
+ return Forbidden;
90
+ case 404:
91
+ return NotFound;
92
+ case 409:
93
+ return ConcurrentModification;
94
+ case 500:
95
+ return InternalServerError;
96
+ case 503:
97
+ return ServiceUnavailable;
98
+ default:
99
+ return undefined;
100
+ }
101
+ }
102
+
103
+ function createError({
104
+ statusCode,
105
+ message,
106
+ ...rest
107
+ }) {
108
+ var _rest$originalRequest;
109
+ let errorMessage = message || 'Unexpected non-JSON error response';
110
+ if (statusCode === 404) errorMessage = `URI not found: ${((_rest$originalRequest = rest.originalRequest) === null || _rest$originalRequest === void 0 ? void 0 : _rest$originalRequest.uri) || rest.uri}`;
111
+ const ResponseError = getErrorByCode(statusCode);
112
+ if (ResponseError) return new ResponseError(errorMessage, rest);
113
+ return new HttpError(statusCode, errorMessage, rest);
114
+ }
115
+
116
+ function predicate(retryCodes, response) {
117
+ return !
118
+ // retryCodes.includes(response?.error?.message) ||
119
+ [503, ...retryCodes].includes((response === null || response === void 0 ? void 0 : response.status) || (response === null || response === void 0 ? void 0 : response.statusCode));
120
+ }
121
+ async function executeHttpClientRequest(fetcher, config) {
122
+ async function sendRequest() {
123
+ const response = await fetcher({
124
+ ...config,
125
+ headers: {
126
+ ...config.headers
127
+ }
128
+ });
129
+
130
+ // validations and error handlings can also be done here
131
+ return response;
132
+ }
133
+
134
+ // Attempt to send the request.
135
+ return sendRequest().catch(error => Promise.reject(error));
136
+ }
137
+ async function executor(request) {
138
+ const {
139
+ url,
140
+ httpClient,
141
+ ...rest
142
+ } = request;
143
+ const data = await executeHttpClientRequest(async options => {
144
+ const {
145
+ enableRetry,
146
+ retryConfig
147
+ } = rest;
148
+ const {
149
+ retryCodes = [],
150
+ maxDelay = Infinity,
151
+ maxRetries = 3,
152
+ backoff = true,
153
+ retryDelay = 200
154
+ } = retryConfig || {};
155
+ let result,
156
+ data,
157
+ retryCount = 0;
158
+
159
+ // validate the `retryCodes` option
160
+ validateRetryCodes(retryCodes);
161
+ async function execute() {
162
+ return httpClient(url, {
163
+ ...rest,
164
+ ...options,
165
+ headers: {
166
+ ...rest.headers,
167
+ ...options.headers,
168
+ // axios header encoding
169
+ 'Accept-Encoding': 'application/json'
170
+ },
171
+ // for axios
172
+ ...(rest.body ? {
173
+ data: rest.body
174
+ } : {}),
175
+ withCredentials: options.credentialsMode === 'include'
176
+ });
177
+ }
178
+ async function executeWithRetry() {
179
+ // first attempt
180
+ let _response = await execute();
181
+ if (predicate(retryCodes, _response)) return _response;
182
+
183
+ // retry attempts
184
+ while (enableRetry && retryCount < maxRetries) {
185
+ retryCount++;
186
+ _response = await execute();
187
+ if (predicate(retryCodes, _response)) return _response;
188
+
189
+ // delay next execution
190
+ const timer = calculateRetryDelay({
191
+ retryCount,
192
+ retryDelay,
193
+ maxRetries,
194
+ backoff,
195
+ maxDelay
196
+ });
197
+ await sleep(timer);
198
+ }
199
+ return _response;
200
+ }
201
+ const response = await executeWithRetry();
202
+ try {
203
+ // try to parse the `fetch` response as text
204
+ if (response.text && typeof response.text == 'function') {
205
+ result = await response.text();
206
+ data = JSON.parse(result);
207
+ } else {
208
+ // axios response
209
+ data = response.data || response;
210
+ }
211
+ } catch (err) {
212
+ data = result;
213
+ }
214
+ return {
215
+ data,
216
+ retryCount,
217
+ statusCode: response.status || response.statusCode || data.statusCode,
218
+ headers: response.headers
219
+ };
220
+ },
221
+ /**
222
+ * get this object from the
223
+ * middleware options or from
224
+ * http client config
225
+ */
226
+ {});
227
+ return data;
228
+ }
229
+
230
+ // TODO: Polyfill crypto for browsers
231
+ function generateID() {
232
+ return crytpo.randomBytes(32).toString('base64').replace(/[\/\-=+]/gi, '');
233
+ }
234
+
235
+ function parse(headers) {
236
+ return DEFAULT_HEADERS.reduce((result, key) => {
237
+ let val = headers[key] ? headers[key] : typeof headers.get == 'function' ? headers.get(key) : null;
238
+ if (val) result[key] = val;
239
+ return result;
240
+ }, {});
241
+ }
242
+ function getHeaders(headers) {
243
+ if (!headers) return null;
244
+
245
+ // node-fetch
246
+ if (headers.raw && typeof headers.raw == 'function') return headers.raw();
247
+
248
+ // Tmp fix for Firefox until it supports iterables
249
+ if (!headers.forEach) return parse(headers);
250
+ return headers.forEach((value, name) => value);
251
+ }
252
+
253
+ function isBuffer(obj) {
254
+ return obj != null && obj.constructor != null && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj);
255
+ }
256
+
257
+ function maskAuthData(request) {
258
+ const _request = Object.assign({}, request);
259
+ if (_request !== null && _request !== void 0 && _request.headers) {
260
+ if (_request.headers.Authorization) {
261
+ _request.headers['Authorization'] = 'Bearer ********';
262
+ }
263
+ if (_request.headers.authorization) {
264
+ _request.headers['authorization'] = 'Bearer ********';
265
+ }
266
+ }
267
+ return _request;
268
+ }
269
+
270
+ function mergeAuthHeader(token, req) {
271
+ return {
272
+ ...req,
273
+ headers: {
274
+ ...req.headers,
275
+ Authorization: `Bearer ${token}`
276
+ }
277
+ };
278
+ }
279
+
280
+ 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'];
281
+
282
+ function calculateRetryDelay({
283
+ retryCount,
284
+ retryDelay,
285
+ // maxRetries,
286
+ backoff,
287
+ maxDelay
288
+ }) {
289
+ if (backoff) {
290
+ return retryCount !== 0 // do not increase if it's the first retry
291
+ ? Math.min(Math.round((Math.random() + 1) * retryDelay * 2 ** retryCount), maxDelay) : retryDelay;
292
+ }
293
+ return retryDelay;
294
+ }
295
+
296
+ function sleep(ms) {
297
+ return new Promise(resolve => {
298
+ setTimeout(resolve, ms);
299
+ });
300
+ }
301
+
302
+ function buildTokenCacheKey(options) {
303
+ var _options$credentials;
304
+ if (!(options !== null && options !== void 0 && (_options$credentials = options.credentials) !== null && _options$credentials !== void 0 && _options$credentials.clientId) || !options.projectKey || !options.host) throw new Error('Missing required options.');
305
+ return {
306
+ clientId: options.credentials.clientId,
307
+ host: options.host,
308
+ projectKey: options.projectKey
309
+ };
310
+ }
311
+
312
+ function calculateExpirationTime(expiresIn) {
313
+ return Date.now() +
314
+ // Add a gap of 5 minutes before expiration time.
315
+ expiresIn * 1000 - 5 * 60 * 1000;
316
+ }
317
+
318
+ function store(initVal) {
319
+ let value = initVal;
320
+ return {
321
+ get: TokenCacheOption => value,
322
+ set: (val, TokenCacheOption) => {
323
+ value = val;
324
+ }
325
+ };
326
+ }
327
+
328
+ // import { validateUserAgentOptions } from '../utils'
329
+
330
+ /*
331
+ This is the easiest way, for this use case, to detect if we're running in
332
+ Node.js or in a browser environment. In other cases, this won't be even a
333
+ problem as Rollup will provide the correct polyfill in the bundle.
334
+ The main advantage by doing it this way is that it allows to easily test
335
+ the code running in both environments, by overriding `global.window` in
336
+ the specific test.
337
+ */
338
+ const isBrowser = () => window.document && window.document.nodeType === 9;
339
+ function getSystemInfo() {
340
+ var _process;
341
+ if (isBrowser()) return window.navigator.userAgent;
342
+ const nodeVersion = ((_process = process) === null || _process === void 0 ? void 0 : _process.version.slice(1)) || 'unknow'; // unknow environment like React Native etc
343
+ const platformInfo = `(${process.platform}; ${process.arch})`;
344
+
345
+ // return `node.js/${nodeVersion}`
346
+ return `node.js/${nodeVersion} ${platformInfo}`;
347
+ }
348
+ function createUserAgent(options) {
349
+ let libraryInfo = null;
350
+ let contactInfo = null;
351
+
352
+ // validateUserAgentOptions(options)
353
+ if (!options) {
354
+ throw new Error('Missing required option `name`');
355
+ }
356
+
357
+ // Main info
358
+ const baseInfo = options.version ? `${options.name}/${options.version}` : options.name;
359
+
360
+ // Library info
361
+ if (options.libraryName && !options.libraryVersion) {
362
+ libraryInfo = options.libraryName;
363
+ } else if (options.libraryName && options.libraryVersion) {
364
+ libraryInfo = `${options.libraryName}/${options.libraryVersion}`;
365
+ }
366
+
367
+ // Contact info
368
+ if (options.contactUrl && !options.contactEmail) {
369
+ contactInfo = `(+${options.contactUrl})`;
370
+ } else if (!options.contactUrl && options.contactEmail) {
371
+ contactInfo = `(+${options.contactEmail})`;
372
+ } else if (options.contactUrl && options.contactEmail) {
373
+ contactInfo = `(+${options.contactUrl}; +${options.contactEmail})`;
374
+ }
375
+
376
+ // System info
377
+ const systemInfo = getSystemInfo();
378
+
379
+ // customName
380
+ const customAgent = options.customAgent || '';
381
+ return [baseInfo, systemInfo, libraryInfo, contactInfo, customAgent].filter(Boolean).join(' ');
382
+ }
383
+
384
+ function urlParser(url) {
385
+ const object = {};
386
+ const data = new URLSearchParams(url);
387
+ for (let x of data.keys()) {
388
+ if (data.getAll(x).length > 1) {
389
+ object[x] = data.getAll(x);
390
+ } else {
391
+ object[x] = data.get(x);
392
+ }
393
+ }
394
+ return object;
395
+ }
396
+ function urlStringifier(object) {
397
+ const params = new URLSearchParams(object);
398
+ for (const [key, value] of Object.entries(object)) {
399
+ if (Array.isArray(value)) {
400
+ params.delete(key);
401
+ value.filter(Boolean).forEach(v => params.append(key, v));
402
+ }
403
+ }
404
+ return params.toString();
405
+ }
406
+ function parseURLString(url, parser = urlParser) {
407
+ return parser(url);
408
+ }
409
+ function stringifyURLString(object, stringifier = urlStringifier) {
410
+ return urlStringifier(object);
411
+ }
412
+
413
+ /**
414
+ * validate some essential http options
415
+ * @param options
416
+ */
417
+ function validateHttpOptions(options) {
418
+ 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`');
419
+ 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.');
420
+ 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.');
421
+ }
422
+
423
+ /**
424
+ *
425
+ * @param retryCodes
426
+ * @example
427
+ * const retryCodes = [500, 504, "ETIMEDOUT"]
428
+ */
429
+ function validateRetryCodes(retryCodes) {
430
+ if (!Array.isArray(retryCodes)) {
431
+ throw new Error('`retryCodes` option must be an array of retry status (error) codes and/or messages.');
432
+ }
433
+ }
434
+
435
+ /**
436
+ * @param options
437
+ */
438
+ function validateClient(options) {
439
+ if (!options) throw new Error('Missing required options');
440
+ if (options.middlewares && !Array.isArray(options.middlewares)) throw new Error('Middlewares should be an array');
441
+ if (!options.middlewares || !Array.isArray(options.middlewares) || !options.middlewares.length) {
442
+ throw new Error('You need to provide at least one middleware');
443
+ }
444
+ }
445
+
446
+ /**
447
+ * @param options
448
+ */
449
+ function validate(funcName, request, options = {
450
+ allowedMethods: METHODS
451
+ }) {
452
+ if (!request) throw new Error(`The "${funcName}" function requires a "Request" object as an argument. See https://commercetools.github.io/nodejs/sdk/Glossary.html#clientrequest`);
453
+ if (typeof request.uri !== 'string') throw new Error(`The "${funcName}" Request object requires a valid uri. See https://commercetools.github.io/nodejs/sdk/Glossary.html#clientrequest`);
454
+ 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`);
455
+ }
456
+
457
+ /**
458
+ *
459
+ * @param {AuthMiddlewareOptions} options
460
+ * @returns { IBuiltRequestParams } *
461
+ */
462
+ function buildRequestForClientCredentialsFlow(options) {
463
+ // Validate options
464
+ if (!options) throw new Error('Missing required options');
465
+ if (!options.host) throw new Error('Missing required option (host)');
466
+ if (!options.projectKey) throw new Error('Missing required option (projectKey)');
467
+ if (!options.credentials) throw new Error('Missing required option (credentials)');
468
+ const {
469
+ clientId,
470
+ clientSecret
471
+ } = options.credentials || {};
472
+ if (!(clientId && clientSecret)) throw new Error('Missing required credentials (clientId, clientSecret)');
473
+ const scope = options.scopes ? options.scopes.join(' ') : undefined;
474
+ const basicAuth = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
475
+ // This is mostly useful for internal testing purposes to be able to check
476
+ // other oauth endpoints.
477
+ const oauthUri = options.oauthUri || '/oauth/token';
478
+ const url = options.host.replace(/\/$/, '') + oauthUri;
479
+ const body = `grant_type=client_credentials${scope ? `&scope=${scope}` : ''}`;
480
+ return {
481
+ url,
482
+ body,
483
+ basicAuth
484
+ };
485
+ }
486
+
487
+ /**
488
+ *
489
+ * @param {AuthMiddlewareOptions} options
490
+ * @returns {IBuiltRequestParams} *
491
+ */
492
+ function buildRequestForAnonymousSessionFlow(options) {
493
+ if (!options) throw new Error('Missing required options');
494
+ if (!options.projectKey) throw new Error('Missing required option (projectKey)');
495
+ const projectKey = options.projectKey;
496
+ options.oauthUri = options.oauthUri || `/oauth/${projectKey}/anonymous/token`;
497
+ const result = buildRequestForClientCredentialsFlow(options);
498
+ if (options.credentials.anonymousId) result.body += `&anonymous_id=${options.credentials.anonymousId}`;
499
+ return {
500
+ ...result
501
+ };
502
+ }
503
+
504
+ /**
505
+ *
506
+ * @param {RefreshAuthMiddlewareOptions} options
507
+ * @returns {IBuiltRequestParams}
508
+ */
509
+ function buildRequestForRefreshTokenFlow(options) {
510
+ if (!options) throw new Error('Missing required options');
511
+ if (!options.host) throw new Error('Missing required option (host)');
512
+ if (!options.projectKey) throw new Error('Missing required option (projectKey)');
513
+ if (!options.credentials) throw new Error('Missing required option (credentials)');
514
+ if (!options.refreshToken) throw new Error('Missing required option (refreshToken)');
515
+ const {
516
+ clientId,
517
+ clientSecret
518
+ } = options.credentials;
519
+ if (!(clientId && clientSecret)) throw new Error('Missing required credentials (clientId, clientSecret)');
520
+ const basicAuth = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
521
+ // This is mostly useful for internal testing purposes to be able to check
522
+ // other oauth endpoints.
523
+ const oauthUri = options.oauthUri || '/oauth/token';
524
+ const url = options.host.replace(/\/$/, '') + oauthUri;
525
+ const body = `grant_type=refresh_token&refresh_token=${encodeURIComponent(options.refreshToken)}`;
526
+ return {
527
+ basicAuth,
528
+ url,
529
+ body
530
+ };
531
+ }
532
+
533
+ /**
534
+ * @param {PasswordAuthMiddlewareOptions} options
535
+ * @returns {IBuiltRequestParams}
536
+ */
537
+ function buildRequestForPasswordFlow(options) {
538
+ if (!options) throw new Error('Missing required options');
539
+ if (!options.host) throw new Error('Missing required option (host)');
540
+ if (!options.projectKey) throw new Error('Missing required option (projectKey)');
541
+ if (!options.credentials) throw new Error('Missing required option (credentials)');
542
+ const {
543
+ clientId,
544
+ clientSecret,
545
+ user
546
+ } = options.credentials;
547
+ const projectKey = options.projectKey;
548
+ if (!(clientId && clientSecret && user)) throw new Error('Missing required credentials (clientId, clientSecret, user)');
549
+ const {
550
+ username,
551
+ password
552
+ } = user;
553
+ if (!(username && password)) throw new Error('Missing required user credentials (username, password)');
554
+ const scope = (options.scopes || []).join(' ');
555
+ const scopeStr = scope ? `&scope=${scope}` : '';
556
+ const basicAuth = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
557
+
558
+ /**
559
+ * This is mostly useful for internal testing purposes to be able to check
560
+ * other oauth endpoints.
561
+ */
562
+ const oauthUri = options.oauthUri || `/oauth/${projectKey}/customers/token`;
563
+ const url = options.host.replace(/\/$/, '') + oauthUri;
564
+
565
+ // encode username and password as requested by the system
566
+ const body = `grant_type=password&username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}${scopeStr}`;
567
+ return {
568
+ basicAuth,
569
+ url,
570
+ body
571
+ };
572
+ }
573
+
574
+ async function executeRequest$1(options) {
575
+ const {
576
+ request,
577
+ httpClient,
578
+ tokenCache,
579
+ tokenCacheKey,
580
+ requestState,
581
+ userOption,
582
+ next
583
+ } = options;
584
+ let url = options.url;
585
+ let body = options.body;
586
+ let basicAuth = options.basicAuth;
587
+
588
+ // get the pending object from option
589
+ let pendingTasks = options.pendingTasks;
590
+ if (!httpClient || typeof 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.');
591
+
592
+ /**
593
+ * If there is a token in the tokenCache, and it's not
594
+ * expired, append the token in the `Authorization` header.
595
+ */
596
+ const tokenCacheObject = tokenCache.get(tokenCacheKey);
597
+ if (tokenCacheObject && tokenCacheObject.token && Date.now() < tokenCacheObject.expirationTime) {
598
+ const requestWithAuth = mergeAuthHeader(tokenCacheObject.token, request);
599
+ return {
600
+ ...requestWithAuth
601
+ };
602
+ }
603
+
604
+ /**
605
+ * Keep pending tasks until a token is fetched
606
+ * Save next function as well, to call it once the token has been fetched, which prevents
607
+ * unexpected behaviour in a context in which the next function uses global vars
608
+ * or Promises to capture the token to hand it to other libraries, e.g. Apollo
609
+ */
610
+ pendingTasks.push({
611
+ request,
612
+ next
613
+ });
614
+
615
+ // if a token is currently being fetched, then wait
616
+ if (requestState.get()) return;
617
+
618
+ // signal that a token is being fetched
619
+ requestState.set(true);
620
+
621
+ /**
622
+ * use refreshToken flow if there is refresh-token
623
+ * and there's either no token or the token is expired
624
+ */
625
+ if (tokenCacheObject && tokenCacheObject.refreshToken && (!tokenCacheObject.token || tokenCacheObject.token && Date.now() > tokenCacheObject.expirationTime)) {
626
+ if (!userOption) throw new Error('Missing required options.');
627
+ const opt = {
628
+ ...buildRequestForRefreshTokenFlow({
629
+ ...userOption,
630
+ refreshToken: tokenCacheObject.refreshToken
631
+ })
632
+ };
633
+
634
+ // reassign values
635
+ url = opt.url;
636
+ body = opt.body;
637
+ basicAuth = opt.basicAuth;
638
+ }
639
+
640
+ // request a new token
641
+ let response;
642
+ try {
643
+ response = await executor({
644
+ url,
645
+ method: 'POST',
646
+ headers: {
647
+ Authorization: `Basic ${basicAuth}`,
648
+ 'Content-Type': 'application/x-www-form-urlencoded',
649
+ 'Conent-Length': Buffer.byteLength(body).toString()
650
+ },
651
+ httpClient,
652
+ body
653
+ });
654
+ if (response.statusCode >= 200 && response.statusCode < 300) {
655
+ var _response;
656
+ const {
657
+ access_token: token,
658
+ expires_in: expiresIn,
659
+ refresh_token: refreshToken
660
+ } = (_response = response) === null || _response === void 0 ? void 0 : _response.data;
661
+
662
+ // calculate token expiration time
663
+ const expirationTime = calculateExpirationTime(expiresIn);
664
+
665
+ // cache new generated token, refreshToken and expiration time
666
+ tokenCache.set({
667
+ token,
668
+ expirationTime,
669
+ refreshToken
670
+ });
671
+
672
+ // signal that a token fetch is complete
673
+ requestState.set(false);
674
+
675
+ /**
676
+ * Freeze and copy pending queue, reset
677
+ * original one for accepting new pending tasks
678
+ */
679
+ const requestQueue = pendingTasks.slice();
680
+
681
+ // reset pendingTask queue
682
+ pendingTasks = [];
683
+ if (requestQueue.length === 1) {
684
+ return mergeAuthHeader(token, requestQueue.pop().request);
685
+ }
686
+
687
+ // execute all pending tasks if any
688
+ for (let i = 0; i < requestQueue.length; i++) {
689
+ const task = requestQueue[i];
690
+ const requestWithAuth = mergeAuthHeader(token, task.request);
691
+
692
+ // execute task
693
+ task.next(requestWithAuth);
694
+ }
695
+ return;
696
+ }
697
+ const error = new Error(response.data.message ? response.data.message : JSON.stringify(response.data));
698
+ /**
699
+ * reject the error immediately
700
+ * and free up the middleware chain
701
+ */
702
+ request.reject({
703
+ ...request,
704
+ headers: {
705
+ ...request.headers
706
+ },
707
+ response: {
708
+ statusCode: response.statusCode || response.data.statusCode,
709
+ error: {
710
+ error,
711
+ body: response
712
+ }
713
+ }
714
+ });
715
+ } catch (error) {
716
+ return {
717
+ ...request,
718
+ headers: {
719
+ ...request.headers
720
+ },
721
+ response: {
722
+ body: null,
723
+ statusCode: error.statusCode || 0,
724
+ error: {
725
+ ...response,
726
+ error,
727
+ body: response
728
+ }
729
+ }
730
+ };
731
+ }
732
+ }
733
+
734
+ function createAuthMiddlewareForAnonymousSessionFlow$1(options) {
735
+ const pendingTasks = [];
736
+ const requestState = store(false);
737
+ const tokenCache = options.tokenCache || store({
738
+ token: '',
739
+ expirationTime: -1
740
+ });
741
+ const tokenCacheKey = buildTokenCacheKey(options);
742
+ return next => {
743
+ return async request => {
744
+ // if here is a token in the header, then move on to the next middleware
745
+ if (request.headers && (request.headers.Authorization || request.headers.authorization)) {
746
+ // move on
747
+ return next(request);
748
+ }
749
+
750
+ // prepare request options
751
+ const requestOptions = {
752
+ request,
753
+ requestState,
754
+ tokenCache,
755
+ pendingTasks,
756
+ tokenCacheKey,
757
+ httpClient: options.httpClient || fetch$1,
758
+ ...buildRequestForAnonymousSessionFlow(options),
759
+ userOption: options,
760
+ next
761
+ };
762
+
763
+ // make request to coco
764
+ const requestWithAuth = await executeRequest$1(requestOptions);
765
+ if (requestWithAuth) {
766
+ return next(requestWithAuth);
767
+ }
768
+ };
769
+ };
770
+ }
771
+
772
+ function createAuthMiddlewareForClientCredentialsFlow$1(options) {
773
+ const requestState = store(false);
774
+ const pendingTasks = [];
775
+ const tokenCache = options.tokenCache || store({
776
+ token: '',
777
+ expirationTime: -1
778
+ });
779
+ const tokenCacheKey = buildTokenCacheKey(options);
780
+ return next => {
781
+ return async request => {
782
+ // if here is a token in the header, then move on to the next middleware
783
+ if (request.headers && (request.headers.Authorization || request.headers.authorization)) {
784
+ // move on
785
+ return next(request);
786
+ }
787
+
788
+ // prepare request options
789
+ const requestOptions = {
790
+ request,
791
+ requestState,
792
+ tokenCache,
793
+ pendingTasks,
794
+ tokenCacheKey,
795
+ httpClient: options.httpClient || fetch$1,
796
+ ...buildRequestForClientCredentialsFlow(options),
797
+ next
798
+ };
799
+
800
+ // make request to coco
801
+ const requestWithAuth = await executeRequest$1(requestOptions);
802
+ if (requestWithAuth) {
803
+ // make the request and inject the token into the header
804
+ return next(requestWithAuth);
805
+ }
806
+ };
807
+ };
808
+ }
809
+
810
+ function createAuthMiddlewareForExistingTokenFlow$1(authorization, options) {
811
+ return next => {
812
+ return async request => {
813
+ if (typeof authorization !== 'string') throw new Error('authorization must be a string');
814
+ const isForce = (options === null || options === void 0 ? void 0 : options.force) === undefined ? true : options.force;
815
+
816
+ /**
817
+ * The request will not be modified if:
818
+ * 1. no argument is passed
819
+ * 2. force is false and authorization header exists
820
+ */
821
+ if (!authorization || request.headers && (request.headers.Authorization || request.headers.authorization) && isForce === false) {
822
+ return next(request);
823
+ }
824
+ const requestWithAuth = {
825
+ ...request,
826
+ headers: {
827
+ ...request.headers,
828
+ Authorization: authorization
829
+ }
830
+ };
831
+ return next(requestWithAuth);
832
+ };
833
+ };
834
+ }
835
+
836
+ function createAuthMiddlewareForPasswordFlow$1(options) {
837
+ const tokenCache = options.tokenCache || store({
838
+ token: '',
839
+ expirationTime: -1
840
+ });
841
+ const pendingTasks = [];
842
+ const requestState = store(false);
843
+ const tokenCacheKey = buildTokenCacheKey(options);
844
+ return next => {
845
+ return async request => {
846
+ if (request.headers && (request.headers.Authorization || request.headers.authorization)) {
847
+ return next(request);
848
+ }
849
+ const requestOptions = {
850
+ request,
851
+ requestState,
852
+ tokenCache,
853
+ pendingTasks,
854
+ tokenCacheKey,
855
+ httpClient: options.httpClient || fetch$1,
856
+ ...buildRequestForPasswordFlow(options),
857
+ userOption: options,
858
+ next
859
+ };
860
+
861
+ // make request to coco
862
+ const requestWithAuth = await executeRequest$1(requestOptions);
863
+ if (requestWithAuth) {
864
+ return next(requestWithAuth);
865
+ }
866
+ };
867
+ };
868
+ }
869
+
870
+ function createAuthMiddlewareForRefreshTokenFlow$1(options) {
871
+ const tokenCache = options.tokenCache || store({
872
+ token: '',
873
+ tokenCacheKey: null
874
+ });
875
+ const pendingTasks = [];
876
+ const requestState = store(false);
877
+ return next => {
878
+ return async request => {
879
+ if (request.headers && (request.headers.Authorization || request.headers.authorization)) {
880
+ return next(request);
881
+ }
882
+
883
+ // prepare request options
884
+ const requestOptions = {
885
+ request,
886
+ requestState,
887
+ tokenCache,
888
+ pendingTasks,
889
+ httpClient: options.httpClient || fetch,
890
+ ...buildRequestForRefreshTokenFlow(options),
891
+ next
892
+ };
893
+
894
+ // make request to coco
895
+ const requestWithAuth = await executeRequest$1(requestOptions);
896
+ if (requestWithAuth) {
897
+ return next(requestWithAuth);
898
+ }
899
+ };
900
+ };
901
+ }
902
+
903
+ function createConcurrentModificationMiddleware$1() {
904
+ return next => {
905
+ return async request => {
906
+ const response = await next(request);
907
+ if (response.statusCode == 409) {
908
+ var _response$error, _response$error$body, _response$error$body$, _response$error$body$2;
909
+ /**
910
+ * extract the currentVersion
911
+ * from the error body and update
912
+ * request with the currentVersion
913
+ */
914
+ const version = (_response$error = response.error) === null || _response$error === void 0 ? void 0 : (_response$error$body = _response$error.body) === null || _response$error$body === void 0 ? void 0 : (_response$error$body$ = _response$error$body.errors) === null || _response$error$body$ === void 0 ? void 0 : (_response$error$body$2 = _response$error$body$[0]) === null || _response$error$body$2 === void 0 ? void 0 : _response$error$body$2.currentVersion;
915
+
916
+ // update the resource version here
917
+ if (version) {
918
+ request.body = typeof request.body == 'string' ? {
919
+ ...JSON.parse(request.body),
920
+ version
921
+ } : {
922
+ ...request.body,
923
+ version
924
+ };
925
+ return next(request);
926
+ }
927
+ }
928
+ return response;
929
+ };
930
+ };
931
+ }
932
+
933
+ function createCorrelationIdMiddleware$1(options) {
934
+ return next => request => {
935
+ const nextRequest = {
936
+ ...request,
937
+ headers: {
938
+ ...request.headers,
939
+ 'X-Correlation-ID': options.generate && typeof options.generate == 'function' ? options.generate() : generateID()
940
+ }
941
+ };
942
+ return next(nextRequest);
943
+ };
944
+ }
945
+
946
+ function createErrorMiddleware$1(options) {
947
+ return next => async request => {
948
+ const response = await next(request);
949
+ if (response.error) {
950
+ const {
951
+ error
952
+ } = response;
953
+ return {
954
+ ...response,
955
+ statusCode: error.statusCode || 0,
956
+ headers: error.headers || getHeaders({}),
957
+ error: {
958
+ ...error,
959
+ body: error.data || error
960
+ }
961
+ };
962
+ }
963
+ return response;
964
+ };
965
+ }
966
+
967
+ async function executeRequest({
968
+ url,
969
+ httpClient,
970
+ clientOptions
971
+ }) {
972
+ let timer;
973
+ const {
974
+ timeout,
975
+ request,
976
+ abortController,
977
+ maskSensitiveHeaderData,
978
+ includeRequestInErrorResponse
979
+ } = clientOptions;
980
+ try {
981
+ var _response$data, _response$data2;
982
+ if (timeout) timer = setTimeout(() => {
983
+ abortController.abort();
984
+ }, timeout);
985
+ const response = await executor({
986
+ url,
987
+ ...clientOptions,
988
+ httpClient,
989
+ method: clientOptions.method,
990
+ ...(clientOptions.body ? {
991
+ body: clientOptions.body
992
+ } : {})
993
+ });
994
+ if (response.statusCode >= 200 && response.statusCode < 300) {
995
+ if (clientOptions.method == 'HEAD') {
996
+ return {
997
+ body: null,
998
+ statusCode: response.statusCode,
999
+ retryCount: response.retryCount,
1000
+ headers: getHeaders(response.headers)
1001
+ };
1002
+ }
1003
+ return {
1004
+ body: response.data,
1005
+ statusCode: response.statusCode,
1006
+ retryCount: response.retryCount,
1007
+ headers: getHeaders(response.headers)
1008
+ };
1009
+ }
1010
+ const error = createError({
1011
+ message: (response === null || response === void 0 ? void 0 : (_response$data = response.data) === null || _response$data === void 0 ? void 0 : _response$data.message) || (response === null || response === void 0 ? void 0 : response.message),
1012
+ statusCode: response.statusCode || (response === null || response === void 0 ? void 0 : (_response$data2 = response.data) === null || _response$data2 === void 0 ? void 0 : _response$data2.statusCode),
1013
+ headers: getHeaders(response.headers),
1014
+ method: clientOptions.method,
1015
+ body: response.data,
1016
+ retryCount: response.retryCount,
1017
+ ...(includeRequestInErrorResponse ? {
1018
+ originalRequest: maskSensitiveHeaderData ? maskAuthData(request) : request
1019
+ } : {
1020
+ uri: request.uri
1021
+ })
1022
+ });
1023
+
1024
+ /**
1025
+ * handle non-ok (error) response
1026
+ * build error body
1027
+ */
1028
+ return {
1029
+ body: response.data,
1030
+ code: response.statusCode,
1031
+ statusCode: response.statusCode,
1032
+ headers: getHeaders(response.headers),
1033
+ error
1034
+ };
1035
+ } catch (e) {
1036
+ var _e$response, _e$response2, _e$response3, _e$response4, _e$response4$data, _e$response5, _e$response6;
1037
+ // We know that this is a network error
1038
+ const headers = getHeaders((_e$response = e.response) === null || _e$response === void 0 ? void 0 : _e$response.headers);
1039
+ const statusCode = ((_e$response2 = e.response) === null || _e$response2 === void 0 ? void 0 : _e$response2.status) || ((_e$response3 = e.response) === null || _e$response3 === void 0 ? void 0 : _e$response3.data0) || 0;
1040
+ const message = (_e$response4 = e.response) === null || _e$response4 === void 0 ? void 0 : (_e$response4$data = _e$response4.data) === null || _e$response4$data === void 0 ? void 0 : _e$response4$data.message;
1041
+ const error = createError({
1042
+ statusCode,
1043
+ code: statusCode,
1044
+ status: statusCode,
1045
+ message: message || e.message,
1046
+ headers,
1047
+ body: ((_e$response5 = e.response) === null || _e$response5 === void 0 ? void 0 : _e$response5.data) || e,
1048
+ error: (_e$response6 = e.response) === null || _e$response6 === void 0 ? void 0 : _e$response6.data,
1049
+ ...(includeRequestInErrorResponse ? {
1050
+ originalRequest: maskSensitiveHeaderData ? maskAuthData(request) : request
1051
+ } : {
1052
+ uri: request.uri
1053
+ })
1054
+ });
1055
+ return {
1056
+ body: error,
1057
+ error
1058
+ };
1059
+ } finally {
1060
+ clearTimeout(timer);
1061
+ }
1062
+ }
1063
+ function createHttpMiddleware$1(options) {
1064
+ // validate response
1065
+ validateHttpOptions(options);
1066
+ const {
1067
+ host,
1068
+ credentialsMode,
1069
+ httpClient,
1070
+ timeout,
1071
+ enableRetry,
1072
+ retryConfig,
1073
+ getAbortController,
1074
+ includeOriginalRequest,
1075
+ includeRequestInErrorResponse,
1076
+ maskSensitiveHeaderData,
1077
+ httpClientOptions
1078
+ } = options;
1079
+ return next => {
1080
+ return async request => {
1081
+ let abortController;
1082
+ if (timeout || getAbortController) abortController = (getAbortController ? getAbortController() : null) || new AbortController();
1083
+ const url = host.replace(/\/$/, '') + request.uri;
1084
+ const requestHeader = {
1085
+ ...request.headers
1086
+ };
1087
+
1088
+ // validate header
1089
+ if (!(Object.prototype.hasOwnProperty.call(requestHeader, 'Content-Type') || Object.prototype.hasOwnProperty.call(requestHeader, 'content-type'))) {
1090
+ requestHeader['Content-Type'] = 'application/json';
1091
+ }
1092
+
1093
+ // Unset the content-type header if explicitly asked to (passing `null` as value).
1094
+ if (requestHeader['Content-Type'] === null) {
1095
+ delete requestHeader['Content-Type'];
1096
+ }
1097
+
1098
+ // Ensure body is a string if content type is application/{json|graphql}
1099
+ const body = HEADERS_CONTENT_TYPES.indexOf(requestHeader['Content-Type']) > -1 && typeof request.body === 'string' || isBuffer(request.body) ? request.body : JSON.stringify(request.body || undefined);
1100
+ if (body && (typeof body === 'string' || isBuffer(body))) {
1101
+ requestHeader['Content-Length'] = Buffer.byteLength(body).toString();
1102
+ }
1103
+ const clientOptions = {
1104
+ enableRetry,
1105
+ retryConfig,
1106
+ request: request,
1107
+ method: request.method,
1108
+ headers: requestHeader,
1109
+ includeRequestInErrorResponse,
1110
+ maskSensitiveHeaderData,
1111
+ ...httpClientOptions
1112
+ };
1113
+ if (credentialsMode) {
1114
+ clientOptions.credentialsMode = credentialsMode;
1115
+ }
1116
+ if (abortController) {
1117
+ clientOptions.signal = abortController.signal;
1118
+ }
1119
+ if (timeout) {
1120
+ clientOptions.timeout = timeout;
1121
+ clientOptions.abortController = abortController;
1122
+ }
1123
+ if (body) {
1124
+ clientOptions.body = body;
1125
+ }
1126
+
1127
+ // get result from executed request
1128
+ const response = await executeRequest({
1129
+ url,
1130
+ clientOptions,
1131
+ httpClient
1132
+ });
1133
+ const responseWithRequest = {
1134
+ ...request,
1135
+ includeOriginalRequest,
1136
+ maskSensitiveHeaderData,
1137
+ response
1138
+ };
1139
+ return next(responseWithRequest);
1140
+ };
1141
+ };
1142
+ }
1143
+
1144
+ // error, info, success
1145
+ function createLoggerMiddleware$1(options) {
1146
+ return next => {
1147
+ return async request => {
1148
+ let response = await next(request);
1149
+ const originalResponse = Object.assign({}, response);
1150
+ const {
1151
+ loggerFn = console.log,
1152
+ // logLevel = 'ERROR',
1153
+ maskSensitiveHeaderData = true,
1154
+ includeOriginalRequest = true,
1155
+ includeResponseHeaders = true
1156
+ // includeRequestInErrorResponse
1157
+ } = options || {};
1158
+ if (includeOriginalRequest && maskSensitiveHeaderData) {
1159
+ maskAuthData(response.request);
1160
+ }
1161
+ if (!includeOriginalRequest) {
1162
+ const {
1163
+ request,
1164
+ ...rest
1165
+ } = response;
1166
+ response = rest;
1167
+ }
1168
+ if (!includeResponseHeaders) {
1169
+ const {
1170
+ headers,
1171
+ ...rest
1172
+ } = response;
1173
+ response = rest;
1174
+ }
1175
+ if (loggerFn && typeof loggerFn == 'function') {
1176
+ loggerFn(response);
1177
+ // return originalResponse
1178
+ }
1179
+
1180
+ // console.log({ Response: response })
1181
+ return originalResponse;
1182
+ };
1183
+ };
1184
+ }
1185
+
1186
+ function createQueueMiddleware$1({
1187
+ concurrency = 20
1188
+ }) {
1189
+ let runningCount = 0;
1190
+ const queue = [];
1191
+ const dequeue = next => {
1192
+ runningCount--;
1193
+ if (queue.length && runningCount <= concurrency) {
1194
+ const nextTask = queue.shift();
1195
+ runningCount++;
1196
+ return next(nextTask.request);
1197
+ }
1198
+ };
1199
+ const enqueue = ({
1200
+ request
1201
+ }) => queue.push({
1202
+ request
1203
+ });
1204
+ return next => request => {
1205
+ // wrap and override resolve and reject functions
1206
+ const patchedRequest = {
1207
+ ...request,
1208
+ resolve(data) {
1209
+ request.resolve(data);
1210
+ dequeue(next);
1211
+ },
1212
+ reject(error) {
1213
+ request.reject(error);
1214
+ dequeue(next);
1215
+ }
1216
+ };
1217
+
1218
+ // enqueue requests
1219
+ enqueue({
1220
+ request: patchedRequest
1221
+ });
1222
+ if (runningCount < concurrency) {
1223
+ runningCount++;
1224
+ const nextTask = queue.shift();
1225
+ return next(nextTask.request);
1226
+ }
1227
+ };
1228
+ }
1229
+
1230
+ var packageJson = {
1231
+ name: "@commercetools/ts-client",
1232
+ version: "1.1.0",
1233
+ engines: {
1234
+ node: ">=14"
1235
+ },
1236
+ description: "commercetools Composable Commerce TypeScript SDK client.",
1237
+ keywords: [
1238
+ "commercetools",
1239
+ "composable commerce",
1240
+ "sdk",
1241
+ "typescript",
1242
+ "client",
1243
+ "middleware",
1244
+ "http",
1245
+ "oauth",
1246
+ "auth"
1247
+ ],
1248
+ homepage: "https://github.com/commercetools/commercetools-sdk-typescript",
1249
+ license: "MIT",
1250
+ directories: {
1251
+ lib: "lib",
1252
+ test: "test"
1253
+ },
1254
+ publishConfig: {
1255
+ access: "public"
1256
+ },
1257
+ repository: {
1258
+ type: "git",
1259
+ url: "git+https://github.com/commercetools/commercetools-sdk-typescript.git"
1260
+ },
1261
+ bugs: {
1262
+ url: "https://github.com/commercetools/commercetools-sdk-typescript/issues"
1263
+ },
1264
+ dependencies: {
1265
+ "abort-controller": "3.0.0",
1266
+ buffer: "^6.0.3",
1267
+ "node-fetch": "^2.6.1"
1268
+ },
1269
+ files: [
1270
+ "dist",
1271
+ "CHANGELOG.md"
1272
+ ],
1273
+ author: "Chukwuemeka Ajima <meeky.ae@gmail.com>",
1274
+ main: "dist/commercetools-ts-client.cjs.js",
1275
+ module: "dist/commercetools-ts-client.esm.js",
1276
+ browser: {
1277
+ "./dist/commercetools-ts-client.cjs.js": "./dist/commercetools-ts-client.browser.cjs.js",
1278
+ "./dist/commercetools-ts-client.esm.js": "./dist/commercetools-ts-client.browser.esm.js"
1279
+ },
1280
+ devDependencies: {
1281
+ "common-tags": "1.8.2",
1282
+ dotenv: "16.0.3",
1283
+ jest: "29.5.0",
1284
+ nock: "12.0.3",
1285
+ "organize-imports-cli": "0.10.0"
1286
+ },
1287
+ scripts: {
1288
+ organize_imports: "find src -type f -name '*.ts' | xargs organize-imports-cli",
1289
+ postbuild: "yarn organize_imports",
1290
+ post_process_generate: "yarn organize_imports"
1291
+ }
1292
+ };
1293
+
1294
+ function createUserAgentMiddleware$1(options) {
1295
+ return next => async request => {
1296
+ const userAgent = createUserAgent({
1297
+ ...options,
1298
+ name: `commercetools-sdk-javascript-v3/${packageJson.version}`
1299
+ });
1300
+ const requestWithUserAgent = {
1301
+ ...request,
1302
+ headers: {
1303
+ ...request.headers,
1304
+ 'User-Agent': userAgent
1305
+ }
1306
+ };
1307
+ return next(requestWithUserAgent);
1308
+ };
1309
+ }
1310
+
1311
+ var middleware = /*#__PURE__*/Object.freeze({
1312
+ __proto__: null,
1313
+ createAuthMiddlewareForAnonymousSessionFlow: createAuthMiddlewareForAnonymousSessionFlow$1,
1314
+ createAuthMiddlewareForClientCredentialsFlow: createAuthMiddlewareForClientCredentialsFlow$1,
1315
+ createAuthMiddlewareForExistingTokenFlow: createAuthMiddlewareForExistingTokenFlow$1,
1316
+ createAuthMiddlewareForPasswordFlow: createAuthMiddlewareForPasswordFlow$1,
1317
+ createAuthMiddlewareForRefreshTokenFlow: createAuthMiddlewareForRefreshTokenFlow$1,
1318
+ createConcurrentModificationMiddleware: createConcurrentModificationMiddleware$1,
1319
+ createCorrelationIdMiddleware: createCorrelationIdMiddleware$1,
1320
+ createErrorMiddleware: createErrorMiddleware$1,
1321
+ createHttpMiddleware: createHttpMiddleware$1,
1322
+ createLoggerMiddleware: createLoggerMiddleware$1,
1323
+ createQueueMiddleware: createQueueMiddleware$1,
1324
+ createUserAgentMiddleware: createUserAgentMiddleware$1
1325
+ });
1326
+
1327
+ function compose({
1328
+ middlewares
1329
+ }) {
1330
+ if (middlewares.length === 1) return middlewares[0];
1331
+ const _middlewares = middlewares.slice();
1332
+ return _middlewares.reduce((ac, cv) => (...args) => ac(cv.apply(null, args)));
1333
+ }
1334
+
1335
+ // process batch requests
1336
+ let _options;
1337
+ function process$1(request, fn, processOpt) {
1338
+ validate('process', request, {
1339
+ allowedMethods: ['GET']
1340
+ });
1341
+ 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');
1342
+
1343
+ // Set default process options
1344
+ const opt = {
1345
+ total: Number.POSITIVE_INFINITY,
1346
+ accumulate: true,
1347
+ ...processOpt
1348
+ };
1349
+ return new Promise((resolve, reject) => {
1350
+ let _path,
1351
+ _queryString = '';
1352
+ if (request && request.uri) {
1353
+ const [path, queryString] = request.uri.split('?');
1354
+ _path = path;
1355
+ _queryString = queryString;
1356
+ }
1357
+ const requestQuery = {
1358
+ ...parseURLString(_queryString)
1359
+ };
1360
+ const query = {
1361
+ // defaults
1362
+ limit: 20,
1363
+ // merge given query params
1364
+ ...requestQuery
1365
+ };
1366
+ let itemsToGet = opt.total;
1367
+ let hasFirstPageBeenProcessed = false;
1368
+ const processPage = async (lastId, acc = []) => {
1369
+ // Use the lesser value between limit and itemsToGet in query
1370
+ const limit = query.limit < itemsToGet ? query.limit : itemsToGet;
1371
+ const originalQueryString = stringifyURLString({
1372
+ ...query,
1373
+ limit
1374
+ });
1375
+ const enhancedQuery = {
1376
+ sort: 'id asc',
1377
+ withTotal: false,
1378
+ ...(lastId ? {
1379
+ where: `id > "${lastId}"`
1380
+ } : {})
1381
+ };
1382
+ const enhancedQueryString = stringifyURLString(enhancedQuery);
1383
+ const enhancedRequest = {
1384
+ ...request,
1385
+ uri: `${_path}?${enhancedQueryString}&${originalQueryString}`
1386
+ };
1387
+ try {
1388
+ const payload = await createClient(_options).execute(enhancedRequest);
1389
+ const {
1390
+ results,
1391
+ count: resultsLength
1392
+ } = (payload === null || payload === void 0 ? void 0 : payload.body) || {};
1393
+ if (!resultsLength && hasFirstPageBeenProcessed) {
1394
+ return resolve(acc || []);
1395
+ }
1396
+ const result = await Promise.resolve(fn(payload));
1397
+ let accumulated;
1398
+ hasFirstPageBeenProcessed = true;
1399
+ if (opt.accumulate) accumulated = acc.concat(result || []);
1400
+ itemsToGet -= resultsLength;
1401
+ // If there are no more items to get, it means the total number
1402
+ // of items in the original request have been fetched so we
1403
+ // resolve the promise.
1404
+ // Also, if we get less results in a page then the limit set it
1405
+ // means that there are no more pages and that we can finally
1406
+ // resolve the promise.
1407
+ if (resultsLength < query.limit || !itemsToGet) {
1408
+ return resolve(accumulated || []);
1409
+ }
1410
+ const last = results[resultsLength - 1];
1411
+ const newLastId = last && last.id;
1412
+ processPage(newLastId, accumulated);
1413
+ } catch (error) {
1414
+ reject(error);
1415
+ }
1416
+ };
1417
+
1418
+ // Start iterating through pages
1419
+ processPage();
1420
+ });
1421
+ }
1422
+ function createClient(middlewares) {
1423
+ _options = middlewares;
1424
+ validateClient(middlewares);
1425
+ const resolver = {
1426
+ async resolve(rs) {
1427
+ const {
1428
+ response,
1429
+ includeOriginalRequest,
1430
+ maskSensitiveHeaderData,
1431
+ ...request
1432
+ } = rs;
1433
+ const {
1434
+ retryCount,
1435
+ ...rest
1436
+ } = response;
1437
+ const res = {
1438
+ body: null,
1439
+ error: null,
1440
+ reject: rs.reject,
1441
+ resolve: rs.resolve,
1442
+ ...rest,
1443
+ ...(includeOriginalRequest ? {
1444
+ originalRequest: maskSensitiveHeaderData ? maskAuthData(request) : request
1445
+ } : {}),
1446
+ ...(response !== null && response !== void 0 && response.retryCount ? {
1447
+ retryCount: response.retryCount
1448
+ } : {})
1449
+ };
1450
+ if (res.error) {
1451
+ res.reject(res.error);
1452
+ return res;
1453
+ }
1454
+ res.resolve(res);
1455
+ return res;
1456
+ }
1457
+ };
1458
+ const dispatch = compose(middlewares)(resolver.resolve);
1459
+ return {
1460
+ process: process$1,
1461
+ execute(request) {
1462
+ validate('exec', request);
1463
+ return new Promise((resolve, reject) => {
1464
+ return dispatch({
1465
+ reject,
1466
+ resolve,
1467
+ ...request
1468
+ });
1469
+ });
1470
+ }
1471
+ };
1472
+ }
1473
+
1474
+ const {
1475
+ createAuthMiddlewareForPasswordFlow,
1476
+ createAuthMiddlewareForAnonymousSessionFlow,
1477
+ createAuthMiddlewareForClientCredentialsFlow,
1478
+ createAuthMiddlewareForRefreshTokenFlow,
1479
+ createAuthMiddlewareForExistingTokenFlow,
1480
+ createCorrelationIdMiddleware,
1481
+ createHttpMiddleware,
1482
+ createLoggerMiddleware,
1483
+ createQueueMiddleware,
1484
+ createUserAgentMiddleware,
1485
+ createConcurrentModificationMiddleware,
1486
+ createErrorMiddleware
1487
+ } = middleware;
1488
+ class ClientBuilder {
1489
+ constructor() {
1490
+ _defineProperty(this, "projectKey", void 0);
1491
+ _defineProperty(this, "authMiddleware", void 0);
1492
+ _defineProperty(this, "httpMiddleware", void 0);
1493
+ _defineProperty(this, "userAgentMiddleware", void 0);
1494
+ _defineProperty(this, "correlationIdMiddleware", void 0);
1495
+ _defineProperty(this, "loggerMiddleware", void 0);
1496
+ _defineProperty(this, "queueMiddleware", void 0);
1497
+ _defineProperty(this, "concurrentMiddleware", void 0);
1498
+ _defineProperty(this, "errorMiddleware", void 0);
1499
+ _defineProperty(this, "middlewares", []);
1500
+ this.userAgentMiddleware = createUserAgentMiddleware({});
1501
+ }
1502
+ withProjectKey(key) {
1503
+ this.projectKey = key;
1504
+ return this;
1505
+ }
1506
+ defaultClient(baseUri, credentials, oauthUri, projectKey, scopes, httpClient) {
1507
+ return this.withClientCredentialsFlow({
1508
+ host: oauthUri,
1509
+ projectKey: projectKey || this.projectKey,
1510
+ credentials,
1511
+ scopes
1512
+ }).withHttpMiddleware({
1513
+ host: baseUri,
1514
+ httpClient: httpClient || fetch$1
1515
+ });
1516
+ }
1517
+ withAuthMiddleware(authMiddleware) {
1518
+ this.authMiddleware = authMiddleware;
1519
+ return this;
1520
+ }
1521
+ withMiddleware(middleware) {
1522
+ this.middlewares.push(middleware);
1523
+ return this;
1524
+ }
1525
+ withClientCredentialsFlow(options) {
1526
+ return this.withAuthMiddleware(createAuthMiddlewareForClientCredentialsFlow({
1527
+ host: options.host || CTP_AUTH_URL,
1528
+ projectKey: options.projectKey || this.projectKey,
1529
+ credentials: {
1530
+ clientId: options.credentials.clientId || null,
1531
+ clientSecret: options.credentials.clientSecret || null
1532
+ },
1533
+ oauthUri: options.oauthUri || null,
1534
+ scopes: options.scopes,
1535
+ httpClient: options.httpClient || fetch$1,
1536
+ ...options
1537
+ }));
1538
+ }
1539
+ withPasswordFlow(options) {
1540
+ return this.withAuthMiddleware(createAuthMiddlewareForPasswordFlow({
1541
+ host: options.host || CTP_AUTH_URL,
1542
+ projectKey: options.projectKey || this.projectKey,
1543
+ credentials: {
1544
+ clientId: options.credentials.clientId || null,
1545
+ clientSecret: options.credentials.clientSecret || null,
1546
+ user: {
1547
+ username: options.credentials.user.username || null,
1548
+ password: options.credentials.user.password || null
1549
+ }
1550
+ },
1551
+ httpClient: options.httpClient || fetch$1,
1552
+ ...options
1553
+ }));
1554
+ }
1555
+ withAnonymousSessionFlow(options) {
1556
+ return this.withAuthMiddleware(createAuthMiddlewareForAnonymousSessionFlow({
1557
+ host: options.host || CTP_AUTH_URL,
1558
+ projectKey: this.projectKey || options.projectKey,
1559
+ credentials: {
1560
+ clientId: options.credentials.clientId || null,
1561
+ clientSecret: options.credentials.clientSecret || null,
1562
+ anonymousId: options.credentials.anonymousId || null
1563
+ },
1564
+ httpClient: options.httpClient || fetch$1,
1565
+ ...options
1566
+ }));
1567
+ }
1568
+ withRefreshTokenFlow(options) {
1569
+ return this.withAuthMiddleware(createAuthMiddlewareForRefreshTokenFlow({
1570
+ host: options.host || CTP_AUTH_URL,
1571
+ projectKey: this.projectKey || options.projectKey,
1572
+ credentials: {
1573
+ clientId: options.credentials.clientId || null,
1574
+ clientSecret: options.credentials.clientSecret || null
1575
+ },
1576
+ httpClient: options.httpClient || fetch$1,
1577
+ refreshToken: options.refreshToken || null,
1578
+ ...options
1579
+ }));
1580
+ }
1581
+ withExistingTokenFlow(authorization, options) {
1582
+ return this.withAuthMiddleware(createAuthMiddlewareForExistingTokenFlow(authorization, {
1583
+ force: options.force || true,
1584
+ ...options
1585
+ }));
1586
+ }
1587
+ withHttpMiddleware(options) {
1588
+ this.httpMiddleware = createHttpMiddleware({
1589
+ host: options.host || CTP_API_URL,
1590
+ httpClient: options.httpClient || fetch$1,
1591
+ ...options
1592
+ });
1593
+ return this;
1594
+ }
1595
+ withUserAgentMiddleware(options) {
1596
+ this.userAgentMiddleware = createUserAgentMiddleware(options);
1597
+ return this;
1598
+ }
1599
+ withQueueMiddleware(options) {
1600
+ this.queueMiddleware = createQueueMiddleware({
1601
+ concurrency: options.concurrency || CONCURRENCT_REQUEST,
1602
+ ...options
1603
+ });
1604
+ return this;
1605
+ }
1606
+ withLoggerMiddleware(options) {
1607
+ this.loggerMiddleware = createLoggerMiddleware(options);
1608
+ return this;
1609
+ }
1610
+ withCorrelationIdMiddleware(options) {
1611
+ this.correlationIdMiddleware = createCorrelationIdMiddleware({
1612
+ generate: options === null || options === void 0 ? void 0 : options.generate,
1613
+ ...options
1614
+ });
1615
+ return this;
1616
+ }
1617
+ withConcurrentModificationMiddleware() {
1618
+ this.concurrentMiddleware = createConcurrentModificationMiddleware();
1619
+ return this;
1620
+ }
1621
+ withErrorMiddleware(options) {
1622
+ this.errorMiddleware = createErrorMiddleware(options);
1623
+ return this;
1624
+ }
1625
+ build() {
1626
+ const middlewares = this.middlewares.slice();
1627
+
1628
+ /**
1629
+ * - use default retry policy if not explicity added
1630
+ * - add retry middleware to be used by concurrent modification
1631
+ * middleware if not explicitly added as part of the middleware
1632
+ */
1633
+ if (this.correlationIdMiddleware) middlewares.push(this.correlationIdMiddleware);
1634
+ if (this.userAgentMiddleware) middlewares.push(this.userAgentMiddleware);
1635
+ if (this.authMiddleware) middlewares.push(this.authMiddleware);
1636
+ if (this.queueMiddleware) middlewares.push(this.queueMiddleware);
1637
+ if (this.loggerMiddleware) middlewares.push(this.loggerMiddleware);
1638
+ if (this.errorMiddleware) middlewares.push(this.errorMiddleware);
1639
+ if (this.concurrentMiddleware) middlewares.push(this.concurrentMiddleware);
1640
+ if (this.httpMiddleware) middlewares.push(this.httpMiddleware);
1641
+ return createClient({
1642
+ middlewares
1643
+ });
1644
+ }
1645
+ }
1646
+
1647
+ export { ClientBuilder, process$1 as Process, createAuthMiddlewareForAnonymousSessionFlow$1 as createAuthMiddlewareForAnonymousSessionFlow, createAuthMiddlewareForClientCredentialsFlow$1 as createAuthMiddlewareForClientCredentialsFlow, createAuthMiddlewareForExistingTokenFlow$1 as createAuthMiddlewareForExistingTokenFlow, createAuthMiddlewareForPasswordFlow$1 as createAuthMiddlewareForPasswordFlow, createAuthMiddlewareForRefreshTokenFlow$1 as createAuthMiddlewareForRefreshTokenFlow, createClient, createCorrelationIdMiddleware$1 as createCorrelationIdMiddleware, createHttpMiddleware$1 as createHttpMiddleware, createLoggerMiddleware$1 as createLoggerMiddleware, createQueueMiddleware$1 as createQueueMiddleware, createUserAgentMiddleware$1 as createUserAgentMiddleware };