Skip to content

Commit

Permalink
Merge pull request #487 from uploadcare/fix/upload-file-group-fix-unn…
Browse files Browse the repository at this point in the history
…ecessary-info-request

fix(upload-client): do not request fileInfo before creating group from uuid
  • Loading branch information
nd0ut authored Oct 18, 2023
2 parents 4df9e0c + 8fc0211 commit 7dab64a
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 79 deletions.
12 changes: 11 additions & 1 deletion packages/upload-client/mock-server/controllers/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

/**
Expand Down
29 changes: 2 additions & 27 deletions packages/upload-client/mock-server/data/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: ''
}
]
}
Expand Down
7 changes: 6 additions & 1 deletion packages/upload-client/src/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
1 change: 1 addition & 0 deletions packages/upload-client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export {
FileInfo,
GroupId,
GroupInfo,
GroupFileInfo,
Token,
Url,
Uuid,
Expand Down
14 changes: 12 additions & 2 deletions packages/upload-client/src/tools/UploadcareFile.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FileInfo, Uuid } from '../api/types'
import { FileInfo, GroupFileInfo, Uuid } from '../api/types'
import {
ContentInfo,
ImageInfo,
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
}
}
}
24 changes: 17 additions & 7 deletions packages/upload-client/src/tools/UploadcareGroup.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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
}
Expand Down
73 changes: 39 additions & 34 deletions packages/upload-client/src/uploadFileGroup/uploadFileGroup.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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 = {
Expand Down Expand Up @@ -80,39 +81,43 @@ export function uploadFileGroup(
}
}

return Promise.all<UploadcareFile>(
return Promise.all<Uuid>(
(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,
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion packages/upload-client/test/_fixtureFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ export function groupOfFiles(id: string): Array<string> {
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',
Expand Down
9 changes: 7 additions & 2 deletions packages/upload-client/test/api/group.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,24 @@ 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')
const settings = getSettingsForTesting({
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 () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down

0 comments on commit 7dab64a

Please sign in to comment.