@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.
- package/CHANGELOG.md +12 -0
- package/dist/cjs/client/media-store/MediaStore.js +631 -0
- package/dist/cjs/client/media-store/index.js +19 -627
- package/dist/cjs/client/media-store/types.js +5 -0
- package/dist/cjs/test-helpers/MockedMediaApi/MockedMediaApi.js +449 -0
- package/dist/cjs/test-helpers/MockedMediaApi/helpers.js +184 -0
- package/dist/cjs/test-helpers/MockedMediaApi/index.js +55 -0
- package/dist/cjs/test-helpers/index.js +49 -0
- package/dist/es2019/client/media-store/MediaStore.js +385 -0
- package/dist/es2019/client/media-store/index.js +1 -385
- package/dist/es2019/client/media-store/types.js +1 -0
- package/dist/es2019/test-helpers/MockedMediaApi/MockedMediaApi.js +164 -0
- package/dist/es2019/test-helpers/MockedMediaApi/helpers.js +166 -0
- package/dist/es2019/test-helpers/MockedMediaApi/index.js +2 -0
- package/dist/es2019/test-helpers/index.js +2 -1
- package/dist/esm/client/media-store/MediaStore.js +624 -0
- package/dist/esm/client/media-store/index.js +1 -624
- package/dist/esm/client/media-store/types.js +1 -0
- package/dist/esm/test-helpers/MockedMediaApi/MockedMediaApi.js +442 -0
- package/dist/esm/test-helpers/MockedMediaApi/helpers.js +176 -0
- package/dist/esm/test-helpers/MockedMediaApi/index.js +2 -0
- package/dist/esm/test-helpers/index.js +2 -1
- package/dist/types/client/media-store/MediaStore.d.ts +34 -0
- package/dist/types/client/media-store/index.d.ts +2 -166
- package/dist/types/client/media-store/types.d.ts +161 -0
- package/dist/types/test-helpers/MockedMediaApi/MockedMediaApi.d.ts +16 -0
- package/dist/types/test-helpers/MockedMediaApi/helpers.d.ts +23 -0
- package/dist/types/test-helpers/MockedMediaApi/index.d.ts +3 -0
- package/dist/types/test-helpers/index.d.ts +2 -0
- package/dist/types-ts4.5/client/media-store/MediaStore.d.ts +34 -0
- package/dist/types-ts4.5/client/media-store/index.d.ts +2 -166
- package/dist/types-ts4.5/client/media-store/types.d.ts +161 -0
- package/dist/types-ts4.5/test-helpers/MockedMediaApi/MockedMediaApi.d.ts +16 -0
- package/dist/types-ts4.5/test-helpers/MockedMediaApi/helpers.d.ts +23 -0
- package/dist/types-ts4.5/test-helpers/MockedMediaApi/index.d.ts +3 -0
- package/dist/types-ts4.5/test-helpers/index.d.ts +2 -0
- package/package.json +2 -2
- package/report.api.md +120 -1
- 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
|
-
|
|
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
|
+
});
|