@atlaskit/media-client 25.0.2 → 25.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 (39) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/client/media-store/MediaStore.js +631 -0
  3. package/dist/cjs/client/media-store/index.js +19 -627
  4. package/dist/cjs/client/media-store/types.js +5 -0
  5. package/dist/cjs/test-helpers/MockedMediaApi/MockedMediaApi.js +449 -0
  6. package/dist/cjs/test-helpers/MockedMediaApi/helpers.js +184 -0
  7. package/dist/cjs/test-helpers/MockedMediaApi/index.js +55 -0
  8. package/dist/cjs/test-helpers/index.js +49 -0
  9. package/dist/es2019/client/media-store/MediaStore.js +385 -0
  10. package/dist/es2019/client/media-store/index.js +1 -385
  11. package/dist/es2019/client/media-store/types.js +1 -0
  12. package/dist/es2019/test-helpers/MockedMediaApi/MockedMediaApi.js +164 -0
  13. package/dist/es2019/test-helpers/MockedMediaApi/helpers.js +166 -0
  14. package/dist/es2019/test-helpers/MockedMediaApi/index.js +2 -0
  15. package/dist/es2019/test-helpers/index.js +2 -1
  16. package/dist/esm/client/media-store/MediaStore.js +624 -0
  17. package/dist/esm/client/media-store/index.js +1 -624
  18. package/dist/esm/client/media-store/types.js +1 -0
  19. package/dist/esm/test-helpers/MockedMediaApi/MockedMediaApi.js +442 -0
  20. package/dist/esm/test-helpers/MockedMediaApi/helpers.js +176 -0
  21. package/dist/esm/test-helpers/MockedMediaApi/index.js +2 -0
  22. package/dist/esm/test-helpers/index.js +2 -1
  23. package/dist/types/client/media-store/MediaStore.d.ts +34 -0
  24. package/dist/types/client/media-store/index.d.ts +2 -166
  25. package/dist/types/client/media-store/types.d.ts +161 -0
  26. package/dist/types/test-helpers/MockedMediaApi/MockedMediaApi.d.ts +16 -0
  27. package/dist/types/test-helpers/MockedMediaApi/helpers.d.ts +23 -0
  28. package/dist/types/test-helpers/MockedMediaApi/index.d.ts +3 -0
  29. package/dist/types/test-helpers/index.d.ts +2 -0
  30. package/dist/types-ts4.5/client/media-store/MediaStore.d.ts +34 -0
  31. package/dist/types-ts4.5/client/media-store/index.d.ts +2 -166
  32. package/dist/types-ts4.5/client/media-store/types.d.ts +161 -0
  33. package/dist/types-ts4.5/test-helpers/MockedMediaApi/MockedMediaApi.d.ts +16 -0
  34. package/dist/types-ts4.5/test-helpers/MockedMediaApi/helpers.d.ts +23 -0
  35. package/dist/types-ts4.5/test-helpers/MockedMediaApi/index.d.ts +3 -0
  36. package/dist/types-ts4.5/test-helpers/index.d.ts +2 -0
  37. package/package.json +2 -2
  38. package/report.api.md +120 -1
  39. package/tmp/api-report-tmp.d.ts +47 -1
@@ -1,386 +1,2 @@
1
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- import { getRandomHex } from '@atlaskit/media-common';
3
- import { FILE_CACHE_MAX_AGE, MAX_RESOLUTION } from '../../constants';
4
- import { getArtifactUrl } from '../../models/artifacts';
5
- import { request } from '../../utils/request';
6
- import { createUrl, createMapResponseToJson, createMapResponseToBlob } from '../../utils/request/helpers';
7
- import { resolveAuth, resolveInitialAuth } from './resolveAuth';
8
1
  export { MediaStoreError, isMediaStoreError } from './error';
