react-native-blob-util 0.24.10 → 0.24.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/fetch.js CHANGED
@@ -1,350 +1,351 @@
1
- import {ReactNativeBlobUtilConfig} from './types';
2
- import URIUtil from './utils/uri';
3
- import fs from './fs';
4
- import getUUID from './utils/uuid';
5
- import {NativeEventEmitter} from 'react-native';
6
- import {FetchBlobResponse} from './class/ReactNativeBlobUtilBlobResponse';
7
- import CanceledFetchError from './class/ReactNativeBlobUtilCanceledFetchError';
8
- import ReactNativeBlobUtil from './codegenSpecs/NativeBlobUtils';
9
-
10
- const eventEmitter = new NativeEventEmitter(ReactNativeBlobUtil);
11
-
12
- // register message channel event handler.
13
- eventEmitter.addListener('ReactNativeBlobUtilMessage', (e) => {
14
- if (typeof e === 'string') e = JSON.parse(e);
15
-
16
- if (e.event === 'warn') {
17
- console.warn(e.detail);
18
- }
19
- else if (e.event === 'error') {
20
- throw e.detail;
21
- }
22
- else {
23
- console.log('ReactNativeBlobUtil native message', e.detail);
24
- }
25
- });
26
-
27
- /**
28
- * Calling this method will inject configurations into followed `fetch` method.
29
- * @param {ReactNativeBlobUtilConfig} options
30
- * Fetch API configurations, contains the following options :
31
- * @property {boolean} fileCache
32
- * When fileCache is `true`, response data will be saved in
33
- * storage with a random generated file name, rather than
34
- * a BASE64 encoded string.
35
- * @property {string} appendExt
36
- * Set this property to change file extension of random-
37
- * generated file name.
38
- * @property {string} path
39
- * If this property has a valid string format, resonse data
40
- * will be saved to specific file path. Default string format
41
- * is : `ReactNativeBlobUtil-file://path-to-file`
42
- * @property {string} key
43
- * If this property is set, it will be converted to md5, to
44
- * check if a file with this name exists.
45
- * If it exists, the absolute path is returned (no network
46
- * activity takes place )
47
- * If it doesn't exist, the file is downloaded as usual
48
- * @property {number} timeout
49
- * Request timeout in millionseconds, by default it's 60000ms.
50
- * @property {boolean} followRedirect
51
- * Follow redirects automatically, default true
52
- * @property {boolean} trusty
53
- * Trust all certificates
54
- * @property {boolean} wifiOnly
55
- * Only do requests through WiFi. Android SDK 21 or above only.
56
- *
57
- * @return {function} This method returns a `fetch` method instance.
58
- */
59
- export function config(options: ReactNativeBlobUtilConfig) {
60
- return {fetch: fetch.bind(options)};
61
- }
62
-
63
- /**
64
- * Fetch from file system, use the same interface as RNFB.fetch
65
- * @param {ReactNativeBlobUtilConfig} [options={}] Fetch configurations
66
- * @param {string} method Should be one of `get`, `post`, `put`
67
- * @param {string} url A file URI string
68
- * @param {string} headers Arguments of file system API
69
- * @param {any} body Data to put or post to file systen.
70
- * @return {Promise}
71
- */
72
- function fetchFile(options = {}, method, url, headers = {}, body): Promise {
73
-
74
- if (!URIUtil.isFileURI(url)) {
75
- throw `could not fetch file from an invalid URI : ${url}`;
76
- }
77
-
78
- url = URIUtil.unwrapFileURI(url);
79
-
80
- let promise = null,
81
- cursor = 0,
82
- total = -1,
83
- cacheData = '',
84
- info = null,
85
- _progress, _uploadProgress, _stateChange;
86
-
87
- switch (method.toLowerCase()) {
88
-
89
- case 'post':
90
- break;
91
-
92
- case 'put':
93
- break;
94
-
95
- // read data from file system
96
- default:
97
- promise = fs.stat(url)
98
- .then((stat) => {
99
- total = stat.size;
100
- return fs.readStream(url,
101
- headers.encoding || 'utf8',
102
- Math.floor(headers.bufferSize) || 409600,
103
- Math.floor(headers.interval) || 100
104
- );
105
- })
106
- .then((stream) => new Promise((resolve, reject) => {
107
- stream.open();
108
- info = {
109
- state: '2',
110
- headers: {'source': 'system-fs'},
111
- status: 200,
112
- respType: 'text',
113
- rnfbEncode: headers.encoding || 'utf8'
114
- };
115
- _stateChange(info);
116
- stream.onData((chunk) => {
117
- _progress && _progress(cursor, total, chunk);
118
- if (headers.noCache)
119
- return;
120
- cacheData += chunk;
121
- });
122
- stream.onError((err) => {
123
- reject(err);
124
- });
125
- stream.onEnd(() => {
126
- resolve(new FetchBlobResponse(null, info, cacheData));
127
- });
128
- }));
129
- break;
130
- }
131
-
132
- promise.progress = (fn) => {
133
- _progress = fn;
134
- return promise;
135
- };
136
- promise.stateChange = (fn) => {
137
- _stateChange = fn;
138
- return promise;
139
- };
140
- promise.uploadProgress = (fn) => {
141
- _uploadProgress = fn;
142
- return promise;
143
- };
144
-
145
- return promise;
146
- }
147
-
148
- /**
149
- * Create a HTTP request by settings, the `this` context is a `ReactNativeBlobUtilConfig` object.
150
- * @param {string} method HTTP method, should be `GET`, `POST`, `PUT`, `DELETE`
151
- * @param {string} url Request target url string.
152
- * @param {object} headers HTTP request headers.
153
- * @param {string} body
154
- * Request body, can be either a BASE64 encoded data string,
155
- * or a file path with prefix `ReactNativeBlobUtil-file://` (can be changed)
156
- * @return {Promise}
157
- * This promise instance also contains a Customized method `progress`for
158
- * register progress event handler.
159
- */
160
- export function fetch(...args: any): Promise {
161
-
162
- // create task ID for receiving progress event
163
- let taskId = getUUID();
164
- let options = this || {};
165
- let subscription, subscriptionUpload, stateEvent, partEvent;
166
- let respInfo = {'uninit': true};
167
- let [method, url, headers, body] = [...args];
168
-
169
- // # 241 normalize null or undefined headers, in case nil or null string
170
- // pass to native context
171
- headers = headers && Object.keys(headers).reduce((result, key) => {
172
- result[key] = headers[key] || '';
173
- return result;
174
- }, {});
175
-
176
- // fetch from file system
177
- if (URIUtil.isFileURI(url)) {
178
- return fetchFile(options, method, url, headers, body);
179
- }
180
-
181
- let promiseResolve;
182
- let promiseReject;
183
-
184
- // from remote HTTP(S)
185
- let promise = new Promise((resolve, reject) => {
186
- promiseResolve = resolve;
187
- promiseReject = reject;
188
-
189
- let nativeMethodName = Array.isArray(body) ? 'fetchBlobForm' : 'fetchBlob';
190
-
191
- // on progress event listener
192
- subscription = eventEmitter.addListener('ReactNativeBlobUtilProgress', (e) => {
193
- if (typeof e === 'string') e = JSON.parse(e);
194
- if (e.taskId === taskId && promise.onProgress) {
195
- promise.onProgress(e.written, e.total, e.chunk);
196
- }
197
- });
198
-
199
- subscriptionUpload = eventEmitter.addListener('ReactNativeBlobUtilProgress-upload', (e) => {
200
- if (typeof e === 'string') e = JSON.parse(e);
201
- if (e.taskId === taskId && promise.onUploadProgress) {
202
- promise.onUploadProgress(e.written, e.total);
203
- }
204
- });
205
-
206
- stateEvent = eventEmitter.addListener('ReactNativeBlobUtilState', (e) => {
207
- if (typeof e === 'string') e = JSON.parse(e);
208
- if (e.taskId === taskId)
209
- respInfo = e;
210
- promise.onStateChange && promise.onStateChange(e);
211
- });
212
-
213
- subscription = eventEmitter.addListener('ReactNativeBlobUtilExpire', (e) => {
214
- if (typeof e === 'string') e = JSON.parse(e);
215
- if (e.taskId === taskId && promise.onExpire) {
216
- promise.onExpire(e);
217
- }
218
- });
219
-
220
- partEvent = eventEmitter.addListener('ReactNativeBlobUtilServerPush', (e) => {
221
- if (typeof e === 'string') e = JSON.parse(e);
222
- if (e.taskId === taskId && promise.onPartData) {
223
- promise.onPartData(e.chunk);
224
- }
225
- });
226
-
227
- // When the request body comes from Blob polyfill, we should use special its ref
228
- // as the request body
229
- if (body instanceof Blob && body.isReactNativeBlobUtilPolyfill) {
230
- body = body.getReactNativeBlobUtilRef();
231
- }
232
-
233
- let req = ReactNativeBlobUtil[nativeMethodName];
234
-
235
- /**
236
- * Send request via native module, the response callback accepts three arguments
237
- * @callback
238
- * @param err {any} Error message or object, when the request success, this
239
- * parameter should be `null`.
240
- * @param rawType { 'utf8' | 'base64' | 'path'} RNFB request will be stored
241
- * as UTF8 string, BASE64 string, or a file path reference
242
- * in JS context, and this parameter indicates which one
243
- * dose the response data presents.
244
- * @param data {string} Response data or its reference.
245
- * @param responseInfo {Object.<>}
246
- */
247
- req(options, taskId, method, url, headers || {}, body, (err, rawType, data, responseInfo) => {
248
-
249
- // task done, remove event listeners
250
- subscription.remove();
251
- subscriptionUpload.remove();
252
- stateEvent.remove();
253
- partEvent.remove();
254
- delete promise.progress;
255
- delete promise.uploadProgress;
256
- delete promise.stateChange;
257
- delete promise.part;
258
- delete promise.cancel;
259
- // delete promise['expire']
260
- promise.cancel = () => {
261
- };
262
-
263
- if(!responseInfo) responseInfo = {}; // should not be null / undefined
264
-
265
- if (err)
266
- reject(new Error(err, respInfo));
267
- else {
268
- // response data is saved to storage, create a session for it
269
- if (options.path || options.fileCache || options.addAndroidDownloads
270
- || options.key || options.auto && respInfo.respType === 'blob') {
271
- if (options.session)
272
- fs.session(options.session).add(data);
273
- }
274
- if ('uninit' in respInfo && respInfo.uninit) // event didn't fire yet so we override it here
275
- respInfo = responseInfo;
276
-
277
- respInfo.rnfbEncode = rawType;
278
- resolve(new FetchBlobResponse(taskId, respInfo, data));
279
- }
280
-
281
- });
282
-
283
- });
284
-
285
- // extend Promise object, add `progress`, `uploadProgress`, and `cancel`
286
- // method for register progress event handler and cancel request.
287
- // Add second parameter for performance purpose #140
288
- // When there's only one argument pass to this method, use default `interval`
289
- // and `count`, otherwise use the given on.
290
- // TODO : code refactor, move `uploadProgress` and `progress` to StatefulPromise
291
- promise.progress = (...args) => {
292
- let interval = 250;
293
- let count = -1;
294
- let fn = () => {
295
- };
296
- if (args.length === 2) {
297
- interval = args[0].interval || interval;
298
- count = args[0].count || count;
299
- fn = args[1];
300
- }
301
- else {
302
- fn = args[0];
303
- }
304
- promise.onProgress = fn;
305
- ReactNativeBlobUtil.enableProgressReport(taskId, interval, count);
306
- return promise;
307
- };
308
- promise.uploadProgress = (...args) => {
309
- let interval = 250;
310
- let count = -1;
311
- let fn = () => {
312
- };
313
- if (args.length === 2) {
314
- interval = args[0].interval || interval;
315
- count = args[0].count || count;
316
- fn = args[1];
317
- }
318
- else {
319
- fn = args[0];
320
- }
321
- promise.onUploadProgress = fn;
322
- ReactNativeBlobUtil.enableUploadProgressReport(taskId, interval, count);
323
- return promise;
324
- };
325
- promise.part = (fn) => {
326
- promise.onPartData = fn;
327
- return promise;
328
- };
329
- promise.stateChange = (fn) => {
330
- promise.onStateChange = fn;
331
- return promise;
332
- };
333
- promise.expire = (fn) => {
334
- promise.onExpire = fn;
335
- return promise;
336
- };
337
- promise.cancel = (fn) => {
338
- fn = fn || function () {
339
- };
340
- subscription.remove();
341
- subscriptionUpload.remove();
342
- stateEvent.remove();
343
- ReactNativeBlobUtil.cancelRequest(taskId, fn);
344
- promiseReject(new CanceledFetchError('canceled'));
345
- };
346
- promise.taskId = taskId;
347
-
348
- return promise;
349
-
350
- }
1
+ import {ReactNativeBlobUtilConfig} from './types';
2
+ import URIUtil from './utils/uri';
3
+ import fs from './fs';
4
+ import getUUID from './utils/uuid';
5
+ import toByteCount from './utils/byteCount';
6
+ import {NativeEventEmitter} from 'react-native';
7
+ import {FetchBlobResponse} from './class/ReactNativeBlobUtilBlobResponse';
8
+ import CanceledFetchError from './class/ReactNativeBlobUtilCanceledFetchError';
9
+ import ReactNativeBlobUtil from './codegenSpecs/NativeBlobUtils';
10
+
11
+ const eventEmitter = new NativeEventEmitter(ReactNativeBlobUtil);
12
+
13
+ // register message channel event handler.
14
+ eventEmitter.addListener('ReactNativeBlobUtilMessage', (e) => {
15
+ if (typeof e === 'string') e = JSON.parse(e);
16
+
17
+ if (e.event === 'warn') {
18
+ console.warn(e.detail);
19
+ }
20
+ else if (e.event === 'error') {
21
+ throw e.detail;
22
+ }
23
+ else {
24
+ console.log('ReactNativeBlobUtil native message', e.detail);
25
+ }
26
+ });
27
+
28
+ /**
29
+ * Calling this method will inject configurations into followed `fetch` method.
30
+ * @param {ReactNativeBlobUtilConfig} options
31
+ * Fetch API configurations, contains the following options :
32
+ * @property {boolean} fileCache
33
+ * When fileCache is `true`, response data will be saved in
34
+ * storage with a random generated file name, rather than
35
+ * a BASE64 encoded string.
36
+ * @property {string} appendExt
37
+ * Set this property to change file extension of random-
38
+ * generated file name.
39
+ * @property {string} path
40
+ * If this property has a valid string format, resonse data
41
+ * will be saved to specific file path. Default string format
42
+ * is : `ReactNativeBlobUtil-file://path-to-file`
43
+ * @property {string} key
44
+ * If this property is set, it will be converted to md5, to
45
+ * check if a file with this name exists.
46
+ * If it exists, the absolute path is returned (no network
47
+ * activity takes place )
48
+ * If it doesn't exist, the file is downloaded as usual
49
+ * @property {number} timeout
50
+ * Request timeout in millionseconds, by default it's 60000ms.
51
+ * @property {boolean} followRedirect
52
+ * Follow redirects automatically, default true
53
+ * @property {boolean} trusty
54
+ * Trust all certificates
55
+ * @property {boolean} wifiOnly
56
+ * Only do requests through WiFi. Android SDK 21 or above only.
57
+ *
58
+ * @return {function} This method returns a `fetch` method instance.
59
+ */
60
+ export function config(options: ReactNativeBlobUtilConfig) {
61
+ return {fetch: fetch.bind(options)};
62
+ }
63
+
64
+ /**
65
+ * Fetch from file system, use the same interface as RNFB.fetch
66
+ * @param {ReactNativeBlobUtilConfig} [options={}] Fetch configurations
67
+ * @param {string} method Should be one of `get`, `post`, `put`
68
+ * @param {string} url A file URI string
69
+ * @param {string} headers Arguments of file system API
70
+ * @param {any} body Data to put or post to file systen.
71
+ * @return {Promise}
72
+ */
73
+ function fetchFile(options = {}, method, url, headers = {}, body): Promise {
74
+
75
+ if (!URIUtil.isFileURI(url)) {
76
+ throw `could not fetch file from an invalid URI : ${url}`;
77
+ }
78
+
79
+ url = URIUtil.unwrapFileURI(url);
80
+
81
+ let promise = null,
82
+ cursor = 0,
83
+ total = -1,
84
+ cacheData = '',
85
+ info = null,
86
+ _progress, _uploadProgress, _stateChange;
87
+
88
+ switch (method.toLowerCase()) {
89
+
90
+ case 'post':
91
+ break;
92
+
93
+ case 'put':
94
+ break;
95
+
96
+ // read data from file system
97
+ default:
98
+ promise = fs.stat(url)
99
+ .then((stat) => {
100
+ total = stat.size;
101
+ return fs.readStream(url,
102
+ headers.encoding || 'utf8',
103
+ Math.floor(headers.bufferSize) || 409600,
104
+ Math.floor(headers.interval) || 100
105
+ );
106
+ })
107
+ .then((stream) => new Promise((resolve, reject) => {
108
+ stream.open();
109
+ info = {
110
+ state: '2',
111
+ headers: {'source': 'system-fs'},
112
+ status: 200,
113
+ respType: 'text',
114
+ rnfbEncode: headers.encoding || 'utf8'
115
+ };
116
+ _stateChange(info);
117
+ stream.onData((chunk) => {
118
+ _progress && _progress(cursor, total, chunk);
119
+ if (headers.noCache)
120
+ return;
121
+ cacheData += chunk;
122
+ });
123
+ stream.onError((err) => {
124
+ reject(err);
125
+ });
126
+ stream.onEnd(() => {
127
+ resolve(new FetchBlobResponse(null, info, cacheData));
128
+ });
129
+ }));
130
+ break;
131
+ }
132
+
133
+ promise.progress = (fn) => {
134
+ _progress = fn;
135
+ return promise;
136
+ };
137
+ promise.stateChange = (fn) => {
138
+ _stateChange = fn;
139
+ return promise;
140
+ };
141
+ promise.uploadProgress = (fn) => {
142
+ _uploadProgress = fn;
143
+ return promise;
144
+ };
145
+
146
+ return promise;
147
+ }
148
+
149
+ /**
150
+ * Create a HTTP request by settings, the `this` context is a `ReactNativeBlobUtilConfig` object.
151
+ * @param {string} method HTTP method, should be `GET`, `POST`, `PUT`, `DELETE`
152
+ * @param {string} url Request target url string.
153
+ * @param {object} headers HTTP request headers.
154
+ * @param {string} body
155
+ * Request body, can be either a BASE64 encoded data string,
156
+ * or a file path with prefix `ReactNativeBlobUtil-file://` (can be changed)
157
+ * @return {Promise}
158
+ * This promise instance also contains a Customized method `progress`for
159
+ * register progress event handler.
160
+ */
161
+ export function fetch(...args: any): Promise {
162
+
163
+ // create task ID for receiving progress event
164
+ let taskId = getUUID();
165
+ let options = this || {};
166
+ let subscription, subscriptionUpload, stateEvent, partEvent;
167
+ let respInfo = {'uninit': true};
168
+ let [method, url, headers, body] = [...args];
169
+
170
+ // # 241 normalize null or undefined headers, in case nil or null string
171
+ // pass to native context
172
+ headers = headers && Object.keys(headers).reduce((result, key) => {
173
+ result[key] = headers[key] || '';
174
+ return result;
175
+ }, {});
176
+
177
+ // fetch from file system
178
+ if (URIUtil.isFileURI(url)) {
179
+ return fetchFile(options, method, url, headers, body);
180
+ }
181
+
182
+ let promiseResolve;
183
+ let promiseReject;
184
+
185
+ // from remote HTTP(S)
186
+ let promise = new Promise((resolve, reject) => {
187
+ promiseResolve = resolve;
188
+ promiseReject = reject;
189
+
190
+ let nativeMethodName = Array.isArray(body) ? 'fetchBlobForm' : 'fetchBlob';
191
+
192
+ // on progress event listener
193
+ subscription = eventEmitter.addListener('ReactNativeBlobUtilProgress', (e) => {
194
+ if (typeof e === 'string') e = JSON.parse(e);
195
+ if (e.taskId === taskId && promise.onProgress) {
196
+ promise.onProgress(toByteCount(e.written), toByteCount(e.total), e.chunk);
197
+ }
198
+ });
199
+
200
+ subscriptionUpload = eventEmitter.addListener('ReactNativeBlobUtilProgress-upload', (e) => {
201
+ if (typeof e === 'string') e = JSON.parse(e);
202
+ if (e.taskId === taskId && promise.onUploadProgress) {
203
+ promise.onUploadProgress(toByteCount(e.written), toByteCount(e.total));
204
+ }
205
+ });
206
+
207
+ stateEvent = eventEmitter.addListener('ReactNativeBlobUtilState', (e) => {
208
+ if (typeof e === 'string') e = JSON.parse(e);
209
+ if (e.taskId === taskId)
210
+ respInfo = e;
211
+ promise.onStateChange && promise.onStateChange(e);
212
+ });
213
+
214
+ subscription = eventEmitter.addListener('ReactNativeBlobUtilExpire', (e) => {
215
+ if (typeof e === 'string') e = JSON.parse(e);
216
+ if (e.taskId === taskId && promise.onExpire) {
217
+ promise.onExpire(e);
218
+ }
219
+ });
220
+
221
+ partEvent = eventEmitter.addListener('ReactNativeBlobUtilServerPush', (e) => {
222
+ if (typeof e === 'string') e = JSON.parse(e);
223
+ if (e.taskId === taskId && promise.onPartData) {
224
+ promise.onPartData(e.chunk);
225
+ }
226
+ });
227
+
228
+ // When the request body comes from Blob polyfill, we should use special its ref
229
+ // as the request body
230
+ if (body instanceof Blob && body.isReactNativeBlobUtilPolyfill) {
231
+ body = body.getReactNativeBlobUtilRef();
232
+ }
233
+
234
+ let req = ReactNativeBlobUtil[nativeMethodName];
235
+
236
+ /**
237
+ * Send request via native module, the response callback accepts three arguments
238
+ * @callback
239
+ * @param err {any} Error message or object, when the request success, this
240
+ * parameter should be `null`.
241
+ * @param rawType { 'utf8' | 'base64' | 'path'} RNFB request will be stored
242
+ * as UTF8 string, BASE64 string, or a file path reference
243
+ * in JS context, and this parameter indicates which one
244
+ * dose the response data presents.
245
+ * @param data {string} Response data or its reference.
246
+ * @param responseInfo {Object.<>}
247
+ */
248
+ req(options, taskId, method, url, headers || {}, body, (err, rawType, data, responseInfo) => {
249
+
250
+ // task done, remove event listeners
251
+ subscription.remove();
252
+ subscriptionUpload.remove();
253
+ stateEvent.remove();
254
+ partEvent.remove();
255
+ delete promise.progress;
256
+ delete promise.uploadProgress;
257
+ delete promise.stateChange;
258
+ delete promise.part;
259
+ delete promise.cancel;
260
+ // delete promise['expire']
261
+ promise.cancel = () => {
262
+ };
263
+
264
+ if(!responseInfo) responseInfo = {}; // should not be null / undefined
265
+
266
+ if (err)
267
+ reject(new Error(err, respInfo));
268
+ else {
269
+ // response data is saved to storage, create a session for it
270
+ if (options.path || options.fileCache || options.addAndroidDownloads
271
+ || options.key || options.auto && respInfo.respType === 'blob') {
272
+ if (options.session)
273
+ fs.session(options.session).add(data);
274
+ }
275
+ if ('uninit' in respInfo && respInfo.uninit) // event didn't fire yet so we override it here
276
+ respInfo = responseInfo;
277
+
278
+ respInfo.rnfbEncode = rawType;
279
+ resolve(new FetchBlobResponse(taskId, respInfo, data));
280
+ }
281
+
282
+ });
283
+
284
+ });
285
+
286
+ // extend Promise object, add `progress`, `uploadProgress`, and `cancel`
287
+ // method for register progress event handler and cancel request.
288
+ // Add second parameter for performance purpose #140
289
+ // When there's only one argument pass to this method, use default `interval`
290
+ // and `count`, otherwise use the given on.
291
+ // TODO : code refactor, move `uploadProgress` and `progress` to StatefulPromise
292
+ promise.progress = (...args) => {
293
+ let interval = 250;
294
+ let count = -1;
295
+ let fn = () => {
296
+ };
297
+ if (args.length === 2) {
298
+ interval = args[0].interval || interval;
299
+ count = args[0].count || count;
300
+ fn = args[1];
301
+ }
302
+ else {
303
+ fn = args[0];
304
+ }
305
+ promise.onProgress = fn;
306
+ ReactNativeBlobUtil.enableProgressReport(taskId, interval, count);
307
+ return promise;
308
+ };
309
+ promise.uploadProgress = (...args) => {
310
+ let interval = 250;
311
+ let count = -1;
312
+ let fn = () => {
313
+ };
314
+ if (args.length === 2) {
315
+ interval = args[0].interval || interval;
316
+ count = args[0].count || count;
317
+ fn = args[1];
318
+ }
319
+ else {
320
+ fn = args[0];
321
+ }
322
+ promise.onUploadProgress = fn;
323
+ ReactNativeBlobUtil.enableUploadProgressReport(taskId, interval, count);
324
+ return promise;
325
+ };
326
+ promise.part = (fn) => {
327
+ promise.onPartData = fn;
328
+ return promise;
329
+ };
330
+ promise.stateChange = (fn) => {
331
+ promise.onStateChange = fn;
332
+ return promise;
333
+ };
334
+ promise.expire = (fn) => {
335
+ promise.onExpire = fn;
336
+ return promise;
337
+ };
338
+ promise.cancel = (fn) => {
339
+ fn = fn || function () {
340
+ };
341
+ subscription.remove();
342
+ subscriptionUpload.remove();
343
+ stateEvent.remove();
344
+ ReactNativeBlobUtil.cancelRequest(taskId, fn);
345
+ promiseReject(new CanceledFetchError('canceled'));
346
+ };
347
+ promise.taskId = taskId;
348
+
349
+ return promise;
350
+
351
+ }