diff --git a/packages/upload-client/mock-server/controllers/group.ts b/packages/upload-client/mock-server/controllers/group.ts index 4ba350ece..02893d120 100644 --- a/packages/upload-client/mock-server/controllers/group.ts +++ b/packages/upload-client/mock-server/controllers/group.ts @@ -86,7 +86,17 @@ const index = (ctx) => { }) } - ctx.body = find(json, 'info') + const response = find(json, 'info') as (typeof json)['info'] + response.files = files.map((file) => { + const uuid = file.split('/')[0] + const effects = file.split('/-/')[1] ?? '' + return { + ...response.files[0], + uuid, + default_effects: effects.replace(/^-\//, '') + } + }) + ctx.body = response } /** diff --git a/packages/upload-client/mock-server/data/group.ts b/packages/upload-client/mock-server/data/group.ts index 786077c35..249622255 100644 --- a/packages/upload-client/mock-server/data/group.ts +++ b/packages/upload-client/mock-server/data/group.ts @@ -31,33 +31,8 @@ export default { datetime_original: '2018-08-20T08:59:50', dpi: [72, 72] }, - mime_type: 'image/jpeg' - }, - { - is_stored: false, - done: 2667636, - file_id: 'd3275f8b-686d-4980-916a-53a1fc17450b', - total: 2667636, - size: 2667636, - uuid: 'd3275f8b-686d-4980-916a-53a1fc17450b', - is_image: true, - filename: 'newFileName.jpg', - video_info: null, - is_ready: true, - original_filename: 'newFileName.jpg', - image_info: { - orientation: 6, - format: 'JPEG', - height: 4032, - width: 3024, - geo_location: { - latitude: 55.62013611111111, - longitude: 37.66299166666666 - }, - datetime_original: '2018-08-20T08:59:50', - dpi: [72, 72] - }, - mime_type: 'image/jpeg' + mime_type: 'image/jpeg', + default_effects: '' } ] } diff --git a/packages/upload-client/src/api/types.ts b/packages/upload-client/src/api/types.ts index 7f82d4e07..164092c77 100644 --- a/packages/upload-client/src/api/types.ts +++ b/packages/upload-client/src/api/types.ts @@ -25,12 +25,17 @@ export type FileInfo = { metadata?: Metadata } +export type GroupFileInfo = FileInfo & { + defaultEffects: string +} + export type GroupInfo = { datetimeCreated: string datetimeStored: string | null filesCount: string cdnUrl: string - files: FileInfo[] + // An array may contain null values if a file has been removed. + files: (GroupFileInfo | null)[] url: string id: GroupId } diff --git a/packages/upload-client/src/index.ts b/packages/upload-client/src/index.ts index 37022b60a..c46c35a9e 100644 --- a/packages/upload-client/src/index.ts +++ b/packages/upload-client/src/index.ts @@ -95,6 +95,7 @@ export { FileInfo, GroupId, GroupInfo, + GroupFileInfo, Token, Url, Uuid, diff --git a/packages/upload-client/src/tools/UploadcareFile.ts b/packages/upload-client/src/tools/UploadcareFile.ts index 1389ea258..0f3737f48 100644 --- a/packages/upload-client/src/tools/UploadcareFile.ts +++ b/packages/upload-client/src/tools/UploadcareFile.ts @@ -1,4 +1,4 @@ -import { FileInfo, Uuid } from '../api/types' +import { FileInfo, GroupFileInfo, Uuid } from '../api/types' import { ContentInfo, ImageInfo, @@ -8,6 +8,11 @@ import { import getUrl from './getUrl' import defaultSettings from '../defaultSettings' +function isGroupFileInfo( + fileInfo: FileInfo | GroupFileInfo +): fileInfo is GroupFileInfo { + return 'defaultEffects' in fileInfo +} export class UploadcareFile { readonly uuid: Uuid readonly name: null | string = null @@ -23,9 +28,10 @@ export class UploadcareFile { readonly contentInfo: null | ContentInfo = null readonly metadata: null | Metadata = null readonly s3Bucket: null | string = null + readonly defaultEffects: null | string = null constructor( - fileInfo: FileInfo, + fileInfo: FileInfo | GroupFileInfo, { baseCDN = defaultSettings.baseCDN, fileName @@ -57,5 +63,9 @@ export class UploadcareFile { this.metadata = fileInfo.metadata || null this.s3Bucket = s3Bucket || null this.s3Url = s3Url + + if (isGroupFileInfo(fileInfo)) { + this.defaultEffects = fileInfo.defaultEffects + } } } diff --git a/packages/upload-client/src/tools/UploadcareGroup.ts b/packages/upload-client/src/tools/UploadcareGroup.ts index 54bcf1a9c..7abe8a0d2 100644 --- a/packages/upload-client/src/tools/UploadcareGroup.ts +++ b/packages/upload-client/src/tools/UploadcareGroup.ts @@ -1,4 +1,5 @@ -import { GroupId, GroupInfo } from '../api/types' +import { GroupFileInfo, GroupId, GroupInfo } from '../api/types' +import defaultSettings from '../defaultSettings' import { UploadcareFile } from './UploadcareFile' export class UploadcareGroup { @@ -12,19 +13,28 @@ export class UploadcareGroup { readonly createdAt: string readonly storedAt: string | null = null - constructor(groupInfo: GroupInfo, files: UploadcareFile[]) { + constructor( + groupInfo: GroupInfo, + { + baseCDN = defaultSettings.baseCDN + }: { + baseCDN?: string + } = {} + ) { this.uuid = groupInfo.id this.filesCount = groupInfo.filesCount - this.totalSize = Object.values(groupInfo.files).reduce( + const groupFiles = groupInfo.files.filter(Boolean) as GroupFileInfo[] + this.totalSize = Object.values(groupFiles).reduce( (acc, file) => acc + file.size, 0 ) this.isStored = !!groupInfo.datetimeStored - this.isImage = !!Object.values(groupInfo.files).filter( - (file) => file.isImage - ).length + this.isImage = !!Object.values(groupFiles).filter((file) => file.isImage) + .length this.cdnUrl = groupInfo.cdnUrl - this.files = files + this.files = groupFiles.map( + (fileInfo) => new UploadcareFile(fileInfo, { baseCDN }) + ) this.createdAt = groupInfo.datetimeCreated this.storedAt = groupInfo.datetimeStored } diff --git a/packages/upload-client/src/uploadFileGroup/uploadFileGroup.ts b/packages/upload-client/src/uploadFileGroup/uploadFileGroup.ts index 756c8cdfc..3d0f5dece 100644 --- a/packages/upload-client/src/uploadFileGroup/uploadFileGroup.ts +++ b/packages/upload-client/src/uploadFileGroup/uploadFileGroup.ts @@ -1,8 +1,7 @@ import group from '../api/group' import defaultSettings from '../defaultSettings' -import { UploadcareFile } from '../tools/UploadcareFile' import { UploadcareGroup } from '../tools/UploadcareGroup' -import { uploadFile, FileFromOptions } from '../uploadFile' +import { FileFromOptions, uploadFile } from '../uploadFile' /* Types */ import { @@ -12,7 +11,9 @@ import { Url, Uuid } from '../api/types' +import { isFileData } from '../tools/isFileData' import { SupportedFileInput } from '../types' +import { isUrl } from '../uploadFile/types' import { isFileDataArray, isUrlArray, isUuidArray } from './types' export type GroupFromOptions = { @@ -80,39 +81,43 @@ export function uploadFileGroup( } } - return Promise.all( + return Promise.all( (data as SupportedFileInput[]).map( - (file: SupportedFileInput | Url | Uuid, index: number) => - uploadFile(file, { - publicKey, - - fileName, - baseURL, - secureSignature, - secureExpire, - store, - - signal, - onProgress: createProgressHandler(filesCount, index), - - source, - integration, - userAgent, - - retryThrottledRequestMaxTimes, - retryNetworkErrorMaxTimes, - - contentType, - multipartChunkSize, - - baseCDN, - checkForUrlDuplicates, - saveUrlForRecurrentUploads - }) + (file: SupportedFileInput | Url | Uuid, index: number) => { + if (isFileData(file) || isUrl(file)) { + return uploadFile(file, { + publicKey, + + fileName, + baseURL, + secureSignature, + secureExpire, + store, + + signal, + onProgress: createProgressHandler(filesCount, index), + + source, + integration, + userAgent, + + retryThrottledRequestMaxTimes, + retryNetworkErrorMaxTimes, + + contentType, + multipartChunkSize, + + baseCDN, + checkForUrlDuplicates, + saveUrlForRecurrentUploads + }).then((fileInfo) => fileInfo.uuid) + } else { + // Do not request file info by uuid before creating group because this isn't necessary + return file + } + } ) - ).then((files) => { - const uuids = files.map((file) => file.uuid) - + ).then((uuids) => { return group(uuids, { publicKey, baseURL, @@ -126,7 +131,7 @@ export function uploadFileGroup( retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes }) - .then((groupInfo) => new UploadcareGroup(groupInfo, files)) + .then((groupInfo) => new UploadcareGroup(groupInfo, { baseCDN })) .then((group) => { onProgress && onProgress({ isComputable: true, value: 1 }) return group diff --git a/packages/upload-client/test/_fixtureFactory.ts b/packages/upload-client/test/_fixtureFactory.ts index d04a7629f..18a1b7b03 100644 --- a/packages/upload-client/test/_fixtureFactory.ts +++ b/packages/upload-client/test/_fixtureFactory.ts @@ -158,7 +158,7 @@ export function groupOfFiles(id: string): Array { const groupOfFiles = { valid: [ '392e3aa3-5ed6-4ad6-a67e-b3a7c1d5b9e9', - '49b4c5a1-31b3-4349-ba07-d97a2d883c37' + '49b4c5a1-31b3-4349-ba07-d97a2d883c37/-/resize/x800/' ], invalid: [ '2e6b7f23-9143-4b71-94e7-338bb', diff --git a/packages/upload-client/test/api/group.test.ts b/packages/upload-client/test/api/group.test.ts index bac68cc65..111baebd8 100644 --- a/packages/upload-client/test/api/group.test.ts +++ b/packages/upload-client/test/api/group.test.ts @@ -2,6 +2,7 @@ import * as factory from '../_fixtureFactory' import { getSettingsForTesting } from '../_helpers' import group from '../../src/api/group' import { UploadClientError } from '../../src/tools/errors' +import { GroupFileInfo } from '../../src' describe('API - group', () => { const files = factory.groupOfFiles('valid') @@ -9,12 +10,16 @@ describe('API - group', () => { publicKey: factory.publicKey('image') }) - it('should upload group of files', async () => { + it('should create group of files', async () => { const data = await group(files, settings) - + const groupFiles = data.files.filter(Boolean) as GroupFileInfo[] expect(data).toBeTruthy() expect(data.id).toBeTruthy() expect(data.files).toBeTruthy() + expect(groupFiles[0].uuid).toBe(files[0]) + expect(groupFiles[0].defaultEffects).toBe('') + expect(groupFiles[1].uuid).toBe(files[1].split('/')[0]) + expect(groupFiles[1].defaultEffects).toBe('resize/x800/') }) it('should fail with [HTTP 400] No files[N] parameters found.', async () => { diff --git a/packages/upload-client/test/uploadFileGroup/groupFromUploaded.test.ts b/packages/upload-client/test/uploadFileGroup/groupFromUploaded.test.ts index cf4bd706d..1488647ef 100644 --- a/packages/upload-client/test/uploadFileGroup/groupFromUploaded.test.ts +++ b/packages/upload-client/test/uploadFileGroup/groupFromUploaded.test.ts @@ -5,16 +5,21 @@ import { UploadClientError } from '../../src/tools/errors' import { jest, expect } from '@jest/globals' describe('groupFrom Uploaded[]', () => { - const uuid = factory.uuid('image') - const files = [uuid, uuid] + const files = factory.groupOfFiles('valid') const settings = getSettingsForTesting({ publicKey: factory.publicKey('image') }) it('should resolves when file is ready on CDN', async () => { - const { cdnUrl } = await uploadFileGroup(files, settings) + const data = await uploadFileGroup(files, settings) - expect(cdnUrl).toBeTruthy() + expect(data).toBeTruthy() + expect(data.uuid).toBeTruthy() + expect(data.files).toBeTruthy() + expect(data.files[0].uuid).toBe(files[0]) + expect(data.files[0].defaultEffects).toBe('') + expect(data.files[1].uuid).toBe(files[1].split('/')[0]) + expect(data.files[1].defaultEffects).toBe('resize/x800/') }) it('should accept store setting', async () => {