@hxa-rn/rn-fetch-blob 0.12.0

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.
Files changed (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +290 -0
  3. package/harmony/fetch_blob/LICENSE +21 -0
  4. package/harmony/fetch_blob/NOTICE +33 -0
  5. package/harmony/fetch_blob/OAT.xml +38 -0
  6. package/harmony/fetch_blob/build-profile.json5 +16 -0
  7. package/harmony/fetch_blob/hvigorfile.ts +2 -0
  8. package/harmony/fetch_blob/index.ets +1 -0
  9. package/harmony/fetch_blob/oh-package.json5 +14 -0
  10. package/harmony/fetch_blob/src/main/cpp/CMakeLists.txt +15 -0
  11. package/harmony/fetch_blob/src/main/cpp/FetchBlobPackage.h +13 -0
  12. package/harmony/fetch_blob/src/main/cpp/generated/RNOH/generated/BaseFetchBlobPackage.h +72 -0
  13. package/harmony/fetch_blob/src/main/cpp/generated/RNOH/generated/turbo_modules/RNFetchBlob.cpp +55 -0
  14. package/harmony/fetch_blob/src/main/cpp/generated/RNOH/generated/turbo_modules/RNFetchBlob.h +16 -0
  15. package/harmony/fetch_blob/src/main/ets/FetchBlobTurboModulesFactory.ets +18 -0
  16. package/harmony/fetch_blob/src/main/ets/Logger.ts +40 -0
  17. package/harmony/fetch_blob/src/main/ets/RNFetchBlobConfig.ts +45 -0
  18. package/harmony/fetch_blob/src/main/ets/RNFetchBlobFS.ts +673 -0
  19. package/harmony/fetch_blob/src/main/ets/RNFetchBlobImpl.ts +246 -0
  20. package/harmony/fetch_blob/src/main/ets/RNFetchBlobReq.ts +530 -0
  21. package/harmony/fetch_blob/src/main/ets/RNFetchBlobStream.ts +169 -0
  22. package/harmony/fetch_blob/src/main/ets/RNFetchBlobTurboModule.ts +192 -0
  23. package/harmony/fetch_blob/src/main/ets/generated/index.ets +5 -0
  24. package/harmony/fetch_blob/src/main/ets/generated/ts.ts +5 -0
  25. package/harmony/fetch_blob/src/main/ets/generated/turboModules/RNFetchBlob.ts +92 -0
  26. package/harmony/fetch_blob/src/main/ets/generated/turboModules/ts.ts +5 -0
  27. package/harmony/fetch_blob/src/main/module.json5 +22 -0
  28. package/harmony/fetch_blob/src/main/resources/base/element/string.json +8 -0
  29. package/harmony/fetch_blob/src/main/resources/en_US/element/string.json +8 -0
  30. package/harmony/fetch_blob/src/main/resources/zh_CN/element/string.json +8 -0
  31. package/harmony/fetch_blob.har +0 -0
  32. package/package.json +59 -0
  33. package/src/android.js +62 -0
  34. package/src/class/RNFetchBlobFile.js +17 -0
  35. package/src/class/RNFetchBlobReadStream.js +82 -0
  36. package/src/class/RNFetchBlobSession.js +74 -0
  37. package/src/class/RNFetchBlobWriteStream.js +57 -0
  38. package/src/class/StatefulPromise.js +7 -0
  39. package/src/fs.js +432 -0
  40. package/src/index.d.ts +690 -0
  41. package/src/index.js +577 -0
  42. package/src/ios.js +54 -0
  43. package/src/json-stream.js +45 -0
  44. package/src/lib/oboe-browser.min.js +1 -0
  45. package/src/polyfill/Blob.js +362 -0
  46. package/src/polyfill/Event.js +11 -0
  47. package/src/polyfill/EventTarget.js +79 -0
  48. package/src/polyfill/Fetch.js +213 -0
  49. package/src/polyfill/File.js +27 -0
  50. package/src/polyfill/FileReader.js +90 -0
  51. package/src/polyfill/ProgressEvent.js +32 -0
  52. package/src/polyfill/XMLHttpRequest.js +446 -0
  53. package/src/polyfill/XMLHttpRequestEventTarget.js +118 -0
  54. package/src/polyfill/index.js +11 -0
  55. package/src/specs/v1/NativeRNFetchBlob.ts +85 -0
  56. package/src/types.js +64 -0
  57. package/src/utils/log.js +40 -0
  58. package/src/utils/unicode.js +7 -0
  59. package/src/utils/uri.js +28 -0
  60. package/src/utils/uuid.js +4 -0
package/src/index.js ADDED
@@ -0,0 +1,577 @@
1
+ // Copyright 2016 wkh237@github. All rights reserved.
2
+ // Use of this source code is governed by a MIT-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import {
6
+ DeviceEventEmitter,
7
+ NativeAppEventEmitter,
8
+ Platform,
9
+ AppState,
10
+ } from 'react-native'
11
+ import NativeRNFetchBlob from './specs/v1/NativeRNFetchBlob'
12
+ import type {
13
+ RNFetchBlobNative,
14
+ RNFetchBlobConfig,
15
+ RNFetchBlobStream,
16
+ RNFetchBlobResponseInfo
17
+ } from './types'
18
+ import URIUtil from './utils/uri'
19
+ //import StatefulPromise from './class/StatefulPromise.js'
20
+ import fs from './fs'
21
+ import getUUID from './utils/uuid'
22
+ import base64 from 'base-64'
23
+ import polyfill from './polyfill'
24
+ import android from './android'
25
+ import ios from './ios'
26
+ import JSONStream from './json-stream'
27
+ const {
28
+ RNFetchBlobSession,
29
+ readStream,
30
+ createFile,
31
+ unlink,
32
+ exists,
33
+ mkdir,
34
+ session,
35
+ writeStream,
36
+ readFile,
37
+ ls,
38
+ isDir,
39
+ mv,
40
+ cp
41
+ } = fs
42
+
43
+ const Blob = polyfill.Blob
44
+ const emitter = DeviceEventEmitter
45
+ const RNFetchBlob = NativeRNFetchBlob
46
+
47
+ // when app resumes, check if there's any expired network task and trigger
48
+ // their .expire event
49
+ if(Platform.OS === 'ios') {
50
+ AppState.addEventListener('change', (e) => {
51
+ if(e === 'active')
52
+ RNFetchBlob.emitExpiredEvent(()=>{})
53
+ })
54
+ }
55
+
56
+ // register message channel event handler.
57
+ emitter.addListener("RNFetchBlobMessage", (e) => {
58
+
59
+ if(e.event === 'warn') {
60
+ console.warn(e.detail)
61
+ }
62
+ else if (e.event === 'error') {
63
+ throw e.detail
64
+ }
65
+ else {
66
+ console.log("RNFetchBlob native message", e.detail)
67
+ }
68
+ })
69
+
70
+ // Show warning if native module not detected
71
+ if(!RNFetchBlob || !RNFetchBlob.fetchBlobForm || !RNFetchBlob.fetchBlob) {
72
+ console.warn(
73
+ 'rn-fetch-blob could not find valid native module.',
74
+ 'please make sure you have linked native modules using `rnpm link`,',
75
+ 'and restart RN packager or manually compile IOS/Android project.'
76
+ )
77
+ }
78
+
79
+ function wrap(path:string):string {
80
+ const prefix = path.startsWith('content://') ? 'RNFetchBlob-content://' : 'RNFetchBlob-file://'
81
+ return prefix + path
82
+ }
83
+
84
+ /**
85
+ * Calling this method will inject configurations into followed `fetch` method.
86
+ * @param {RNFetchBlobConfig} options
87
+ * Fetch API configurations, contains the following options :
88
+ * @property {boolean} fileCache
89
+ * When fileCache is `true`, response data will be saved in
90
+ * storage with a random generated file name, rather than
91
+ * a BASE64 encoded string.
92
+ * @property {string} appendExt
93
+ * Set this property to change file extension of random-
94
+ * generated file name.
95
+ * @property {string} path
96
+ * If this property has a valid string format, resonse data
97
+ * will be saved to specific file path. Default string format
98
+ * is : `RNFetchBlob-file://path-to-file`
99
+ * @property {string} key
100
+ * If this property is set, it will be converted to md5, to
101
+ * check if a file with this name exists.
102
+ * If it exists, the absolute path is returned (no network
103
+ * activity takes place )
104
+ * If it doesn't exist, the file is downloaded as usual
105
+ * @property {number} timeout
106
+ * Request timeout in millionseconds, by default it's 60000ms.
107
+ * @property {boolean} followRedirect
108
+ * Follow redirects automatically, default true
109
+ * @property {boolean} trusty
110
+ * Trust all certificates
111
+ * @property {boolean} wifiOnly
112
+ * Only do requests through WiFi. Android SDK 21 or above only.
113
+ *
114
+ * @return {function} This method returns a `fetch` method instance.
115
+ */
116
+ function config (options:RNFetchBlobConfig) {
117
+ return { fetch : fetch.bind(options) }
118
+ }
119
+
120
+ /**
121
+ * Fetch from file system, use the same interface as RNFB.fetch
122
+ * @param {RNFetchBlobConfig} [options={}] Fetch configurations
123
+ * @param {string} method Should be one of `get`, `post`, `put`
124
+ * @param {string} url A file URI string
125
+ * @param {string} headers Arguments of file system API
126
+ * @param {any} body Data to put or post to file systen.
127
+ * @return {Promise}
128
+ */
129
+ function fetchFile(options = {}, method, url, headers = {}, body):Promise {
130
+
131
+ if(!URIUtil.isFileURI(url)) {
132
+ throw `could not fetch file from an invalid URI : ${url}`
133
+ }
134
+
135
+ url = URIUtil.unwrapFileURI(url)
136
+
137
+ let promise = null
138
+ let cursor = 0
139
+ let total = -1
140
+ let cacheData = ''
141
+ let info = null
142
+ let _progress, _uploadProgress, _stateChange
143
+
144
+ switch(method.toLowerCase()) {
145
+
146
+ case 'post':
147
+ break
148
+
149
+ case 'put':
150
+ break
151
+
152
+ // read data from file system
153
+ default:
154
+ promise = fs.stat(url)
155
+ .then((stat) => {
156
+ total = stat.size
157
+ return fs.readStream(url,
158
+ headers.encoding || 'utf8',
159
+ Math.floor(headers.bufferSize) || 409600,
160
+ Math.floor(headers.interval) || 100
161
+ )
162
+ })
163
+ .then((stream) => new Promise((resolve, reject) => {
164
+ stream.open()
165
+ info = {
166
+ state : "2",
167
+ headers : { 'source' : 'system-fs' },
168
+ status : 200,
169
+ respType : 'text',
170
+ rnfbEncode : headers.encoding || 'utf8'
171
+ }
172
+ _stateChange(info)
173
+ stream.onData((chunk) => {
174
+ _progress && _progress(cursor, total, chunk)
175
+ if(headers.noCache)
176
+ return
177
+ cacheData += chunk
178
+ })
179
+ stream.onError((err) => { reject(err) })
180
+ stream.onEnd(() => {
181
+ resolve(new FetchBlobResponse(null, info, cacheData))
182
+ })
183
+ }))
184
+ break
185
+ }
186
+
187
+ promise.progress = (fn) => {
188
+ _progress = fn
189
+ return promise
190
+ }
191
+ promise.stateChange = (fn) => {
192
+ _stateChange = fn
193
+ return promise
194
+ }
195
+ promise.uploadProgress = (fn) => {
196
+ _uploadProgress = fn
197
+ return promise
198
+ }
199
+
200
+ return promise
201
+ }
202
+
203
+ /**
204
+ * Create a HTTP request by settings, the `this` context is a `RNFetchBlobConfig` object.
205
+ * @param {string} method HTTP method, should be `GET`, `POST`, `PUT`, `DELETE`
206
+ * @param {string} url Request target url string.
207
+ * @param {object} headers HTTP request headers.
208
+ * @param {string} body
209
+ * Request body, can be either a BASE64 encoded data string,
210
+ * or a file path with prefix `RNFetchBlob-file://` (can be changed)
211
+ * @return {Promise}
212
+ * This promise instance also contains a Customized method `progress`for
213
+ * register progress event handler.
214
+ */
215
+ function fetch(...args:any):Promise {
216
+
217
+ // create task ID for receiving progress event
218
+ let taskId = getUUID()
219
+ let options = this || {}
220
+ let subscription, subscriptionUpload, stateEvent, partEvent
221
+ let respInfo = {}
222
+ let [method, url, headers, body] = [...args]
223
+
224
+ // # 241 normalize null or undefined headers, in case nil or null string
225
+ // pass to native context
226
+ headers = Object.keys(headers || {}).reduce((result, key) => {
227
+ result[key] = headers[key] || ''
228
+ return result
229
+ }, {});
230
+
231
+ // fetch from file system
232
+ if(URIUtil.isFileURI(url)) {
233
+ return fetchFile(options, method, url, headers, body)
234
+ }
235
+
236
+ let promiseResolve;
237
+ let promiseReject;
238
+
239
+ // from remote HTTP(S)
240
+ let promise = new Promise((resolve, reject) => {
241
+ promiseResolve = resolve;
242
+ promiseReject = reject;
243
+
244
+ let nativeMethodName = Array.isArray(body) ? 'fetchBlobForm' : 'fetchBlob'
245
+
246
+ // on progress event listener
247
+ subscription = emitter.addListener('RNFetchBlobProgress', (e) => {
248
+ if(e.taskId === taskId && promise.onProgress) {
249
+ promise.onProgress(e.written, e.total, e.chunk)
250
+ }
251
+ })
252
+
253
+ subscriptionUpload = emitter.addListener('RNFetchBlobProgress-upload', (e) => {
254
+ if(e.taskId === taskId && promise.onUploadProgress) {
255
+ promise.onUploadProgress(e.written, e.total)
256
+ }
257
+ })
258
+
259
+ stateEvent = emitter.addListener('RNFetchBlobState', (e) => {
260
+ if(e.taskId === taskId)
261
+ respInfo = e
262
+ promise.onStateChange && promise.onStateChange(e)
263
+ })
264
+
265
+ subscription = emitter.addListener('RNFetchBlobExpire', (e) => {
266
+ if(e.taskId === taskId && promise.onExpire) {
267
+ promise.onExpire(e)
268
+ }
269
+ })
270
+
271
+ partEvent = emitter.addListener('RNFetchBlobServerPush', (e) => {
272
+ if(e.taskId === taskId && promise.onPartData) {
273
+ promise.onPartData(e.chunk)
274
+ }
275
+ })
276
+
277
+ // When the request body comes from Blob polyfill, we should use special its ref
278
+ // as the request body
279
+ if( body instanceof Blob && body.isRNFetchBlobPolyfill) {
280
+ body = body.getRNFetchBlobRef()
281
+ }
282
+
283
+ let req = RNFetchBlob[nativeMethodName]
284
+
285
+ /**
286
+ * Send request via native module, the response callback accepts three arguments
287
+ * @callback
288
+ * @param err {any} Error message or object, when the request success, this
289
+ * parameter should be `null`.
290
+ * @param rawType { 'utf8' | 'base64' | 'path'} RNFB request will be stored
291
+ * as UTF8 string, BASE64 string, or a file path reference
292
+ * in JS context, and this parameter indicates which one
293
+ * dose the response data presents.
294
+ * @param data {string} Response data or its reference.
295
+ */
296
+ req(options, taskId, method, url, headers || {}, body, (err, rawType, data) => {
297
+
298
+ // task done, remove event listeners
299
+ subscription.remove()
300
+ subscriptionUpload.remove()
301
+ stateEvent.remove()
302
+ partEvent.remove()
303
+ delete promise['progress']
304
+ delete promise['uploadProgress']
305
+ delete promise['stateChange']
306
+ delete promise['part']
307
+ delete promise['cancel']
308
+ // delete promise['expire']
309
+ promise.cancel = () => {}
310
+
311
+ if(err)
312
+ reject(new Error(err, respInfo))
313
+ else {
314
+ // response data is saved to storage, create a session for it
315
+ if(options.path || options.fileCache || options.addAndroidDownloads
316
+ || options.key || options.auto && respInfo.respType === 'blob') {
317
+ if(options.session)
318
+ session(options.session).add(data)
319
+ }
320
+ respInfo.rnfbEncode = rawType
321
+ resolve(new FetchBlobResponse(taskId, respInfo, data))
322
+ }
323
+
324
+ })
325
+
326
+ })
327
+
328
+ // extend Promise object, add `progress`, `uploadProgress`, and `cancel`
329
+ // method for register progress event handler and cancel request.
330
+ // Add second parameter for performance purpose #140
331
+ // When there's only one argument pass to this method, use default `interval`
332
+ // and `count`, otherwise use the given on.
333
+ // TODO : code refactor, move `uploadProgress` and `progress` to StatefulPromise
334
+ promise.progress = (...args) => {
335
+ let interval = 250
336
+ let count = -1
337
+ let fn = () => {}
338
+ if(args.length === 2) {
339
+ interval = args[0].interval || interval
340
+ count = args[0].count || count
341
+ fn = args[1]
342
+ }
343
+ else {
344
+ fn = args[0]
345
+ }
346
+ promise.onProgress = fn
347
+ RNFetchBlob.enableProgressReport(taskId, interval, count)
348
+ return promise
349
+ }
350
+ promise.uploadProgress = (...args) => {
351
+ let interval = 250
352
+ let count = -1
353
+ let fn = () => {}
354
+ if(args.length === 2) {
355
+ interval = args[0].interval || interval
356
+ count = args[0].count || count
357
+ fn = args[1]
358
+ }
359
+ else {
360
+ fn = args[0]
361
+ }
362
+ promise.onUploadProgress = fn
363
+ RNFetchBlob.enableUploadProgressReport(taskId, interval, count)
364
+ return promise
365
+ }
366
+ promise.part = (fn) => {
367
+ promise.onPartData = fn
368
+ return promise
369
+ }
370
+ promise.stateChange = (fn) => {
371
+ promise.onStateChange = fn
372
+ return promise
373
+ }
374
+ promise.expire = (fn) => {
375
+ promise.onExpire = fn
376
+ return promise
377
+ }
378
+ promise.cancel = (fn) => {
379
+ fn = fn || function(){}
380
+ subscription.remove()
381
+ subscriptionUpload.remove()
382
+ stateEvent.remove()
383
+ RNFetchBlob.cancelRequest(taskId, fn)
384
+ promiseReject(new Error("canceled"))
385
+ }
386
+ promise.taskId = taskId
387
+
388
+ return promise
389
+
390
+ }
391
+
392
+ /**
393
+ * RNFetchBlob response object class.
394
+ */
395
+ class FetchBlobResponse {
396
+
397
+ taskId : string;
398
+ path : () => string | null;
399
+ type : 'base64' | 'path' | 'utf8';
400
+ data : any;
401
+ blob : (contentType:string, sliceSize:number) => Promise<Blob>;
402
+ text : () => string | Promise<any>;
403
+ json : () => any;
404
+ base64 : () => any;
405
+ flush : () => void;
406
+ respInfo : RNFetchBlobResponseInfo;
407
+ session : (name:string) => RNFetchBlobSession | null;
408
+ readFile : (encode: 'base64' | 'utf8' | 'ascii') => ?Promise<any>;
409
+ readStream : (
410
+ encode: 'utf8' | 'ascii' | 'base64',
411
+ ) => RNFetchBlobStream | null;
412
+
413
+ constructor(taskId:string, info:RNFetchBlobResponseInfo, data:any) {
414
+ this.data = data
415
+ this.taskId = taskId
416
+ this.type = info.rnfbEncode
417
+ this.respInfo = info
418
+
419
+ this.info = ():RNFetchBlobResponseInfo => {
420
+ return this.respInfo
421
+ }
422
+
423
+ this.array = ():Promise<Array> => {
424
+ let cType = info.headers['Content-Type'] || info.headers['content-type']
425
+ return new Promise((resolve, reject) => {
426
+ switch(this.type) {
427
+ case 'base64':
428
+ // TODO : base64 to array buffer
429
+ break
430
+ case 'path':
431
+ fs.readFile(this.data, 'ascii').then(resolve)
432
+ break
433
+ default:
434
+ // TODO : text to array buffer
435
+ break
436
+ }
437
+ })
438
+ }
439
+
440
+ /**
441
+ * Convert result to javascript RNFetchBlob object.
442
+ * @return {Promise<Blob>} Return a promise resolves Blob object.
443
+ */
444
+ this.blob = ():Promise<Blob> => {
445
+ let Blob = polyfill.Blob
446
+ let cType = info.headers['Content-Type'] || info.headers['content-type']
447
+ return new Promise((resolve, reject) => {
448
+ switch(this.type) {
449
+ case 'base64':
450
+ Blob.build(this.data, { type : cType + ';BASE64' }).then(resolve)
451
+ break
452
+ case 'path':
453
+ polyfill.Blob.build(wrap(this.data), { type : cType }).then(resolve)
454
+ break
455
+ default:
456
+ polyfill.Blob.build(this.data, { type : 'text/plain' }).then(resolve)
457
+ break
458
+ }
459
+ })
460
+ }
461
+ /**
462
+ * Convert result to text.
463
+ * @return {string} Decoded base64 string.
464
+ */
465
+ this.text = ():string | Promise<any> => {
466
+ let res = this.data
467
+ switch(this.type) {
468
+ case 'base64':
469
+ return base64.decode(this.data)
470
+ case 'path':
471
+ return fs.readFile(this.data, 'base64').then((b64) => Promise.resolve(base64.decode(b64)))
472
+ default:
473
+ return this.data
474
+ }
475
+ }
476
+ /**
477
+ * Convert result to JSON object.
478
+ * @return {object} Parsed javascript object.
479
+ */
480
+ this.json = ():any => {
481
+ switch(this.type) {
482
+ case 'base64':
483
+ return JSON.parse(base64.decode(this.data))
484
+ case 'path':
485
+ return fs.readFile(this.data, 'utf8')
486
+ .then((text) => Promise.resolve(JSON.parse(text)))
487
+ default:
488
+ return JSON.parse(this.data)
489
+ }
490
+ }
491
+ /**
492
+ * Return BASE64 string directly.
493
+ * @return {string} BASE64 string of response body.
494
+ */
495
+ this.base64 = ():string | Promise<any> => {
496
+ switch(this.type) {
497
+ case 'base64':
498
+ return this.data
499
+ case 'path':
500
+ return fs.readFile(this.data, 'base64')
501
+ default:
502
+ return base64.encode(this.data)
503
+ }
504
+ }
505
+ /**
506
+ * Remove cahced file
507
+ * @return {Promise}
508
+ */
509
+ this.flush = () => {
510
+ let path = this.path()
511
+ if(!path || this.type !== 'path')
512
+ return
513
+ return unlink(path)
514
+ }
515
+ /**
516
+ * get path of response temp file
517
+ * @return {string} File path of temp file.
518
+ */
519
+ this.path = () => {
520
+ if(this.type === 'path')
521
+ return this.data
522
+ return null
523
+ }
524
+
525
+ this.session = (name:string):RNFetchBlobSession | null => {
526
+ if(this.type === 'path')
527
+ return session(name).add(this.data)
528
+ else {
529
+ console.warn('only file paths can be add into session.')
530
+ return null
531
+ }
532
+ }
533
+ /**
534
+ * Start read stream from cached file
535
+ * @param {String} encoding Encode type, should be one of `base64`, `ascii`, `utf8`.
536
+ * @return {void}
537
+ */
538
+ this.readStream = (encoding: 'base64' | 'utf8' | 'ascii'):RNFetchBlobStream | null => {
539
+ if(this.type === 'path') {
540
+ return readStream(this.data, encoding)
541
+ }
542
+ else {
543
+ console.warn('RNFetchblob', 'this response data does not contains any available stream')
544
+ return null
545
+ }
546
+ }
547
+ /**
548
+ * Read file content with given encoding, if the response does not contains
549
+ * a file path, show warning message
550
+ * @param {String} encoding Encode type, should be one of `base64`, `ascrii`, `utf8`.
551
+ * @return {String}
552
+ */
553
+ this.readFile = (encoding: 'base64' | 'utf8' | 'ascii') => {
554
+ if(this.type === 'path') {
555
+ return readFile(this.data, encoding)
556
+ }
557
+ else {
558
+ console.warn('RNFetchblob', 'this response does not contains a readable file')
559
+ return null
560
+ }
561
+ }
562
+ }
563
+
564
+ }
565
+
566
+ export default {
567
+ fetch,
568
+ base64,
569
+ android,
570
+ ios,
571
+ config,
572
+ session,
573
+ fs,
574
+ wrap,
575
+ polyfill,
576
+ JSONStream
577
+ }
package/src/ios.js ADDED
@@ -0,0 +1,54 @@
1
+ // Copyright 2016 wkh237@github. All rights reserved.
2
+ // Use of this source code is governed by a MIT-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import {
6
+ DeviceEventEmitter,
7
+ Platform,
8
+ NativeAppEventEmitter,
9
+ } from 'react-native'
10
+ import NativeRNFetchBlob from './specs/v1/NativeRNFetchBlob'
11
+
12
+ const RNFetchBlob:RNFetchBlobNative = NativeRNFetchBlob
13
+
14
+ /**
15
+ * Open a file using UIDocumentInteractionController
16
+ * @param {string} path Path of the file to be open.
17
+ * @param {string} scheme URI scheme that needs to support, optional
18
+ * @return {Promise}
19
+ */
20
+ function previewDocument(path:string, scheme:string) {
21
+ if(Platform.OS === 'ios')
22
+ return NativeRNFetchBlob.previewDocument('file://' + path, scheme)
23
+ else
24
+ return Promise.reject(new Error('RNFetchBlob.previewDocument only supports IOS.'))
25
+ }
26
+
27
+ /**
28
+ * Preview a file using UIDocumentInteractionController
29
+ * @param {string} path Path of the file to be open.
30
+ * @param {string} scheme URI scheme that needs to support, optional
31
+ * @return {Promise}
32
+ */
33
+ function openDocument(path:string, scheme:string) {
34
+ if(Platform.OS === 'ios')
35
+ return NativeRNFetchBlob.openDocument('file://' + path, scheme)
36
+ else
37
+ return Promise.reject(new Error('RNFetchBlob.openDocument only supports IOS.'))
38
+ }
39
+
40
+ /**
41
+ * Set excludeFromBackupKey to a URL to prevent the resource to be backuped to
42
+ * iCloud.
43
+ * @param {string} url URL of the resource, only file URL is supported
44
+ * @return {Promise}
45
+ */
46
+ function excludeFromBackupKey(path:string) {
47
+ return NativeRNFetchBlob.excludeFromBackupKey('file://' + path);
48
+ }
49
+
50
+ export default {
51
+ openDocument,
52
+ previewDocument,
53
+ excludeFromBackupKey
54
+ }
@@ -0,0 +1,45 @@
1
+ import Oboe from './lib/oboe-browser.min.js'
2
+ import XMLHttpRequest from './polyfill/XMLHttpRequest'
3
+ import URIUtil from './utils/uri'
4
+
5
+ const OboeExtended = (arg: string | Object) => {
6
+
7
+ // Harmony (ArkTS/Hermes) 运行时无 window 全局,跳过 polyfill 覆盖,
8
+ // JSONStream 在鸿蒙端弱化处理(oboe 为浏览器构建,依赖 window/XMLHttpRequest)。
9
+ if (typeof window !== 'undefined') {
10
+ window.location = ''
11
+
12
+ if(!window.XMLHttpRequest.isRNFBPolyfill ) {
13
+ window.XMLHttpRequest = XMLHttpRequest
14
+ console.warn(
15
+ 'Use JSONStream will automatically replace window.XMLHttpRequest with RNFetchBlob.polyfill.XMLHttpRequest. ' +
16
+ 'You are seeing this warning because you did not replace it manually.'
17
+ )
18
+ }
19
+ }
20
+
21
+ if(typeof arg === 'string') {
22
+ if(URIUtil.isFileURI(arg)) {
23
+ arg = {
24
+ url : 'JSONStream://' + arg,
25
+ headers : { noCache : true }
26
+ }
27
+ }
28
+ else
29
+ arg = 'JSONStream://' + arg
30
+
31
+ }
32
+ else if(typeof arg === 'object') {
33
+ let headers = arg.headers || {}
34
+ if(URIUtil.isFileURI(arg.url)) {
35
+ headers.noCache = true
36
+ }
37
+ arg = Object.assign(arg, {
38
+ url : 'JSONStream://' + arg.url,
39
+ headers
40
+ })
41
+ }
42
+ return Oboe(arg)
43
+ }
44
+
45
+ export default OboeExtended