|  | @@ -1,6 +1,7 @@
 | 
	
		
			
			| 1 | 1 |  /**
 | 
	
		
			
			| 2 | 2 |   * @author wkh237
 | 
	
		
			
			| 3 |  | - * @version 0.4.2
 | 
	
		
			
			|  | 3 | + * @version 0.5.0
 | 
	
		
			
			|  | 4 | + * @flow
 | 
	
		
			
			| 4 | 5 |   */
 | 
	
		
			
			| 5 | 6 |  
 | 
	
		
			
			| 6 | 7 |  import {
 | 
	
	
		
			
			|  | @@ -14,6 +15,20 @@ import base64 from 'base-64'
 | 
	
		
			
			| 14 | 15 |  const emitter = (Platform.OS === 'android' ? DeviceEventEmitter : NativeAppEventEmitter)
 | 
	
		
			
			| 15 | 16 |  const RNFetchBlob = NativeModules.RNFetchBlob
 | 
	
		
			
			| 16 | 17 |  
 | 
	
		
			
			|  | 18 | +emitter.addListener("RNFetchBlobMessage", (e) => {
 | 
	
		
			
			|  | 19 | +
 | 
	
		
			
			|  | 20 | +  if(e.event === 'warn') {
 | 
	
		
			
			|  | 21 | +    console.warn(e.detail)
 | 
	
		
			
			|  | 22 | +  }
 | 
	
		
			
			|  | 23 | +  else if (e.event === 'error') {
 | 
	
		
			
			|  | 24 | +    throw e.detail
 | 
	
		
			
			|  | 25 | +  }
 | 
	
		
			
			|  | 26 | +  else {
 | 
	
		
			
			|  | 27 | +    console.log("RNFetchBlob native message", e.detail)
 | 
	
		
			
			|  | 28 | +  }
 | 
	
		
			
			|  | 29 | +
 | 
	
		
			
			|  | 30 | +})
 | 
	
		
			
			|  | 31 | +
 | 
	
		
			
			| 17 | 32 |  // Show warning if native module not detected
 | 
	
		
			
			| 18 | 33 |  if(!RNFetchBlob || !RNFetchBlob.fetchBlobForm || !RNFetchBlob.fetchBlob) {
 | 
	
		
			
			| 19 | 34 |    console.warn(
 | 
	
	
		
			
			|  | @@ -23,12 +38,17 @@ if(!RNFetchBlob || !RNFetchBlob.fetchBlobForm || !RNFetchBlob.fetchBlob) {
 | 
	
		
			
			| 23 | 38 |    )
 | 
	
		
			
			| 24 | 39 |  }
 | 
	
		
			
			| 25 | 40 |  
 | 
	
		
			
			|  | 41 | +type fetchConfig = {
 | 
	
		
			
			|  | 42 | +  fileCache : bool,
 | 
	
		
			
			|  | 43 | +  path : string,
 | 
	
		
			
			|  | 44 | +}
 | 
	
		
			
			|  | 45 | +
 | 
	
		
			
			| 26 | 46 |  const config = function(options) {
 | 
	
		
			
			| 27 | 47 |    return { fetch : fetch.bind(options) }
 | 
	
		
			
			| 28 | 48 |  }
 | 
	
		
			
			| 29 | 49 |  
 | 
	
		
			
			| 30 | 50 |  // Promise wrapper function
 | 
	
		
			
			| 31 |  | -const fetch = function(...args) {
 | 
	
		
			
			|  | 51 | +const fetch = function(...args:any) {
 | 
	
		
			
			| 32 | 52 |  
 | 
	
		
			
			| 33 | 53 |    let options = this || {}
 | 
	
		
			
			| 34 | 54 |  
 | 
	
	
		
			
			|  | @@ -48,14 +68,18 @@ const fetch = function(...args) {
 | 
	
		
			
			| 48 | 68 |      })
 | 
	
		
			
			| 49 | 69 |  
 | 
	
		
			
			| 50 | 70 |      let req = RNFetchBlob[nativeMethodName]
 | 
	
		
			
			| 51 |  | -    req(taskId, method, url, headers || {}, body, (err, ...data) => {
 | 
	
		
			
			|  | 71 | +    req(options, taskId, method, url, headers || {}, body, (err, ...data) => {
 | 
	
		
			
			| 52 | 72 |  
 | 
	
		
			
			| 53 | 73 |        // task done, remove event listener
 | 
	
		
			
			| 54 | 74 |        subscription.remove()
 | 
	
		
			
			| 55 | 75 |        if(err)
 | 
	
		
			
			| 56 | 76 |          reject(new Error(err, ...data))
 | 
	
		
			
			| 57 |  | -      else
 | 
	
		
			
			| 58 |  | -        resolve(new FetchBlobResponse(...data))
 | 
	
		
			
			|  | 77 | +      else {
 | 
	
		
			
			|  | 78 | +        let respType = 'base64'
 | 
	
		
			
			|  | 79 | +        if(options.fileCache || options.path)
 | 
	
		
			
			|  | 80 | +          respType = 'path'
 | 
	
		
			
			|  | 81 | +        resolve(new FetchBlobResponse(taskId, respType,...data))
 | 
	
		
			
			|  | 82 | +      }
 | 
	
		
			
			| 59 | 83 |  
 | 
	
		
			
			| 60 | 84 |      })
 | 
	
		
			
			| 61 | 85 |  
 | 
	
	
		
			
			|  | @@ -75,15 +99,29 @@ const fetch = function(...args) {
 | 
	
		
			
			| 75 | 99 |   */
 | 
	
		
			
			| 76 | 100 |  class FetchBlobResponse {
 | 
	
		
			
			| 77 | 101 |  
 | 
	
		
			
			| 78 |  | -  constructor(data) {
 | 
	
		
			
			|  | 102 | +  taskId : string;
 | 
	
		
			
			|  | 103 | +  type : 'base64' | 'path';
 | 
	
		
			
			|  | 104 | +  data : any;
 | 
	
		
			
			|  | 105 | +  blob : (contentType:string, sliceSize:number) => null;
 | 
	
		
			
			|  | 106 | +  text : () => string;
 | 
	
		
			
			|  | 107 | +  json : () => any;
 | 
	
		
			
			|  | 108 | +  base64 : () => any;
 | 
	
		
			
			|  | 109 | +  flush : () => void;
 | 
	
		
			
			|  | 110 | +  readStream : (
 | 
	
		
			
			|  | 111 | +    encode: 'utf8' | 'ascii' | 'base64',
 | 
	
		
			
			|  | 112 | +    fn:(event : 'data' | 'end', chunk:any) => void
 | 
	
		
			
			|  | 113 | +  ) => void;
 | 
	
		
			
			|  | 114 | +
 | 
	
		
			
			|  | 115 | +  constructor(taskId:string, type:'base64' | 'path',data:any) {
 | 
	
		
			
			| 79 | 116 |      this.data = data
 | 
	
		
			
			|  | 117 | +    this.taskId = taskId
 | 
	
		
			
			| 80 | 118 |      /**
 | 
	
		
			
			| 81 | 119 |       * Convert result to javascript Blob object.
 | 
	
		
			
			| 82 | 120 |       * @param  {string} contentType MIME type of the blob object.
 | 
	
		
			
			| 83 | 121 |       * @param  {number} sliceSize   Slice size.
 | 
	
		
			
			| 84 | 122 |       * @return {blob}             Return Blob object.
 | 
	
		
			
			| 85 | 123 |       */
 | 
	
		
			
			| 86 |  | -    this.blob = (contentType, sliceSize) => {
 | 
	
		
			
			|  | 124 | +    this.blob = (contentType:string, sliceSize:number) => {
 | 
	
		
			
			| 87 | 125 |        console.warn('FetchBlobResponse.blob() is deprecated and has no funtionality.')
 | 
	
		
			
			| 88 | 126 |        return null
 | 
	
		
			
			| 89 | 127 |      }
 | 
	
	
		
			
			|  | @@ -91,23 +129,49 @@ class FetchBlobResponse {
 | 
	
		
			
			| 91 | 129 |       * Convert result to text.
 | 
	
		
			
			| 92 | 130 |       * @return {string} Decoded base64 string.
 | 
	
		
			
			| 93 | 131 |       */
 | 
	
		
			
			| 94 |  | -    this.text = () => {
 | 
	
		
			
			|  | 132 | +    this.text = ():string => {
 | 
	
		
			
			| 95 | 133 |        return base64.decode(this.data)
 | 
	
		
			
			| 96 | 134 |      }
 | 
	
		
			
			| 97 | 135 |      /**
 | 
	
		
			
			| 98 | 136 |       * Convert result to JSON object.
 | 
	
		
			
			| 99 | 137 |       * @return {object} Parsed javascript object.
 | 
	
		
			
			| 100 | 138 |       */
 | 
	
		
			
			| 101 |  | -    this.json = () => {
 | 
	
		
			
			|  | 139 | +    this.json = ():any => {
 | 
	
		
			
			| 102 | 140 |        return JSON.parse(base64.decode(this.data))
 | 
	
		
			
			| 103 | 141 |      }
 | 
	
		
			
			| 104 | 142 |      /**
 | 
	
		
			
			| 105 | 143 |       * Return BASE64 string directly.
 | 
	
		
			
			| 106 | 144 |       * @return {string} BASE64 string of response body.
 | 
	
		
			
			| 107 | 145 |       */
 | 
	
		
			
			| 108 |  | -    this.base64 = () => {
 | 
	
		
			
			|  | 146 | +    this.base64 = ():string => {
 | 
	
		
			
			| 109 | 147 |        return this.data
 | 
	
		
			
			| 110 | 148 |      }
 | 
	
		
			
			|  | 149 | +    /**
 | 
	
		
			
			|  | 150 | +     * Remove cahced file
 | 
	
		
			
			|  | 151 | +     * @return {void}
 | 
	
		
			
			|  | 152 | +     */
 | 
	
		
			
			|  | 153 | +    this.flush = () => {
 | 
	
		
			
			|  | 154 | +      RNFetchBlob.flush(this.taskId)
 | 
	
		
			
			|  | 155 | +    }
 | 
	
		
			
			|  | 156 | +
 | 
	
		
			
			|  | 157 | +    /**
 | 
	
		
			
			|  | 158 | +     * Start read stream from cached file
 | 
	
		
			
			|  | 159 | +     * @param  {String} encoding Encode type, should be one of `base64`, `ascrii`, `utf8`.
 | 
	
		
			
			|  | 160 | +     * @param  {Function} fn On data event handler
 | 
	
		
			
			|  | 161 | +     * @return {void}
 | 
	
		
			
			|  | 162 | +     */
 | 
	
		
			
			|  | 163 | +    this.readStream = (encode: 'base64' | 'utf8' | 'ascii', fn) => {
 | 
	
		
			
			|  | 164 | +
 | 
	
		
			
			|  | 165 | +      // register for file stream event
 | 
	
		
			
			|  | 166 | +      let subscription = emitter.addListener(`RNFetchBlobStream${this.taskId}`, (event, chunk) => {
 | 
	
		
			
			|  | 167 | +        fn(event, chunk)
 | 
	
		
			
			|  | 168 | +        // when stream closed, remove event handler
 | 
	
		
			
			|  | 169 | +        if(event === 'end')
 | 
	
		
			
			|  | 170 | +          subscription()
 | 
	
		
			
			|  | 171 | +      })
 | 
	
		
			
			|  | 172 | +
 | 
	
		
			
			|  | 173 | +      RNFetchBlob.readStream(this.taskId, encode)
 | 
	
		
			
			|  | 174 | +    }
 | 
	
		
			
			| 111 | 175 |  
 | 
	
		
			
			| 112 | 176 |    }
 | 
	
		
			
			| 113 | 177 |  
 |