@atlaskit/media-client 15.1.1 → 17.0.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 (46) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/constants/package.json +1 -0
  3. package/dist/cjs/client/file-fetcher/index.js +0 -2
  4. package/dist/cjs/client/media-store/index.js +63 -24
  5. package/dist/cjs/constants.js +11 -2
  6. package/dist/cjs/index.js +12 -6
  7. package/dist/cjs/models/media.js +10 -2
  8. package/dist/cjs/uploader/calculateChunkSize.js +45 -0
  9. package/dist/cjs/uploader/error.js +67 -0
  10. package/dist/cjs/{uploader.js → uploader/index.js} +43 -8
  11. package/dist/cjs/utils/request/errors.js +4 -0
  12. package/dist/cjs/utils/request/helpers.js +40 -34
  13. package/dist/cjs/version.json +1 -1
  14. package/dist/es2019/client/media-store/index.js +37 -9
  15. package/dist/es2019/constants.js +5 -1
  16. package/dist/es2019/index.js +2 -2
  17. package/dist/es2019/models/media.js +8 -1
  18. package/dist/es2019/uploader/calculateChunkSize.js +32 -0
  19. package/dist/es2019/uploader/error.js +30 -0
  20. package/dist/es2019/{uploader.js → uploader/index.js} +39 -8
  21. package/dist/es2019/utils/request/errors.js +4 -0
  22. package/dist/es2019/utils/request/helpers.js +22 -24
  23. package/dist/es2019/version.json +1 -1
  24. package/dist/esm/client/file-fetcher/index.js +0 -2
  25. package/dist/esm/client/media-store/index.js +57 -24
  26. package/dist/esm/constants.js +5 -1
  27. package/dist/esm/index.js +2 -2
  28. package/dist/esm/models/media.js +8 -1
  29. package/dist/esm/uploader/calculateChunkSize.js +32 -0
  30. package/dist/esm/uploader/error.js +51 -0
  31. package/dist/esm/{uploader.js → uploader/index.js} +39 -8
  32. package/dist/esm/utils/request/errors.js +4 -0
  33. package/dist/esm/utils/request/helpers.js +36 -31
  34. package/dist/esm/version.json +1 -1
  35. package/dist/types/client/media-store/index.d.ts +11 -2
  36. package/dist/types/constants.d.ts +3 -0
  37. package/dist/types/index.d.ts +2 -2
  38. package/dist/types/models/errors/types.d.ts +1 -1
  39. package/dist/types/models/media.d.ts +5 -0
  40. package/dist/types/uploader/calculateChunkSize.d.ts +11 -0
  41. package/dist/types/uploader/error.d.ts +29 -0
  42. package/dist/types/{uploader.d.ts → uploader/index.d.ts} +1 -1
  43. package/dist/types/utils/request/errors.d.ts +2 -0
  44. package/dist/types/utils/request/helpers.d.ts +4 -4
  45. package/dist/types/utils/request/types.d.ts +2 -0
  46. package/package.json +7 -9
@@ -14,7 +14,7 @@ exports.createProcessFetchResponse = createProcessFetchResponse;
14
14
  exports.createRequestErrorFromResponse = createRequestErrorFromResponse;
15
15
  exports.createRequestErrorReason = createRequestErrorReason;
16
16
  exports.createUrl = createUrl;
17
- exports.extract = extract;
17
+ exports.extractMediaHeaders = extractMediaHeaders;
18
18
  exports.fetchRetry = fetchRetry;
19
19
  exports.isAbortedRequestError = isAbortedRequestError;
20
20
  exports.isFetchNetworkError = isFetchNetworkError;
@@ -30,12 +30,14 @@ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"))
30
30
 
31
31
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
32
32
 
33
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
34
+
35
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
36
+
33
37
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
34
38
 
35
39
  var _mediaCore = require("@atlaskit/media-core");
36
40
 
37
- var _queryString = require("query-string");
38
-
39
41
  var _authQueryParameters = require("../../models/auth-query-parameters");
40
42
 
41
43
  var _errors = require("./errors");
@@ -69,21 +71,6 @@ function isRateLimitedError(error) {
69
71
  return !!error && (0, _errors.isRequestError)(error) && error.attributes.statusCode === 429 || !!error && !!error.message && error.message.includes('429');
70
72
  }
