diff --git a/node_modules/react-native/Libraries/Blob/FileReader.js b/node_modules/react-native/Libraries/Blob/FileReader.js index 15a8b44..5a47924 100644 --- a/node_modules/react-native/Libraries/Blob/FileReader.js +++ b/node_modules/react-native/Libraries/Blob/FileReader.js @@ -12,6 +12,7 @@ const Blob = require('./Blob'); const EventTarget = require('event-target-shim'); +const { toByteArray } = require('base64-js'); import NativeFileReaderModule from './NativeFileReaderModule'; @@ -81,8 +82,35 @@ class FileReader extends (EventTarget(...READER_EVENTS): any) { } } - readAsArrayBuffer() { - throw new Error('FileReader.readAsArrayBuffer is not implemented'); + readAsArrayBuffer(blob: ?Blob) { + this._aborted = false; + + if (blob == null) { + throw new TypeError( + "Failed to execute 'readAsArrayBuffer' on 'FileReader': parameter 1 is not of type 'Blob'", + ); + } + + NativeFileReaderModule.readAsDataURL(blob.data).then( + (text: string) => { + if (this._aborted) { + return; + } + + const base64 = text.split(',')[1]; + const typedArray = toByteArray(base64); + + this._result = typedArray.buffer; + this._setReadyState(DONE); + }, + error => { + if (this._aborted) { + return; + } + this._error = error; + this._setReadyState(DONE); + }, + ); } readAsDataURL(blob: ?Blob) { diff --git a/node_modules/react-native/Libraries/Network/FormData.js b/node_modules/react-native/Libraries/Network/FormData.js index bdb1da3..2ef68aa 100644 --- a/node_modules/react-native/Libraries/Network/FormData.js +++ b/node_modules/react-native/Libraries/Network/FormData.js @@ -11,7 +11,7 @@ 'use strict'; type FormDataValue = any; -type FormDataNameValuePair = [string, FormDataValue]; +type FormDataPartInternal = [string, FormDataValue, string]; type Headers = {[name: string]: string, ...}; type FormDataPart = @@ -49,25 +49,46 @@ type FormDataPart = * xhr.send(body); */ class FormData { - _parts: Array; + _parts: Array; constructor() { this._parts = []; } - append(key: string, value: FormDataValue) { + append(key: string, value: FormDataValue, fileName: string) { // The XMLHttpRequest spec doesn't specify if duplicate keys are allowed. // MDN says that any new values should be appended to existing values. // In any case, major browsers allow duplicate keys, so that's what we'll do // too. They'll simply get appended as additional form data parts in the // request body, leaving the server to deal with them. - this._parts.push([key, value]); + this._parts.push([key, value, fileName]); + } + + set(key: string, value: FormDataValue, fileName: string) { + const newParts = []; + let replaced = false; + + fileName = fileName || value.name || 'blob'; + + this._parts.forEach((part) => { + if (part[0] === key) { + newParts.push([key, value, fileName]); + replaced = true; + } else { + newParts.push(part); + } + }); + + if (!replaced) { + newParts.push([key, value, fileName]); + } + + this._parts = newParts; } getParts(): Array { - return this._parts.map(([name, value]) => { + return this._parts.map(([name, value, fileName]) => { const contentDisposition = 'form-data; name="' + name + '"'; - const headers: Headers = {'content-disposition': contentDisposition}; // The body part is a "blob", which in React Native just means @@ -75,13 +96,24 @@ class FormData { // have a `name` and `type` attribute to specify filename and // content type (cf. web Blob interface.) if (typeof value === 'object' && value) { - if (typeof value.name === 'string') { - headers['content-disposition'] += '; filename="' + value.name + '"'; - } - if (typeof value.type === 'string') { - headers['content-type'] = value.type; + headers['content-disposition'] += '; filename="' + fileName + '"'; + headers['content-type'] = value.type || 'application/octet-stream'; + + const blob = { + uri: value.uri, + type: value.type, + name: value.name, + }; + + if (value instanceof Blob) { + blob.uri = URL.createObjectURL(value); } - return {...value, headers, fieldName: name}; + + return { + ...blob, + headers, + fieldName: name + }; } // Convert non-object values to strings as per FormData.append() spec return {string: String(value), headers, fieldName: name};