Skip to content

Commit 36c4c25

Browse files
committed
fix(react-native): set default content-type if no one provided
1 parent 5b0d711 commit 36c4c25

File tree

6 files changed

+118
-7
lines changed

6 files changed

+118
-7
lines changed

Diff for: packages/upload-client/src/api/base.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import { retryIfFailed } from '../tools/retryIfFailed'
1414
/* Types */
1515
import { Uuid, ProgressCallback, Metadata } from './types'
1616
import { FailedResponse } from '../request/types'
17-
import { NodeFile, BrowserFile } from '../types'
17+
import { getContentType } from '../tools/getContentType'
18+
import { getFileName } from '../tools/getFileName'
1819
import { getStoreValue } from '../tools/getStoreValue'
1920

2021
export type BaseResponse = {
@@ -82,9 +83,8 @@ export default function base(
8283
data: buildFormData({
8384
file: {
8485
data: file,
85-
name: fileName || (file as File)?.name || defaultFilename,
86-
contentType:
87-
contentType || (file as File)?.type || defaultContentType
86+
name: fileName || getFileName(file),
87+
contentType: contentType || getContentType(file)
8888
},
8989
UPLOADCARE_PUB_KEY: publicKey,
9090
UPLOADCARE_STORE: getStoreValue(store),

Diff for: packages/upload-client/src/tools/getContentType.ts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { defaultContentType } from '../defaultSettings'
2+
import { SupportedFileInput } from '../types'
3+
import { isBlob, isFile, isReactNativeAsset } from './isFileData'
4+
5+
export const getContentType = (file: SupportedFileInput): string => {
6+
let contentType = ''
7+
if (isBlob(file) || isFile(file) || isReactNativeAsset(file)) {
8+
contentType = file.type
9+
}
10+
if (contentType) {
11+
return contentType
12+
}
13+
console.warn(
14+
`Cannot determine content type. Using default content type: ${defaultContentType}`,
15+
file
16+
)
17+
return defaultContentType
18+
}

Diff for: packages/upload-client/src/tools/getFileName.ts

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { defaultFilename } from '../defaultSettings'
2+
import { SupportedFileInput } from '../types'
3+
import { isBlob, isBuffer, isFile, isReactNativeAsset } from './isFileData'
4+
5+
export const getFileName = (file: SupportedFileInput): string => {
6+
let filename = ''
7+
8+
if (isFile(file) && file.name) {
9+
filename = file.name
10+
} else if (isBlob(file) || isBuffer(file)) {
11+
filename = ''
12+
} else if (isReactNativeAsset(file) && file.name) {
13+
filename = file.name
14+
}
15+
if (filename) {
16+
return filename
17+
}
18+
console.warn(
19+
`Cannot determine filename. Using default filename: ${defaultFilename}`,
20+
file
21+
)
22+
return defaultFilename
23+
}

Diff for: packages/upload-client/src/uploadFile/uploadMultipart.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ import {
2121
ProgressCallback,
2222
UnknownProgressInfo
2323
} from '../api/types'
24-
import { NodeFile, BrowserFile } from '../types'
24+
import { getContentType } from '../tools/getContentType'
25+
import { getFileName } from '../tools/getFileName'
26+
import { getFileSize } from '../tools/getFileSize'
27+
import { SupportedFileInput } from '../types'
2528

2629
export type MultipartOptions = {
2730
publicKey: string
@@ -125,8 +128,8 @@ const uploadMultipart = (
125128

126129
return multipartStart(size, {
127130
publicKey,
128-
contentType: contentType || (file as File).type || defaultContentType,
129-
fileName: fileName || (file as File).name || defaultFilename,
131+
contentType: contentType || getContentType(file),
132+
fileName: fileName || getFileName(file),
130133
baseURL,
131134
secureSignature,
132135
secureExpire,
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* @jest-environment jsdom
3+
*/
4+
import { getContentType } from '../../src/tools/getContentType'
5+
6+
describe('getContentType', () => {
7+
it('should return content type of Blob', () => {
8+
const blob = new Blob([''], { type: 'text/plain' })
9+
expect(getContentType(blob)).toEqual('text/plain')
10+
})
11+
12+
it('should return content type of File', () => {
13+
const file = new File([''], 'test.txt', { type: 'text/plain' })
14+
expect(getContentType(file)).toEqual('text/plain')
15+
})
16+
17+
it('should return content type of ReactNative asset', () => {
18+
const asset = { uri: 'file://data', name: 'test.txt', type: 'text/plain' }
19+
expect(getContentType(asset)).toEqual('text/plain')
20+
})
21+
22+
it('should return fallback value if no type found', () => {
23+
const blob = new Blob([''])
24+
expect(getContentType(blob)).toEqual('application/octet-stream')
25+
26+
const file = new File([''], 'test.txt')
27+
expect(getContentType(file)).toEqual('application/octet-stream')
28+
29+
const asset = { uri: 'file://data', name: 'test.txt', type: '' }
30+
expect(getContentType(asset)).toEqual('application/octet-stream')
31+
})
32+
})
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* @jest-environment jsdom
3+
*/
4+
import { expect, jest } from '@jest/globals'
5+
import { getFileName } from '../../src/tools/getFileName'
6+
7+
describe('getFileName', () => {
8+
it('should return filename of File', () => {
9+
const file = new File([''], 'test.txt')
10+
expect(getFileName(file)).toEqual('test.txt')
11+
})
12+
13+
it('should return filename of ReactNative asset', () => {
14+
const asset = { uri: 'file://data', name: 'test.txt', type: 'text/plain' }
15+
expect(getFileName(asset)).toEqual('test.txt')
16+
})
17+
18+
it('should return fallback value if no filename found', () => {
19+
const spy = jest.spyOn(console, 'warn').mockImplementation(() => ({}))
20+
21+
const blob = new Blob([''])
22+
expect(getFileName(blob)).toEqual('original')
23+
24+
const file = new File([''], '')
25+
expect(getFileName(file)).toEqual('original')
26+
27+
const buffer = Buffer.from('')
28+
expect(getFileName(buffer)).toEqual('original')
29+
30+
const asset = { uri: 'file://data', name: '', type: 'text/plain' }
31+
expect(getFileName(asset)).toEqual('original')
32+
33+
expect(spy).toBeCalledTimes(4)
34+
})
35+
})

0 commit comments

Comments
 (0)