71
73
 
72
- function extract(url) {
73
- var index = url.indexOf('?');
74
-
75
- if (index > 0) {
76
- return {
77
- baseUrl: url.substring(0, index),
78
- queryParams: (0, _queryString.parse)(url.substring(index + 1, url.length))
79
- };
80
- } else {
81
- return {
82
- baseUrl: url
83
- };
84
- }
85
- }
86
-
87
74
  function mapAuthToRequestHeaders(auth) {
88
75
  if ((0, _mediaCore.isClientBasedAuth)(auth)) {
89
76
  return {
@@ -101,15 +88,24 @@ function mapAuthToRequestHeaders(auth) {
101
88
  function createUrl(url, _ref) {
102
89
  var params = _ref.params,
103
90
  auth = _ref.auth;
91
+ var parsedUrl = new URL(url);
92
+ var authParams = auth && (0, _authQueryParameters.mapAuthToQueryParameters)(auth) || {};
93
+
94
+ var paramsToAppend = _objectSpread(_objectSpread({}, params), authParams);
104
95
 
105
- var _extract = extract(url),
106
- baseUrl = _extract.baseUrl,
107
- queryParams = _extract.queryParams;
96
+ Object.entries(paramsToAppend).filter(function (_ref2) {
97
+ var _ref3 = (0, _slicedToArray2.default)(_ref2, 2),
98
+ _ = _ref3[0],
99
+ value = _ref3[1];
108
100
 
109
- var authParams = auth && (0, _authQueryParameters.mapAuthToQueryParameters)(auth);
110
- var queryString = (0, _queryString.stringify)(_objectSpread(_objectSpread(_objectSpread({}, queryParams), params), authParams));
111
- var shouldAppendQueryString = queryString.length > 0;
112
- return "".concat(baseUrl).concat(shouldAppendQueryString ? "?".concat(queryString) : '');
101
+ return value != null;
102
+ }).forEach(function (pair) {
103
+ var _parsedUrl$searchPara;
104
+
105
+ (_parsedUrl$searchPara = parsedUrl.searchParams).append.apply(_parsedUrl$searchPara, (0, _toConsumableArray2.default)(pair));
106
+ });
107
+ parsedUrl.searchParams.sort();
108
+ return parsedUrl.toString();
113
109
  }
114
110
 
115
111
  function withAuth(auth) {
@@ -217,7 +213,7 @@ function mapResponseToVoid() {
217
213
 
218
214
  function createMapResponseToJson(metadata) {
219
215
  return /*#__PURE__*/function () {
220
- var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(response) {
216
+ var _ref4 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(response) {
221
217
  return _regenerator.default.wrap(function _callee$(_context) {
222
218
  while (1) {
223
219
  switch (_context.prev = _context.next) {
@@ -232,7 +228,7 @@ function createMapResponseToJson(metadata) {
232
228
  case 6:
233
229
  _context.prev = 6;
234
230
  _context.t0 = _context["catch"](0);
235
- throw new _errors.RequestError('serverInvalidBody', _objectSpread(_objectSpread({}, metadata), {}, {
231
+ throw new _errors.RequestError('serverInvalidBody', _objectSpread(_objectSpread(_objectSpread({}, metadata), extractMediaHeaders(response)), {}, {
236
232
  statusCode: response.status
237
233
  }), _context.t0);
238
234
 
@@ -245,14 +241,14 @@ function createMapResponseToJson(metadata) {
245
241
  }));
246
242
 
247
243
  return function (_x3) {
248
- return _ref2.apply(this, arguments);
244
+ return _ref4.apply(this, arguments);
249
245
  };
250
246
  }();
251
247
  }
252
248
 
253
249
  function createMapResponseToBlob(metadata) {
254
250
  return /*#__PURE__*/function () {
255
- var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(response) {
251
+ var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(response) {
256
252
  return _regenerator.default.wrap(function _callee2$(_context2) {
257
253
  while (1) {
258
254
  switch (_context2.prev = _context2.next) {
@@ -267,7 +263,7 @@ function createMapResponseToBlob(metadata) {
267
263
  case 6:
268
264
  _context2.prev = 6;
269
265
  _context2.t0 = _context2["catch"](0);
270
- throw new _errors.RequestError('serverInvalidBody', _objectSpread(_objectSpread({}, metadata), {}, {
266
+ throw new _errors.RequestError('serverInvalidBody', _objectSpread(_objectSpread(_objectSpread({}, metadata), extractMediaHeaders(response)), {}, {
271
267
  statusCode: response.status
272
268
  }), _context2.t0);
273
269
 
@@ -280,7 +276,7 @@ function createMapResponseToBlob(metadata) {
280
276
  }));
281
277
 
282
278
  return function (_x4) {
283
- return _ref3.apply(this, arguments);
279
+ return _ref5.apply(this, arguments);
284
280
  };
285
281
  }();
286
282
  }
@@ -329,7 +325,7 @@ function _fetchRetry() {
329
325
  timeoutInMs = startTimeoutInMs;
330
326
 
331
327
  waitAndBumpTimeout = /*#__PURE__*/function () {
332
- var _ref4 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
328
+ var _ref6 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
333
329
  return _regenerator.default.wrap(function _callee5$(_context5) {
334
330
  while (1) {
335
331
  switch (_context5.prev = _context5.next) {
@@ -350,7 +346,7 @@ function _fetchRetry() {
350
346
  }));
351
347
 
352
348
  return function waitAndBumpTimeout() {
353
- return _ref4.apply(this, arguments);
349
+ return _ref6.apply(this, arguments);
354
350
  };
355
351
  }();
356
352
 
@@ -453,7 +449,7 @@ function createRequestErrorReason(statusCode) {
453
449
  function createRequestErrorFromResponse(metadata, response) {
454
450
  var statusCode = response.status;
455
451
  var reason = createRequestErrorReason(statusCode);
456
- return new _errors.RequestError(reason, _objectSpread(_objectSpread({}, metadata), {}, {
452
+ return new _errors.RequestError(reason, _objectSpread(_objectSpread(_objectSpread({}, metadata), extractMediaHeaders(response)), {}, {
457
453
  statusCode: statusCode
458
454
  }));
459
455
  }
@@ -467,4 +463,14 @@ function createProcessFetchResponse(metadata) {
467
463
  var requestError = createRequestErrorFromResponse(metadata, response);
468
464
  throw requestError;
469
465
  };
466
+ }
467
+
468
+ function extractMediaHeaders(response) {
469
+ var headers = response.headers;
470
+ var mediaRegion = headers.get('x-media-region') || 'unknown';
471
+ var mediaEnv = headers.get('x-media-env') || 'unknown';
472
+ return {
473
+ mediaRegion: mediaRegion,
474
+ mediaEnv: mediaEnv
475
+ };
470
476
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/media-client",
3
- "version": "15.1.1",
3
+ "version": "17.0.0",
4
4
  "sideEffects": false
5
5
  }
@@ -5,6 +5,8 @@ import { request } from '../../utils/request';
5
5
  import { createUrl, createMapResponseToJson, createMapResponseToBlob } from '../../utils/request/helpers';
6
6
  import { resolveAuth, resolveInitialAuth } from './resolveAuth';
7
7
  export { MediaStoreError, isMediaStoreError } from './error';
8
+ const MEDIA_API_REGION = 'media-api-region';
9
+ const MEDIA_API_ENVIRONMENT = 'media-api-environment';
8
10
  const defaultImageOptions = {
9
11
  'max-age': FILE_CACHE_MAX_AGE,
10
12
  allowAnimated: true,
@@ -120,12 +122,20 @@ export class MediaStore {
120
122
  return this.request(`/upload`, options).then(createMapResponseToJson(metadata));
121
123
  }
122
124
 
123
- async uploadChunk(etag, blob, collectionName) {
125
+ async uploadChunk(etag, blob, {
126
+ collectionName,
127
+ uploadId,
128
+ partNumber
129
+ } = {}) {
124
130
  const metadata = {
125
131
  method: 'PUT',
126
132
  endpoint: '/chunk/{etag}'
127
133
  };
128
134
  const options = { ...metadata,
135
+ params: {
136
+ uploadId,
137
+ partNumber
138
+ },
129
139
  authContext: {
130
140
  collectionName
131
141
  },
@@ -134,12 +144,18 @@ export class MediaStore {
134
144
  await this.request(`/chunk/${etag}`, options);
135
145
  }
136
146
 
137
- probeChunks(chunks, collectionName) {
147
+ probeChunks(chunks, {
148
+ collectionName,
149
+ uploadId
150
+ } = {}) {
138
151
  const metadata = {
139
152
  method: 'POST',
140
153
  endpoint: '/chunk/probe'
141
154
  };
142
155
  const options = { ...metadata,
156
+ params: {
157
+ uploadId
158
+ },
143
159
  authContext: {
144
160
  collectionName
145
161
  },
@@ -373,20 +389,32 @@ export class MediaStore {
373
389
  body,
374
390
  clientOptions
375
391
  }, controller);
376
- updateMediaRegion(response.headers.get('x-media-region'));
392
+ setKeyValueInSessionStorage(MEDIA_API_REGION, response.headers.get('x-media-region'));
393
+ setKeyValueInSessionStorage(MEDIA_API_ENVIRONMENT, response.headers.get('x-media-env'));
377
394
  return response;
378
395
  }
379
396
 
380
397
  }
381
398
 
382
- function updateMediaRegion(region) {
383
- if (!region || !(window && window.sessionStorage)) {
399
+ const getValueFromSessionStorage = key => {
400
+ return window && window.sessionStorage && window.sessionStorage.getItem(key) || undefined;
401
+ };
402
+
403
+ const setKeyValueInSessionStorage = (key, value) => {
404
+ if (!value || !(window && window.sessionStorage)) {
384
405
  return;
385
406
  }
386
407
 
387
- const currentRegion = window.sessionStorage.getItem('media-api-region');
408
+ const currentValue = window.sessionStorage.getItem(key);
388
409
 
389
- if (currentRegion !== region) {
390
- window.sessionStorage.setItem('media-api-region', region);
410
+ if (currentValue !== value) {
411
+ window.sessionStorage.setItem(key, value);
391
412
  }
392
- }
413
+ };
414
+
415
+ export const getMediaEnvironment = () => {
416
+ return getValueFromSessionStorage(MEDIA_API_ENVIRONMENT);
417
+ };
418
+ export const getMediaRegion = () => {
419
+ return getValueFromSessionStorage(MEDIA_API_REGION);
420
+ };
@@ -1,4 +1,8 @@
1
+ import { DATA_UNIT } from './models/media';
1
2
  export const RECENTS_COLLECTION = 'recents';
2
3
  export const FILE_CACHE_MAX_AGE = 60 * 60 * 24 * 30; // Retain for 30 days
3
4
 
4
- export const MAX_RESOLUTION = 4096;
5
+ export const MAX_RESOLUTION = 4096;
6
+ export const CHUNK_SIZE = 4 * DATA_UNIT.MB;
7
+ export const PROCESSING_BATCH_SIZE = 1000;
8
+ export const MAX_UPLOAD_FILE_SIZE = 2 * DATA_UNIT.TB;
@@ -1,11 +1,11 @@
1
- export { MediaStore, MediaStoreError, isMediaStoreError } from './client/media-store';
1
+ export { MediaStore, MediaStoreError, isMediaStoreError, getMediaEnvironment, getMediaRegion } from './client/media-store';
2
2
  export { UploadController } from './upload-controller';
3
3
  export { isPreviewableType, isMediaCollectionItemFullDetails } from './models/media';
4
4
  export { getArtifactUrl } from './models/artifacts';
5
5
  export { isMediaClientError, getMediaClientErrorReason } from './models/errors';
6
6
  export { isUploadingFileState, isProcessingFileState, isProcessedFileState, isErrorFileState, isPreviewableFileState, isFinalFileState, isImageRepresentationReady, mapMediaFileToFileState, mapMediaItemToFileState } from './models/file-state';
7
7
  // TODO: remove access to media file stream cache https://product-fabric.atlassian.net/browse/MEX-1417
8
- export { getFileStreamsCache, StreamsCache } from './file-streams-cache';
8
+ export { StreamsCache } from './file-streams-cache';
9
9
  export { uploadFile } from './uploader';
10
10
  export { request, RequestError, isRequestError, isRateLimitedError } from './utils/request';
11
11
  export { isAbortedRequestError, mapResponseToJson, mapResponseToBlob, mapResponseToVoid, createUrl } from './utils/request/helpers';
@@ -9,4 +9,11 @@ export const isPreviewableType = (type, featureFlags) => {
9
9
 
10
10
  return defaultPreviewableTypes.indexOf(type) > -1;
11
11
  };
12
- export const isMediaCollectionItemFullDetails = mediaCollectionItem => !!mediaCollectionItem['mediaType'] && !!mediaCollectionItem['mimeType'] && !!mediaCollectionItem['processingStatus'];
12
+ export const isMediaCollectionItemFullDetails = mediaCollectionItem => !!mediaCollectionItem['mediaType'] && !!mediaCollectionItem['mimeType'] && !!mediaCollectionItem['processingStatus'];
13
+ export let DATA_UNIT;
14
+
15
+ (function (DATA_UNIT) {
16
+ DATA_UNIT[DATA_UNIT["MB"] = 1048576] = "MB";
17
+ DATA_UNIT[DATA_UNIT["GB"] = 1073741824] = "GB";
18
+ DATA_UNIT[DATA_UNIT["TB"] = 1099511627776] = "TB";
19
+ })(DATA_UNIT || (DATA_UNIT = {}));
@@ -0,0 +1,32 @@
1
+ import { DATA_UNIT } from '../models/media';
2
+ import { MAX_UPLOAD_FILE_SIZE } from '../constants';
3
+ export const fileSizeError = 'fileSizeExceedsLimit';
4
+ /**
5
+ * This is a helper to dynamically calculate the chunk size for a given file size.
6
+ *
7
+ * @param fileSize The size of a file to calculate the chunk size for.
8
+ * @returns A number of bytes per chunk or Throws an Error if the file size exceeds 2TB
9
+ *
10
+ * @see {@link https://product-fabric.atlassian.net/wiki/spaces/FIL/pages/3221881143/Rule+of+thumb+for+chunk+sizes#Given-the-following-conditions}
11
+ *
12
+ */
13
+
14
+ export const calculateChunkSize = fileSize => {
15
+ if (fileSize > MAX_UPLOAD_FILE_SIZE) {
16
+ throw new Error(fileSizeError);
17
+ }
18
+
19
+ if (fileSize <= 5 * DATA_UNIT.GB) {
20
+ return 5 * DATA_UNIT.MB;
21
+ }
22
+
23
+ if (fileSize > 5 * DATA_UNIT.GB && fileSize <= 50 * DATA_UNIT.GB) {
24
+ return 50 * DATA_UNIT.MB;
25
+ }
26
+
27
+ if (fileSize > 50 * DATA_UNIT.GB && fileSize <= 0.95 * DATA_UNIT.TB) {
28
+ return 100 * DATA_UNIT.MB;
29
+ }
30
+
31
+ return 210 * DATA_UNIT.MB;
32
+ };
@@ -0,0 +1,30 @@
1
+ import { BaseMediaClientError } from '../models/errors';
2
+ export class UploaderError extends BaseMediaClientError {
3
+ constructor(reason, id, metadata) {
4
+ super(reason);
5
+ this.reason = reason;
6
+ this.id = id;
7
+ this.metadata = metadata;
8
+ }
9
+
10
+ get attributes() {
11
+ const {
12
+ reason,
13
+ id,
14
+ metadata: {
15
+ collectionName,
16
+ occurrenceKey
17
+ } = {}
18
+ } = this;
19
+ return {
20
+ reason,
21
+ id,
22
+ collectionName,
23
+ occurrenceKey
24
+ };
25
+ }
26
+
27
+ }
28
+ export function isUploaderError(err) {
29
+ return err instanceof UploaderError;
30
+ }
@@ -1,21 +1,29 @@
1
1
  import { chunkinator } from '@atlaskit/chunkinator';
2
2
  import { from } from 'rxjs/observable/from';
3
3
  import { concatMap } from 'rxjs/operators/concatMap';
4
- import { createHasher } from './utils/hashing/hasherCreator'; // TODO: Allow to pass multiple files
4
+ import { createHasher } from '../utils/hashing/hasherCreator';
5
+ import { UploaderError } from './error';
6
+ import { CHUNK_SIZE, PROCESSING_BATCH_SIZE } from '../constants';
7
+ import { calculateChunkSize, fileSizeError } from './calculateChunkSize';
8
+ import { getMediaFeatureFlag } from '@atlaskit/media-common'; // TODO: Allow to pass multiple files
5
9
 
6
10
  const hashingFunction = async blob => {
7
11
  const hasher = await createHasher();
8
12
  return hasher.hash(blob);
9
13
  };
10
14
 
11
- const createProbingFunction = (store, collection) => async chunks => {
12
- const response = await store.probeChunks(hashedChunks(chunks), collection);
15
+ const createProbingFunction = (store, collectionName) => async chunks => {
16
+ const response = await store.probeChunks(hashedChunks(chunks), {
17
+ collectionName
18
+ });
13
19
  const results = response.data.results;
14
20
  return Object.values(results).map(result => result.exists);
15
21
  };
16
22
 
17
- const createUploadingFunction = (store, collection) => {
18
- return chunk => store.uploadChunk(chunk.hash, chunk.blob, collection);
23
+ const createUploadingFunction = (store, collectionName) => {
24
+ return chunk => store.uploadChunk(chunk.hash, chunk.blob, {
25
+ collectionName
26
+ });
19
27
  };
20
28
 
21
29
  const createProcessingFunction = (store, deferredUploadId, collection) => {
@@ -56,17 +64,40 @@ export const uploadFile = (file, store, uploadableFileUpfrontIds, callbacks) =>
56
64
  collection
57
65
  } = file;
58
66
  const {
59
- deferredUploadId
67
+ deferredUploadId,
68
+ id,
69
+ occurrenceKey
60
70
  } = uploadableFileUpfrontIds;
71
+ let chunkSize = CHUNK_SIZE;
72
+
73
+ try {
74
+ if (content instanceof Blob && getMediaFeatureFlag('mediaUploadApiV2', store.featureFlags)) {
75
+ chunkSize = calculateChunkSize(content.size);
76
+ }
77
+ } catch (err) {
78
+ if (err instanceof Error && err.message === fileSizeError) {
79
+ callbacks === null || callbacks === void 0 ? void 0 : callbacks.onUploadFinish(new UploaderError(err.message, id, {
80
+ collectionName: collection,
81
+ occurrenceKey: occurrenceKey
82
+ }));
83
+ }
84
+
85
+ return {
86
+ cancel: () => {
87
+ callbacks === null || callbacks === void 0 ? void 0 : callbacks.onUploadFinish('canceled');
88
+ }
89
+ };
90
+ }
91
+
61
92
  const chunkinatorObservable = chunkinator(content, {
62
93
  hashingFunction,
63
94
  hashingConcurrency: 5,
64
95
  probingBatchSize: 100,
65
- chunkSize: 4 * 1024 * 1024,
96
+ chunkSize,
66
97
  uploadingConcurrency: 3,
67
98
  uploadingFunction: createUploadingFunction(store, collection),
68
99
  probingFunction: createProbingFunction(store, collection),
69
- processingBatchSize: 1000,
100
+ processingBatchSize: PROCESSING_BATCH_SIZE,
70
101
  processingFunction: createProcessingFunction(store, deferredUploadId, collection)
71
102
  }, {
72
103
  onProgress(progress) {
@@ -13,6 +13,8 @@ export class RequestError extends BaseMediaClientError {
13
13
  metadata: {
14
14
  method,
15
15
  endpoint,
16
+ mediaRegion,
17
+ mediaEnv,
16
18
  attempts,
17
19
  clientExhaustedRetries,
18
20
  statusCode
@@ -23,6 +25,8 @@ export class RequestError extends BaseMediaClientError {
23
25
  reason,
24
26
  method,
25
27
  endpoint,
28
+ mediaRegion,
29
+ mediaEnv,
26
30
  attempts,
27
31
  clientExhaustedRetries,
28
32
  statusCode,
@@ -1,5 +1,4 @@
1
1
  import { isClientBasedAuth } from '@atlaskit/media-core';
2
- import { parse, stringify } from 'query-string';
3
2
  import { mapAuthToQueryParameters } from '../../models/auth-query-parameters';
4
3
  import { RequestError, isRequestError } from './errors';
5
4
  export function clientTimeoutPromise(timeout) {
@@ -20,20 +19,6 @@ export function isFetchNetworkError(err) {
20
19
  export function isRateLimitedError(error) {
21
20
  return !!error && isRequestError(error) && error.attributes.statusCode === 429 || !!error && !!error.message && error.message.includes('429');
22
21
  }
23
- export function extract(url) {
24
- const index = url.indexOf('?');
25
-
26
- if (index > 0) {
27
- return {
28
- baseUrl: url.substring(0, index),
29
- queryParams: parse(url.substring(index + 1, url.length))
30
- };
31
- } else {
32
- return {
33
- baseUrl: url
34
- };
35
- }
36
- }
37
22
  export function mapAuthToRequestHeaders(auth) {
38
23
  if (isClientBasedAuth(auth)) {
39
24
  return {
@@ -51,17 +36,16 @@ export function createUrl(url, {
51
36
  params,
52
37
  auth
53
38
  }) {
54
- const {
55
- baseUrl,
56
- queryParams
57
- } = extract(url);
58
- const authParams = auth && mapAuthToQueryParameters(auth);
59
- const queryString = stringify({ ...queryParams,
60
- ...params,
39
+ const parsedUrl = new URL(url);
40
+ const authParams = auth && mapAuthToQueryParameters(auth) || {};
41
+ const paramsToAppend = { ...params,
61
42
  ...authParams
43
+ };
44
+ Object.entries(paramsToAppend).filter(([_, value]) => value != null).forEach(pair => {
45
+ parsedUrl.searchParams.append(...pair);
62
46
  });
63
- const shouldAppendQueryString = queryString.length > 0;
64
- return `${baseUrl}${shouldAppendQueryString ? `?${queryString}` : ''}`;
47
+ parsedUrl.searchParams.sort();
48
+ return parsedUrl.toString();
65
49
  }
66
50
  export function withAuth(auth) {
67
51
  return headers => {
@@ -124,6 +108,7 @@ export function createMapResponseToJson(metadata) {
124
108
  return await response.json();
125
109
  } catch (err) {
126
110
  throw new RequestError('serverInvalidBody', { ...metadata,
111
+ ...extractMediaHeaders(response),
127
112
  statusCode: response.status
128
113
  }, err);
129
114
  }
@@ -135,6 +120,7 @@ export function createMapResponseToBlob(metadata) {
135
120
  return await response.blob();
136
121
  } catch (err) {
137
122
  throw new RequestError('serverInvalidBody', { ...metadata,
123
+ ...extractMediaHeaders(response),
138
124
  statusCode: response.status
139
125
  }, err);
140
126
  }
@@ -240,6 +226,7 @@ export function createRequestErrorFromResponse(metadata, response) {
240
226
  } = response;
241
227
  const reason = createRequestErrorReason(statusCode);
242
228
  return new RequestError(reason, { ...metadata,
229
+ ...extractMediaHeaders(response),
243
230
  statusCode
244
231
  });
245
232
  }
@@ -252,4 +239,15 @@ export function createProcessFetchResponse(metadata) {
252
239
  const requestError = createRequestErrorFromResponse(metadata, response);
253
240
  throw requestError;
254
241
  };
242
+ }
243
+ export function extractMediaHeaders(response) {
244
+ const {
245
+ headers
246
+ } = response;
247
+ const mediaRegion = headers.get('x-media-region') || 'unknown';
248
+ const mediaEnv = headers.get('x-media-env') || 'unknown';
249
+ return {
250
+ mediaRegion,
251
+ mediaEnv
252
+ };
255
253
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/media-client",
3
- "version": "15.1.1",
3
+ "version": "17.0.0",
4
4
  "sideEffects": false
5
5
  }
@@ -285,7 +285,6 @@ export var FileFetcherImpl = /*#__PURE__*/function () {
285
285
  };
286
286
  mediaType = getMediaTypeFromMimeType(type); // we emit a richer state after the blob is fetched
287
287
 
288
- // we emit a richer state after the blob is fetched
289
288
  subject.next({
290
289
  status: 'processing',
291
290
  name: name,
@@ -297,7 +296,6 @@ export var FileFetcherImpl = /*#__PURE__*/function () {
297
296
  preview: preview
298
297
  }); // we don't want to wait for the file to be upload
299
298
 
300
- // we don't want to wait for the file to be upload
301
299
  _this3.upload(file, undefined, uploadableFileUpfrontIds);
302
300
 
303
301
  _context3.next = 12;