Skip to content

Commit

Permalink
fix(react-native): support direct uploads through FormData (#307)
Browse files Browse the repository at this point in the history
* fix: support direct uploads through FormData under react-native runtime

* chore: ignore lgtm warning

* chore: dont use word 'triple' in variable name
  • Loading branch information
nd0ut authored Mar 16, 2021
1 parent 589ddbe commit 428b039
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 7 deletions.
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
"./lib/tools/getFormData.node.js": "./lib/tools/getFormData.browser.js",
"./lib/tools/sockets.node.js": "./lib/tools/sockets.browser.js"
},
"react-native": {
"./lib/request/request.node.js": "./lib/request/request.browser.js",
"./lib/tools/getFormData.node.js": "./lib/tools/getFormData.react-native.js",
"./lib/tools/sockets.node.js": "./lib/tools/sockets.browser.js"
},
"scripts": {
"check-env-vars": "node ./checkvars.js",
"mock:start": "ts-node --project ./mock-server/tsconfig.mock.json ./mock-server/server.ts --silent",
Expand Down Expand Up @@ -52,9 +57,9 @@
"@types/koa": "2.11.4",
"@types/node": "12.12.67",
"@types/promise": "7.1.30",
"@types/ws": "7.2.7",
"@typescript-eslint/eslint-plugin": "2.34.0",
"@typescript-eslint/parser": "2.34.0",
"@types/ws": "7.2.7",
"chalk": "4.1.0",
"data-uri-to-buffer": "3.0.1",
"dataurl-to-blob": "0.0.1",
Expand Down
14 changes: 8 additions & 6 deletions src/tools/buildFormData.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import getFormData from './getFormData.node'
import getFormData, { transformFile } from './getFormData.node'

import * as NodeFormData from 'form-data'
import { BrowserFile, NodeFile } from '../request/types'
Expand All @@ -13,20 +13,22 @@ type FileTuple = ['file', BrowserFile | NodeFile, string]
type BaseType = string | number | void
type FormDataTuple = [string, BaseType | BaseType[]]

const isFileTuple = (tuple: FormDataTuple | FileTuple): tuple is FileTuple =>
tuple[0] === 'file'

function buildFormData(
body: (FormDataTuple | FileTuple)[]
): FormData | NodeFormData {
const formData = getFormData()

const isTriple = (tuple: FormDataTuple | FileTuple): tuple is FileTuple =>
tuple[0] === 'file'

for (const tuple of body) {
if (Array.isArray(tuple[1])) {
// refactor this
tuple[1].forEach(val => val && formData.append(tuple[0] + '[]', `${val}`))
} else if (isTriple(tuple)) {
formData.append(tuple[0], tuple[1] as Blob, tuple[2])
} else if (isFileTuple(tuple)) {
const name = tuple[2]
const file = transformFile(tuple[1], name) as Blob // lgtm[js/superfluous-trailing-arguments]
formData.append(tuple[0], file, name)
} else if (tuple[1] != null) {
formData.append(tuple[0], `${tuple[1]}`)
}
Expand Down
4 changes: 4 additions & 0 deletions src/tools/getFormData.browser.ts
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
import { FileTransformer } from './types'
import { identity } from './identity'

export const transformFile: FileTransformer = identity
export default (): FormData => new FormData()
3 changes: 3 additions & 0 deletions src/tools/getFormData.node.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import * as NodeFormData from 'form-data'
import { FileTransformer } from './types'
import { identity } from './identity'

export const transformFile: FileTransformer = identity
export default (): NodeFormData | FormData => new NodeFormData()
16 changes: 16 additions & 0 deletions src/tools/getFormData.react-native.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { BrowserFile, NodeFile } from '../request/types'
import { FileTransformer, ReactNativeAsset } from './types'

export const transformFile: FileTransformer = (
file: BrowserFile | NodeFile,
name: string
): ReactNativeAsset => {
if (!file) {
return file
}
const uri = URL.createObjectURL(file)
const type = (file as BrowserFile).type
return { uri, name, type }
}

export default (): FormData => new FormData()
3 changes: 3 additions & 0 deletions src/tools/identity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function identity<T>(obj: T): T {
return obj
}
8 changes: 8 additions & 0 deletions src/tools/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { BrowserFile, NodeFile } from '../request/types'

export type ReactNativeAsset = { name?: string; type?: string; uri: string }

export type FileTransformer = (
file: NodeFile | BrowserFile,
name: string
) => NodeFile | BrowserFile | ReactNativeAsset

0 comments on commit 428b039

Please sign in to comment.