9
- const MEDIA_API_REGION = 'media-api-region';
10
- const MEDIA_API_ENVIRONMENT = 'media-api-environment';
11
- const defaultImageOptions = {
12
- 'max-age': FILE_CACHE_MAX_AGE,
13
- allowAnimated: true,
14
- mode: 'crop'
15
- };
16
- const extendImageParams = (params, fetchMaxRes = false) => {
17
- return {
18
- ...defaultImageOptions,
19
- ...params,
20
- ...(fetchMaxRes ? {
21
- width: MAX_RESOLUTION,
22
- height: MAX_RESOLUTION
23
- } : {})
24
- };
25
- };
26
- const jsonHeaders = {
27
- Accept: 'application/json',
28
- 'Content-Type': 'application/json'
29
- };
30
- export class MediaStore {
31
- constructor(config) {
32
- _defineProperty(this, "resolveAuth", authContext => resolveAuth(this.config.authProvider, authContext));
33
- _defineProperty(this, "resolveInitialAuth", () => resolveInitialAuth(this.config.initialAuth));
34
- this.config = config;
35
- }
36
- async removeCollectionFile(id, collectionName, occurrenceKey, traceContext) {
37
- const metadata = {
38
- method: 'PUT',
39
- endpoint: '/collection/{collectionName}'
40
- };
41
- const body = {
42
- actions: [{
43
- action: 'remove',
44
- item: {
45
- type: 'file',
46
- id,
47
- occurrenceKey
48
- }
49
- }]
50
- };
51
- const options = {
52
- ...metadata,
53
- authContext: {
54
- collectionName
55
- },
56
- headers: {
57
- Accept: 'application/json',
58
- 'Content-Type': 'application/json'
59
- },
60
- body: JSON.stringify(body),
61
- traceContext
62
- };
63
- await this.request(`/collection/${collectionName}`, options);
64
- }
65
- createUpload(createUpTo = 1, collectionName, traceContext) {
66
- const metadata = {
67
- method: 'POST',
68
- endpoint: '/upload'
69
- };
70
- const options = {
71
- ...metadata,
72
- authContext: {
73
- collectionName
74
- },
75
- params: {
76
- createUpTo
77
- },
78
- headers: {
79
- Accept: 'application/json'
80
- },
81
- traceContext
82
- };
83
- return this.request(`/upload`, options).then(createMapResponseToJson(metadata));
84
- }
85
- async uploadChunk(etag, blob, uploadId, partNumber, collectionName, traceContext) {
86
- const metadata = {
87
- method: 'PUT',
88
- endpoint: '/chunk/{etag}'
89
- };
90
- const options = {
91
- ...metadata,
92
- params: {
93
- uploadId,
94
- partNumber
95
- },
96
- authContext: {
97
- collectionName
98
- },
99
- body: blob,
100
- traceContext
101
- };
102
- await this.request(`/chunk/${etag}`, options);
103
- }
104
- probeChunks(chunks, uploadId, collectionName, traceContext) {
105
- const metadata = {
106
- method: 'POST',
107
- endpoint: '/chunk/probe'
108
- };
109
- const options = {
110
- ...metadata,
111
- params: {
112
- uploadId
113
- },
114
- authContext: {
115
- collectionName
116
- },
117
- headers: jsonHeaders,
118
- body: JSON.stringify({
119
- chunks
120
- }),
121
- traceContext
122
- };
123
- return this.request(`/chunk/probe`, options).then(createMapResponseToJson(metadata));
124
- }
125
- createFileFromUpload(body, params = {}, traceContext) {
126
- const metadata = {
127
- method: 'POST',
128
- endpoint: '/file/upload'
129
- };
130
- const options = {
131
- ...metadata,
132
- authContext: {
133
- collectionName: params.collection
134
- },
135
- params,
136
- headers: jsonHeaders,
137
- body: JSON.stringify(body),
138
- traceContext
139
- };
140
- return this.request('/file/upload', options).then(createMapResponseToJson(metadata));
141
- }
142
- getRejectedResponseFromDescriptor(descriptor, limit) {
143
- return {
144
- fileId: descriptor.fileId,
145
- error: {
146
- code: 'ExceedMaxFileSizeLimit',
147
- title: 'The expected file size exceeded the maximum size limit.',
148
- href: 'https://dt-api-filestore--app.ap-southeast-2.dev.atl-paas.net/api.html#BadRequest',
149
- limit,
150
- size: descriptor.size
151
- }
152
- };
153
- }
154
- async touchFiles(body, params = {}, traceContext) {
155
- const metadata = {
156
- method: 'POST',
157
- endpoint: '/upload/createWithFiles'
158
- };
159
- const options = {
160
- ...metadata,
161
- authContext: {
162
- collectionName: params.collection
163
- },
164
- headers: jsonHeaders,
165
- body: JSON.stringify(body),
166
- traceContext
167
- };
168
- return this.request('/upload/createWithFiles', options).then(createMapResponseToJson(metadata));
169
- }
170
- getFile(fileId, params = {}, traceContext) {
171
- const metadata = {
172
- method: 'GET',
173
- endpoint: '/file/{fileId}'
174
- };
175
- const options = {
176
- ...metadata,
177
- authContext: {
178
- collectionName: params.collection
179
- },
180
- params,
181
- traceContext
182
- };
183
- return this.request(`/file/${fileId}`, options).then(createMapResponseToJson(metadata));
184
- }
185
- async getFileImageURL(id, params) {
186
- const {
187
- collection: collectionName
188
- } = params || {};
189
- const auth = await this.resolveAuth({
190
- collectionName
191
- });
192
- return this.createFileImageURL(id, auth, params);
193
- }
194
-
195
- // TODO Create ticket in case Trace Id can be supported through query params
196
- getFileImageURLSync(id, params) {
197
- const auth = this.resolveInitialAuth();
198
- return this.createFileImageURL(id, auth, params);
199
- }
200
- createFileImageURL(id, auth, params) {
201
- const options = {
202
- params: extendImageParams(params),
203
- auth
204
- };
205
- return createUrl(`${auth.baseUrl}/file/${id}/image`, options);
206
- }
207
- async getFileBinaryURL(id, collectionName) {
208
- const auth = await this.resolveAuth({
209
- collectionName
210
- });
211
- const options = {
212
- params: {
213
- dl: true,
214
- collection: collectionName,
215
- 'max-age': FILE_CACHE_MAX_AGE
216
- },
217
- auth
218
- };
219
- return createUrl(`${auth.baseUrl}/file/${id}/binary`, options);
220
- }
221
- async getArtifactURL(artifacts, artifactName, collectionName) {
222
- const artifactUrl = getArtifactUrl(artifacts, artifactName);
223
- if (!artifactUrl) {
224
- throw new Error(`artifact ${artifactName} not found`);
225
- }
226
- const auth = await this.resolveAuth({
227
- collectionName
228
- });
229
- const options = {
230
- params: {
231
- collection: collectionName,
232
- 'max-age': FILE_CACHE_MAX_AGE
233
- },
234
- auth
235
- };
236
- return createUrl(`${auth.baseUrl}${artifactUrl}`, options);
237
- }
238
- async getImage(id, params, controller, fetchMaxRes, traceContext) {
239
- // TODO add checkWebpSupport() back https://product-fabric.atlassian.net/browse/MPT-584
240
- const isWebpSupported = false;
241
- const headers = {};
242
- if (isWebpSupported) {
243
- headers.accept = 'image/webp,image/*,*/*;q=0.8';
244
- }
245
- const metadata = {
246
- method: 'GET',
247
- endpoint: '/file/{fileId}/image'
248
- };
249
- const options = {
250
- ...metadata,
251
- authContext: {
252
- collectionName: params && params.collection
253
- },
254
- params: extendImageParams(params, fetchMaxRes),
255
- headers,
256
- traceContext
257
- };
258
- return this.request(`/file/${id}/image`, options, controller).then(createMapResponseToBlob(metadata));
259
- }
260
- async getItems(ids, collectionName, traceContext) {
261
- const descriptors = ids.map(id => ({
262
- type: 'file',
263
- id,
264
- collection: collectionName
265
- }));
266
- const metadata = {
267
- method: 'POST',
268
- endpoint: '/items'
269
- };
270
- const options = {
271
- ...metadata,
272
- authContext: {
273
- collectionName
274
- },
275
- headers: jsonHeaders,
276
- body: JSON.stringify({
277
- descriptors
278
- }),
279
- traceContext
280
- };
281
- return this.request('/items', options).then(createMapResponseToJson(metadata));
282
- }
283
- async getImageMetadata(id, params, traceContext) {
284
- const metadata = {
285
- method: 'GET',
286
- endpoint: '/file/{fileId}/image/metadata'
287
- };
288
- const options = {
289
- ...metadata,
290
- authContext: {
291
- collectionName: params && params.collection
292
- },
293
- params,
294
- traceContext
295
- };
296
- return this.request(`/file/${id}/image/metadata`, options).then(createMapResponseToJson(metadata));
297
- }
298
- async appendChunksToUpload(uploadId, body, collectionName, traceContext) {
299
- const metadata = {
300
- method: 'PUT',
301
- endpoint: '/upload/{uploadId}/chunks'
302
- };
303
- const options = {
304
- ...metadata,
305
- authContext: {
306
- collectionName
307
- },
308
- headers: jsonHeaders,
309
- body: JSON.stringify(body),
310
- traceContext
311
- };
312
- await this.request(`/upload/${uploadId}/chunks`, options);
313
- }
314
- copyFileWithToken(body, params, traceContext) {
315
- const metadata = {
316
- method: 'POST',
317
- endpoint: '/file/copy/withToken'
318
- };
319
- const options = {
320
- ...metadata,
321
- authContext: {
322
- collectionName: params.collection
323
- },
324
- // Contains collection name to write to
325
- params,
326
- // Contains collection name to write to
327
- headers: jsonHeaders,
328
- body: JSON.stringify(body),
329
- // Contains collection name to read from
330
- traceContext
331
- };
332
- return this.request('/file/copy/withToken', options).then(createMapResponseToJson(metadata));
333
- }
334
- async request(path, options = {
335
- method: 'GET',
336
- endpoint: undefined,
337
- authContext: {}
338
- }, controller) {
339
- const {
340
- method,
341
- endpoint,
342
- authContext,
343
- params,
344
- headers,
345
- body,
346
- clientOptions,
347
- traceContext
348
- } = options;
349
- const auth = await this.resolveAuth(authContext);
350
- const extendedTraceContext = traceContext ? {
351
- ...traceContext,
352
- spanId: (traceContext === null || traceContext === void 0 ? void 0 : traceContext.spanId) || getRandomHex(8)
353
- } : undefined;
354
- const response = await request(`${auth.baseUrl}${path}`, {
355
- method,
356
- endpoint,
357
- auth,
358
- params,
359
- headers,
360
- body,
361
- clientOptions,
362
- traceContext: extendedTraceContext
363
- }, controller);
364
- setKeyValueInSessionStorage(MEDIA_API_REGION, response.headers.get('x-media-region'));
365
- setKeyValueInSessionStorage(MEDIA_API_ENVIRONMENT, response.headers.get('x-media-env'));
366
- return response;
367
- }
368
- }
369
- const getValueFromSessionStorage = key => {
370
- return window && window.sessionStorage && window.sessionStorage.getItem(key) || undefined;
371
- };
372
- const setKeyValueInSessionStorage = (key, value) => {
373
- if (!value || !(window && window.sessionStorage)) {
374
- return;
375
- }
376
- const currentValue = window.sessionStorage.getItem(key);
377
- if (currentValue !== value) {
378
- window.sessionStorage.setItem(key, value);
379
- }
380
- };
381
- export const getMediaEnvironment = () => {
382
- return getValueFromSessionStorage(MEDIA_API_ENVIRONMENT);
383
- };
384
- export const getMediaRegion = () => {
385
- return getValueFromSessionStorage(MEDIA_API_REGION);
386
- };
2
+ export { MediaStore, getMediaEnvironment, getMediaRegion } from './MediaStore';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,164 @@
1
+ import { getMediaFile, normaliseInput } from './helpers';
2
+ const getMediaApi = ({
3
+ getFileItem
4
+ }) => ({
5
+ // --------------------------------------------------------
6
+ // UPLOAD ENDPOINTS - None is supported
7
+ // --------------------------------------------------------
8
+
9
+ touchFiles: async ({
10
+ descriptors
11
+ }) => {
12
+ throw new Error('500 - MockedMediaApi.touchFiles: method not implemented');
13
+ },
14
+ probeChunks: async (...args) => {
15
+ throw new Error('500 - MockedMediaApi.probeChunks: method not implemented');
16
+ },
17
+ uploadChunk: async (_etag, _blob, uploadId) => {
18
+ throw new Error('500 - MockedMediaApi.uploadChunk: method not implemented');
19
+ },
20
+ appendChunksToUpload: async () => {
21
+ throw new Error('500 - MockedMediaApi.appendChunksToUpload: method not implemented');
22
+ },
23
+ createFileFromUpload: async ({
24
+ uploadId
25
+ }, {
26
+ collection
27
+ }) => {
28
+ throw new Error('500 - MockedMediaApi.createFileFromUpload: method not implemented');
29
+ },
30
+ // Used by Media Picker as a fallback for conflicted file Ids
31
+ createUpload: async () => {
32
+ throw new Error('500 - MockedMediaApi.createUpload: method not implemented');
33
+ },
34
+ // For File size limits
35
+ getRejectedResponseFromDescriptor: () => {
36
+ throw new Error('500 - MockedMediaApi.getRejectedResponseFromDescriptor: method not implemented');
37
+ },
38
+ // --------------------------------------------------------
39
+ // METADATA ENDPOINTS
40
+ // --------------------------------------------------------
41
+
42
+ getFile: async fileId => {
43
+ const fileItem = getFileItem(fileId);
44
+ if (!fileItem) {
45
+ throw new Error('404 - MockedMediaApi.getFile: file not found');
46
+ }
47
+ return {
48
+ data: getMediaFile(fileItem)
49
+ };
50
+ },
51
+ getItems: async ids => {
52
+ const items = ids.map(id => getFileItem(id)).filter(fileState => !!fileState);
53
+ return {
54
+ data: {
55
+ items
56
+ }
57
+ };
58
+ },
59
+ // TODO
60
+ getImageMetadata: async () => {
61
+ throw new Error('500 - MockedMediaApi.getImageMetadata: method not implemented');
62
+ },
63
+ // --------------------------------------------------------
64
+ // URL ENDPOINTS
65
+ // --------------------------------------------------------
66
+
67
+ // TODO
68
+ getFileImageURL: async () => {
69
+ throw new Error('500 - MockedMediaApi.getFileImageURL: method not implemented');
70
+ },
71
+ // TODO
72
+ getFileImageURLSync: () => {
73
+ throw new Error('500 - MockedMediaApi.getFileImageURLSync: method not implemented');
74
+ },
75
+ getFileBinaryURL: async id => {
76
+ const fileItem = getFileItem(id);
77
+ if (!fileItem) {
78
+ throw new Error('404 - MockedMediaApi.getFileBinaryURL: file not found');
79
+ }
80
+ if (fileItem.details.size === 0) {
81
+ // TODO veryify if this is the correct answer for an uploading file
82
+ throw new Error('404 - MockedMediaApi.getFileBinaryURL: file is empty');
83
+ }
84
+ return `/file/${id}/binary`;
85
+ },
86
+ getArtifactURL: async (artifacts, artifactName) => {
87
+ var _artifacts$artifactNa;
88
+ const artifactUrl = (_artifacts$artifactNa = artifacts[artifactName]) === null || _artifacts$artifactNa === void 0 ? void 0 : _artifacts$artifactNa.url;
89
+ if (!artifactUrl) {
90
+ throw new Error(`404 - MockedMediaApi.getArtifactURL: artifact ${artifactName} not found`);
91
+ }
92
+ return artifactUrl;
93
+ },
94
+ // --------------------------------------------------------
95
+ // BINARY ENDPOINTS
96
+ // --------------------------------------------------------
97
+ getImage: async fileId => {
98
+ const fileItem = getFileItem(fileId);
99
+ if (!fileItem) {
100
+ throw new Error('404 - MockedMediaApi.getImage: file not found');
101
+ }
102
+ if (!fileItem.details.representations.image) {
103
+ throw new Error('404 - MockedMediaApi.getImage: image not found');
104
+ }
105
+
106
+ // Empty Blob. Might have to change for a real one if TLR loads the image
107
+ return new Blob();
108
+ },
109
+ // --------------------------------------------------------
110
+ // OTHER ENDPOINTS
111
+ // --------------------------------------------------------
112
+
113
+ // TODO
114
+ copyFileWithToken: async body => {
115
+ const fileId = body.sourceFile.id;
116
+ const fileItem = getFileItem(fileId);
117
+ if (!fileItem) {
118
+ throw new Error('404 - MockedMediaApi.copyFileWithToken: file not found');
119
+ }
120
+ return {
121
+ data: getMediaFile(fileItem)
122
+ };
123
+ },
124
+ // TODO
125
+ removeCollectionFile: async () => {},
126
+ // --------------------------------------------------------
127
+ // OTHER ENDPOINTS
128
+ // --------------------------------------------------------
129
+ request: async () => new Response(),
130
+ resolveAuth: async () => ({
131
+ asapIssuer: '',
132
+ token: '',
133
+ baseUrl: ''
134
+ }),
135
+ resolveInitialAuth: () => ({
136
+ asapIssuer: '',
137
+ token: '',
138
+ baseUrl: ''
139
+ })
140
+ });
141
+
142
+ /**
143
+ * Mocked Media API
144
+ */
145
+ export const createMockedMediaApi = initialFileItems => {
146
+ const storedFileItems = new Map();
147
+ const getFileItem = fileId => storedFileItems.get(fileId);
148
+ const setFileItems = fileItems => {
149
+ const normalised = normaliseInput(fileItems);
150
+ normalised.forEach(fileItem => storedFileItems.set(fileItem.id, fileItem));
151
+ };
152
+ if (initialFileItems) {
153
+ setFileItems(initialFileItems);
154
+ }
155
+ const mediaApi = getMediaApi({
156
+ setFileItems,
157
+ getFileItem
158
+ });
159
+ return {
160
+ setFileItems,
161
+ getFileItem,
162
+ mediaApi
163
+ };
164
+ };
@@ -0,0 +1,166 @@
1
+ import uuid from 'uuid/v4';
2
+ // --------------------------------------------------------
3
+ // Factory Utils
4
+ // --------------------------------------------------------
5
+ export const normaliseInput = input => !input ? [] : input instanceof Array ? input : [input];
6
+
7
+ // --------------------------------------------------------
8
+ // Utils for the main class
9
+ // --------------------------------------------------------
10
+
11
+ export const getMediaFile = fileItem => ({
12
+ id: fileItem.id,
13
+ ...fileItem.details
14
+ });
15
+
16
+ // --------------------------------------------------------
17
+ // Utils for creating file descriptors for tests
18
+ // --------------------------------------------------------
19
+
20
+ export const createEmptyFileItem = (id, collection) => {
21
+ const emptyFileItem = {
22
+ type: 'file',
23
+ id,
24
+ details: {
25
+ mediaType: 'unknown',
26
+ mimeType: 'binary/octet-stream',
27
+ name: '',
28
+ size: 0,
29
+ processingStatus: 'pending',
30
+ artifacts: {},
31
+ representations: {},
32
+ createdAt: 1699488941974
33
+ }
34
+ };
35
+ if (collection) {
36
+ emptyFileItem.collection = collection;
37
+ }
38
+ return emptyFileItem;
39
+ };
40
+
41
+ /**
42
+ * Simulates the processing of the file by updating the processing status of the artifacts by a percentage
43
+ * Percent must be between 0 and 1
44
+ */
45
+ export const createProcessingFileItem = (fileItem, percent) => {
46
+ if (percent < 0 || percent > 1) {
47
+ throw new Error('Error createProcessingFileItem: percent must be between 0 and 1');
48
+ }
49
+
50
+ /**
51
+ * This behaviour has to be confirmed
52
+ * Artifacts show up immediately after processed or they have a
53
+ * "processing time"?
54
+ */
55
+
56
+ if (percent === 1) {
57
+ return fileItem;
58
+ }
59
+
60
+ // No artifacts for 0% processing
61
+ if (percent === 0) {
62
+ return {
63
+ ...fileItem,
64
+ details: {
65
+ ...fileItem.details,
66
+ processingStatus: 'pending',
67
+ artifacts: {},
68
+ // The preview will only be ready at 100% -> TODO verify against backend
69
+ representations: {}
70
+ }
71
+ };
72
+ }
73
+ const artifactsKeys = Object.keys(fileItem.details.artifacts);
74
+ const artifactsEntries = Object.entries({
75
+ ...fileItem.details.artifacts // Spreading to make TS happy
76
+ });
77
+
78
+ // Get a % of the total artifacts to be set as processed
79
+ const processedArtifactKeys = artifactsKeys.slice(0, Math.ceil(artifactsKeys.length * percent));
80
+ const processedArtifactEntries = artifactsEntries.map(([key, artifact]) => [key, {
81
+ ...artifact,
82
+ processingStatus: processedArtifactKeys.includes(key) ? 'succeeded' : 'pending'
83
+ }]);
84
+ const artifactsProcessingPercent = Object.fromEntries(processedArtifactEntries);
85
+ return {
86
+ ...fileItem,
87
+ details: {
88
+ ...fileItem.details,
89
+ processingStatus: 'pending',
90
+ artifacts: artifactsProcessingPercent,
91
+ // The preview will only be ready at 100% -> TODO verify against backend
92
+ representations: {}
93
+ }
94
+ };
95
+ };
96
+
97
+ /**
98
+ * Makes a copy of the provided file item with a random file id
99
+ * */
100
+ export const copy = fileItem => JSON.parse(JSON.stringify(fileItem).replace(new RegExp(fileItem.id, 'g'), uuid()));
101
+ /**
102
+ * Extracts the file identifier from the provided file item
103
+ */
104
+ export const getIdentifier = fileItem => ({
105
+ mediaItemType: 'file',
106
+ id: fileItem.id,
107
+ collectionName: fileItem.collection
108
+ });
109
+ export const createFileState = ({
110
+ id,
111
+ details: {
112
+ name,
113
+ size,
114
+ mediaType,
115
+ mimeType,
116
+ createdAt,
117
+ processingStatus,
118
+ artifacts,
119
+ representations
120
+ }
121
+ }) => ({
122
+ status: processingStatus === 'succeeded' ? 'processed' : 'processing',
123
+ id,
124
+ name,
125
+ size,
126
+ mediaType,
127
+ mimeType,
128
+ createdAt,
129
+ artifacts,
130
+ representations
131
+ });
132
+ export const createUploadingFileState = ({
133
+ id,
134
+ details: {
135
+ name,
136
+ size,
137
+ mediaType,
138
+ mimeType,
139
+ createdAt
140
+ }
141
+ }, progress) => ({
142
+ status: 'uploading',
143
+ progress,
144
+ id,
145
+ name,
146
+ size,
147
+ mediaType,
148
+ mimeType,
149
+ createdAt,
150
+ preview: {
151
+ value: new Blob(['some-content'], {
152
+ type: mimeType
153
+ })
154
+ }
155
+ });
156
+ export const createErrorFileState = ({
157
+ id
158
+ }) => ({
159
+ status: 'error',
160
+ id,
161
+ reason: 'a random error',
162
+ message: 'a random error message',
163
+ details: {
164
+ some: 'mocked error detail'
165
+ }
166
+ });